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 객체가 최대 하나만 존재하도록 보장하는 데 사용된다. 그러나 이 속성은 공유 객체에는 적용되지 않는다.
-
내보낸 Function 캐시: 함수 주소를 Exported Function 객체에 매핑한다.
-
내보낸 GC Object 캐시: struct 주소와 array 주소를 Exported GC Object 객체에 매핑한다.
-
호스트 값 캐시: 호스트 주소를 값에 매핑한다.
5. WebAssembly 네임스페이스
dictionary {WebAssemblyInstantiatedSource required Module ;module required Instance ; };instance dictionary {WebAssemblyCompileOptions USVString ?=importedStringConstants null ;sequence <USVString >= []; }; [Exposed=*]builtins 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 ; };
-
module을 module_decode(bytes)라고 하자. 만약 module이 error이면, error를 반환한다.
-
만약 module_validate(module)가 error이면, error를 반환한다.
-
module을 반환한다.
다음과 같이 WebAssembly 모듈의 내장 기능 및 가져온 문자열을 검증합니다. 모듈 module, 활성화된 내장 기능 builtinSetNames 및 importedStringModule이 주어지면 다음 단계를 수행합니다:
-
만약 내장 기능 집합 이름 검증을 builtinSetNames에 대해 수행한 결과가 false이면 false를 반환합니다.
-
각각에 대해 import를 module_imports(module)에서 가져와 다음을 수행합니다.
-
importedStringModule이 null이 아니고 import[0]이 importedStringModule과 같으면,
-
importExternType을 import[2]로 설정합니다.
-
match_externtype(stringExternType, importExternType)가 false이면 false를 반환합니다
-
-
그렇지 않으면,
-
가져오기의 내장 기능 검증을 import와 builtinSetNames로 수행한 결과가 false이면, false를 반환합니다.
-
-
-
true를 반환합니다.
validate(bytes, options) 메서드는
호출되면 다음 단계를 수행한다:
-
stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.
-
stableBytes를 WebAssembly 모듈로 컴파일하고 그 결과를 module로 저장한다.
-
만약 module이 error이면, false를 반환한다.
-
builtinSetNames를 options["builtins"]라고 하자.
-
importedStringModule을 options["importedStringConstants"]라고 하자.
-
만약 빌트인 및 imported strings 검증을 module에 대해 builtinSetNames 및 importedStringModule와 함께 수행한 결과가 false이면, false를 반환한다.
-
true를 반환한다.
Module 객체는
하나의 WebAssembly 모듈을 나타낸다. 각 Module 객체는 다음
내부 슬롯을 가진다:
-
[[Module]] : WebAssembly module
-
[[Bytes]] : [[Module]]의 소스 바이트.
-
[[BuiltinSets]] : builtin sets 이름의 순서 집합
-
[[ImportedStringModule]] : 임의의 문자열 상수를 가져올 수 있는 선택적 모듈 지정자 문자열.
WebAssemblyCompileOptions
options로부터 선택적 task
source taskSource를 사용하여
WebAssembly 모듈을 비동기적으로 컴파일하기 위해 다음 단계를 수행한다:
-
promise를 새로운 promise라고 하자.
-
다음 단계를 병렬로 실행한다:
-
WebAssembly 모듈을 컴파일합니다 bytes를 컴파일하고 그 결과를 module로 저장합니다.
-
태스크를 큐에 넣습니다. taskSource가 제공된 경우, 다음 단계를 수행하도록 해당 taskSource에 태스크를 큐에 넣습니다:
-
module이 오류인 경우, 거부합니다 promise를
CompileError예외로 거부하고 반환합니다. -
builtinSetNames를 options["builtins"]로 둡니다.
-
importedStringModule을 options["importedStringConstants"]로 둡니다.
-
module에 대해 builtinSetNames 및 importedStringModule을 사용하여 내장 기능과 가져온 문자열을 검증한 결과가 false이면, 거부합니다 promise를
CompileError예외로 거부합니다. -
그렇지 않으면,
-
module, bytes, builtinSetNames, importedStringModule로부터 WebAssembly 모듈 객체를 생성하고, 그 결과를 moduleObject로 둡니다.
-
moduleObject를 사용하여 promise를 해결합니다.
-
-
-
-
promise를 반환한다.
compile(bytes, options) 메서드는
호출되면 다음 단계를 수행한다:
-
stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.
-
stableBytes로부터 WebAssembly 모듈을 비동기적으로 컴파일하고 options를 사용하여 그 결과를 반환한다.
가져온 문자열을 인스턴스화하려면 모듈 module 및 importedStringModule을 사용하여 다음 단계를 수행합니다:
-
단언: importedStringModule은 null이 아닙니다.
-
exportsObject를 OrdinaryObjectCreate(null)로 둡니다.
-
각각에 대해 module_imports(module)의 (moduleName, componentName, externtype)에 대해,
-
moduleName이 importedStringModule과 같지 않으면 계속합니다.
-
stringConstant를 componentName으로 둡니다.
-
status를 ! CreateDataProperty(exportsObject, stringConstant, stringConstant)로 둡니다.
-
단언: status는 true입니다.
-
-
exportsObject를 반환합니다.
-
module_imports(module)가 비어 있지 않고, importObject가 제공되지 않았다면
TypeError예외를 던집니다. -
builtinOrStringImports를 순서가 있는 맵 «[ ]»으로 둡니다.
-
builtinSetNames의 각 builtinSetName에 대해 다음을 수행합니다.
-
builtinSetQualifiedName을 builtinSetName 앞에 "wasm:"을 붙인 값으로 둡니다.
-
단언: builtinOrStringImports는 builtinSetQualifiedName을 포함하지 않습니다.
-
builtinSetName이 내장 기능 집합을 참조하지 않으면 계속 진행합니다.
-
exportsObject를 builtinSetName으로 내장 기능 집합을 인스턴스화한 결과로 둡니다.
-
설정합니다: builtinOrStringImports[builtinSetQualifiedName]을 exportsObject로 설정합니다.
-
-
importedStringModule이 null이 아니면,
-
exportsObject를 가져온 문자열을 인스턴스화한 결과로 두며, module과 importedStringModule을 사용합니다.
-
설정합니다: builtinOrStringImports[importedStringModule]을 exportsObject로 설정합니다.
-
-
imports를 « »로 둡니다.
-
각 (moduleName, componentName, externtype)에 대해 module_imports(module)에서 다음을 수행합니다.
-
builtinOrStringImports[moduleName]이 존재하면,
-
o를 builtinOrStringImports[moduleName]로 둡니다.
-
o가 Object가 아니거나 ? HasProperty(o, componentName)가 false이면,
-
-
그렇지 않으면,
-
o가 Object가 아니면,
TypeError예외를 던집니다. -
externtype이 func functype 형식이면,
-
IsCallable(v)이 false이면,
LinkError예외를 던집니다. -
v에 [[FunctionAddress]] 내부 슬롯이 있어 내보낸 함수에 해당하면,
-
funcaddr를 v의 [[FunctionAddress]] 내부 슬롯 값으로 둡니다.
-
-
그렇지 않으면,
-
v와 functype으로 호스트 함수를 생성하고, funcaddr를 그 결과로 둡니다.
-
index를 imports에 있는 외부 함수의 수로 둡니다. 이 값 index를 호스트 함수의 인덱스라고 하며, funcaddr에 해당합니다.
-
-
추가합니다: externfunc를 imports에 추가합니다.
-
-
externtype이 global mut valtype 형식이면,
-
-
globaladdr를 v.[[Global]]로 둡니다.
-
-
그렇지 않으면,
-
valtype이 i64이고 v가 BigInt가 아니면,
-
LinkError예외를 던집니다.
-
-
valtype이 i32, f32 또는 f64 중 하나이고 v가 Number가 아니면,
-
LinkError예외를 던집니다.
-
-
valtype이 v128이면,
-
LinkError예외를 던집니다.
-
-
value를 ToWebAssemblyValue(v, valtype)로 둡니다. 이 연산이
TypeError를 던지면, 이를 포착한 후LinkError예외를 던집니다. -
(store, globaladdr)를 global_alloc(store, valtype, value)으로 둡니다.
-
-
externglobal을 global globaladdr로 둡니다.
-
추가합니다: externglobal을 imports에 추가합니다.
-
-
externtype이 mem memtype 형식이면,
-
externtype이 table tabletype 형식이면,
-
externtype이 tag functype 형식이면,
-
-
imports를 반환합니다.
참고: 이 알고리즘은 올바른 종류의 JavaScript 값이 전달되었는지만 확인합니다. WebAssembly 타입 요구 사항의 검증은 "WebAssembly 모듈의 핵심을 인스턴스화"하는 알고리즘으로 연기됩니다.
-
exportsObject를 OrdinaryObjectCreate(null)로 둡니다.
-
각 (name, externtype)에 대해 module_exports(module)에서 다음을 수행합니다.
-
externval을 instance_export(instance, name)으로 둡니다.
-
단언: externval은 오류가 아닙니다.
-
externtype이 func functype 형식이면,
-
단언: externval은 func funcaddr 형식입니다.
-
func funcaddr를 externval로 둡니다.
-
func를 funcaddr로부터 새로운 내보낸 함수를 생성한 결과로 둡니다.
-
value를 func로 둡니다.
-
-
externtype이 global mut globaltype 형식이면,
-
단언: externval은 global globaladdr 형식입니다.
-
global globaladdr를 externval로 둡니다.
-
global을 새로운 Global 객체를 globaladdr로부터 생성한 결과로 둡니다.
-
value를 global로 둡니다.
-
-
externtype이 mem memtype 형식이면,
-
단언: externval은 mem memaddr 형식입니다.
-
mem memaddr를 externval로 둡니다.
-
memory를 새로운 Memory 객체를 memaddr로부터 생성한 결과로 둡니다.
-
value를 memory로 둡니다.
-
-
externtype이 table tabletype 형식이면,
-
단언: externval은 table tableaddr 형식입니다.
-
table tableaddr를 externval로 둡니다.
-
table을 새로운 Table 객체를 tableaddr로부터 생성한 결과로 둡니다.
-
value를 table로 둡니다.
-
-
externtype이 tag functype 형식이면,
-
단언: externval은 tag tagaddr 형식입니다.
-
tag tagaddr를 externval로 둡니다.
-
tag를 새로운 Tag 객체를 tagaddr로부터 생성한 결과로 둡니다.
-
value를 tag로 둡니다.
-
-
status를 ! CreateDataProperty(exportsObject, name, value)로 둡니다.
-
단언: status는 true입니다.
참고: WebAssembly 모듈 검증 중 수행되는 유효성 및 고유성 검사는 각 속성 이름이 유효하고 동일한 속성이 두 번 정의되지 않도록 보장합니다.
-
-
! SetIntegrityLevel(exportsObject,
"frozen")을 수행합니다. -
exportsObject를 반환합니다.
-
module 및 instance에서 내보내기 객체를 생성하고 그 결과를 exportsObject로 둡니다.
-
instanceObject.[[Instance]]를 instance로 설정합니다.
-
instanceObject.[[Exports]]를 exportsObject로 설정합니다.
-
(store, result)를 module_instantiate(store, module, imports)로 둡니다.
-
result가 오류이면 적절한 예외 유형을 발생시킵니다:
-
링크 중 발생하는 대부분의 경우에는
LinkError예외를 발생시킵니다. -
시작 함수를 실행할 때 오류가 발생했다면 WebAssembly에서 발생하는 대부분의 오류에는
RuntimeError를 발생시키거나, 내부 ECMAScript 코드에서 전파된 오류 객체를 발생시킵니다. -
적절한 경우, 예를 들어 메모리 부족 예외와 같은 다른 오류 유형을 WebAssembly 오류 매핑에 문서화된 대로 발생시킵니다.
-
-
result를 반환합니다.
Module
moduleObject 및 가져오기 importObject로부터 다음 단계를 수행합니다:
-
promise를 새 프로미스로 둡니다.
-
module을 moduleObject.[[Module]]로 둡니다.
-
builtinSetNames를 moduleObject.[[BuiltinSets]]로 둡니다.
-
importedStringModule을 moduleObject.[[ImportedStringModule]]로 둡니다.
-
module의 가져오기를 읽되, 가져오기 importObject, builtinSetNames 및 importedStringModule을 사용하고, imports를 그 결과로 둡니다. 이 연산이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 promise를 반환합니다.
-
다음 단계를 병렬로 실행합니다:
-
다음 단계를 수행하도록 태스크를 큐에 넣습니다: 참고: 여기에서 구현별 작업을 수행할 수 있습니다.
-
imports를 사용하여 module의 WebAssembly 모듈의 코어를 인스턴스화하고, 그 결과를 instance로 둡니다. 이 작업이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 이 하위 단계를 종료합니다.
-
module 및 instance로부터 instanceObject를 초기화합니다. 이 작업이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 이 하위 단계를 종료합니다.
-
instanceObject로 promise를 해결합니다.
-
-
-
promise를 반환합니다.
-
promise를 새 프로미스로 둡니다.
-
promiseOfModule에 반응합니다:
-
promiseOfModule이 값 module로 이행된 경우:
-
importObject를 가져오면서 module인 WebAssembly 모듈을 인스턴스화하고, 그 결과를 innerPromise로 둡니다.
-
innerPromise에 반응합니다:
-
innerPromise이 값 instance로 이행된 경우.
-
result를
WebAssemblyInstantiatedSource값 «[ "module" → module, "instance" → instance ]»로 둡니다. -
result로 promise를 해결합니다.
-
-
innerPromise이 이유 reason으로 거부된 경우:
-
reason으로 promise를 거부합니다.
-
-
-
-
promiseOfModule이 이유 reason으로 거부된 경우:
-
reason으로 promise를 거부합니다.
-
-
-
promise를 반환합니다.
instantiate(bytes, importObject, options)
메서드는 호출되면 다음 단계를 수행합니다:
-
stableBytes를 bytes 버퍼가 보유한 바이트의 복사본으로 둡니다.
-
stableBytes로부터 options를 사용하여 WebAssembly 모듈을 비동기적으로 컴파일하고, 그 결과를 promiseOfModule로 둡니다.
-
가져오기 importObject를 사용하여 promiseOfModule을 인스턴스화하고 그 결과를 반환합니다.
instantiate(moduleObject, importObject)
메서드는 호출되면 다음 단계를 수행합니다:
-
importObject를 가져오면서 moduleObject인 WebAssembly 모듈을 비동기적으로 인스턴스화하고, 그 결과를 반환합니다.
참고: 후속 스트리밍 API는 WebAssembly Web API에 문서화되어 있습니다.
WebAssembly
Namespace의 JSTag 속성의 getter는 호출되면 다음 단계를 수행합니다:
-
JSTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.
-
JSTagObject를 JSTagAddr로부터 Tag 객체를 생성한 결과로 둡니다.
-
JSTagObject를 반환합니다.
5.1. 모듈
enum {ImportExportKind ,"function" ,"table" ,"memory" ,"global" };"tag" enum {AddressType ,"i32" , };"i64" typedef any ;AddressValue dictionary {ModuleExportDescriptor required USVString ;name required ImportExportKind ; // Note: Other fields such as signature may be added in the future. };kind 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
exports(moduleObject) 메서드는 호출되면,
다음 단계를 수행한다:
-
module을 moduleObject.[[Module]]라고 하자.
-
exports를 « »라고 하자.
-
각각에 대해 module_exports(module)의 (name, type)에 대해,
-
kind를 type의 extern type의 문자열 값이라고 하자.
-
Append를 사용하여 obj를 exports에 추가한다.
-
-
exports를 반환한다.
imports(moduleObject) 메서드는 호출되면,
다음 단계를 수행한다:
-
module을 moduleObject.[[Module]]라고 하자.
-
builtinSetNames를 moduleObject.[[BuiltinSets]]라고 하자.
-
importedStringModule를 moduleObject.[[ImportedStringModule]]라고 하자.
-
imports를 « »라고 하자.
-
각각에 대해 module_imports(module)의 (moduleName, name, type)에 대해,
-
만약 (moduleName, name, type)에 대해 빌트인을 찾기 결과가 있고 builtinSetNames가 null이 아니면, continue한다.
-
만약 importedStringModule이 null이 아니고 moduleName이 importedStringModule과 같다면, continue한다.
-
kind를 type의 extern type의 문자열 값이라고 하자.
-
obj를 «[ "
module" → moduleName, "name" → name, "kind" → kind ]»라고 하자. -
Append를 사용하여 obj를 imports에 추가한다.
-
-
imports를 반환한다.
customSections(moduleObject, sectionName)
메서드는 호출되면 다음 단계를 수행한다:
-
bytes를 moduleObject.[[Bytes]]라고 하자.
-
customSections를 « »라고 하자.
-
각각에 대해 bytes의 custom section customSection에 대해, module grammar에 따라 해석한다,
-
name을 customSection의
name을 UTF-8로 디코드한 것이라고 하자. -
단언: name은 failure가 아니다 (moduleObject.[[Module]]은 유효하다).
-
만약 name이 문자 값으로서 sectionName과 같다면,
-
Append를 사용하여 새로운
ArrayBuffer를 customSections에 추가한다. 이 ArrayBuffer는 이 customsec 생성 규칙에 매치된 범위에 대한 bytes의 복사본 바이트를 포함한다.
-
-
-
customSections를 반환한다.
Module(bytes, options) 생성자는
호출되면 다음 단계를 수행한다:
-
stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.
-
stableBytes를 WebAssembly 모듈로 컴파일하고 그 결과를 module로 저장한다.
-
만약 module이 error이면,
CompileError예외를 던진다. -
builtinSetNames를 options["builtins"]라고 하자.
-
importedStringModule을 options["importedStringConstants"]라고 하자.
-
만약 빌트인 및 imported strings 검증을 module에 대해 builtinSetNames 및 importedStringModule와 함께 수행한 결과가 false이면,
CompileError예외를 던진다. -
this.[[Module]]를 module로 설정한다.
-
this.[[Bytes]]를 stableBytes로 설정한다.
-
this.[[BuiltinSets]]를 builtinSetNames로 설정한다.
-
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)
생성자는 호출되면 다음 단계를 실행한다:
-
builtinSetNames를 moduleObject.[[BuiltinSets]]라고 하자.
-
importedStringModule를 moduleObject.[[ImportedStringModule]]라고 하자.
-
module을 moduleObject.[[Module]]라고 하자.
-
module의 imports를 읽고, imports importObject, builtinSetNames, 그리고 importedStringModule와 함께 사용하여, 그 결과를 imports라고 하자.
-
module을 imports와 함께 WebAssembly 모듈의 코어로 인스턴스화하고, 그 결과를 instance라고 하자.
-
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 객체는
다음 내부 슬롯을 가진다:
-
[[Memory]] : 하나의 메모리 주소
-
[[BufferObject]] : 위 메모리 주소와 식별되는 Data Block을 가지는
ArrayBuffer
-
block을 memaddr의 기저 메모리와 식별되는 Data Block이라고 하자.
-
buffer를 내부 슬롯 [[ArrayBufferData]], [[ArrayBufferByteLength]], 그리고 [[ArrayBufferDetachKey]]를 가진 새
ArrayBuffer라고 하자. -
buffer.[[ArrayBufferData]]를 block으로 설정한다.
-
buffer.[[ArrayBufferByteLength]]를 block의 길이로 설정한다.
-
buffer.[[ArrayBufferDetachKey]]를 "WebAssembly.Memory"로 설정한다.
-
buffer를 반환한다.
-
block을 memaddr의 기저 메모리와 식별되는 Data Block이라고 하자.
-
length를 block의 길이라고 하자.
-
buffer를 내부 슬롯 [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferMaxByteLength]], 그리고 [[ArrayBufferDetachKey]]를 가진 새
ArrayBuffer라고 하자. -
buffer.[[ArrayBufferData]]를 block으로 설정한다.
-
buffer.[[ArrayBufferByteLength]]를 length로 설정한다.
-
buffer.[[ArrayBufferMaxByteLength]]를 maxsize로 설정한다.
-
buffer.[[ArrayBufferDetachKey]]를 "WebAssembly.Memory"로 설정한다.
-
buffer를 반환한다.
-
map을 현재 agent에 연관된 Memory 객체 캐시라고 하자.
-
단언: map[memaddr]는 존재하지 않는다.
-
buffer를 고정 길이 메모리 버퍼를 생성하여 memaddr로부터 얻은 결과라고 하자.
-
memory.[[Memory]]를 memaddr로 설정한다.
-
memory.[[BufferObject]]를 buffer로 설정한다.
-
Set map[memaddr]를 memory로 설정한다.
Memory(descriptor) 생성자는 호출되면
다음 단계를 수행합니다:
-
descriptor["address"]가 존재하면, addrtype을 ToValueType(descriptor["address"])으로 두고, 그렇지 않으면 addrtype을 i32로 둡니다.
-
initial을 ? AddressValueToU64(descriptor["initial"], addrtype)으로 둡니다.
-
descriptor["maximum"]이 존재하면, maximum을 ? AddressValueToU64(descriptor["maximum"], addrtype)으로 두고, 그렇지 않으면 maximum을 비어 있는 값으로 둡니다.
-
memtype을 메모리 타입 addrtype [initial .. maximum] page로 둡니다.
-
memtype이 유효하지 않으면
RangeError예외를 던집니다. -
(store, memaddr)를 mem_alloc(store, memtype)으로 둡니다. 할당에 실패하면
RangeError예외를 던집니다. -
초기화를 this에 대해 memaddr로부터 수행합니다.
-
map을 주변 에이전트에 연결된 Memory 객체 캐시로 둡니다.
-
단언: map[memaddr]가 존재합니다.
-
memory를 map[memaddr]로 둡니다.
-
buffer를 memory.[[BufferObject]]로 둡니다.
-
IsFixedLengthArrayBuffer(buffer)가 true이면,
-
! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.
-
buffer를 고정 길이 메모리 버퍼를 생성한 결과로 두며, memaddr로부터 생성합니다.
-
memory.[[BufferObject]]를 buffer로 설정합니다.
-
-
그렇지 않으면,
-
ret를 mem_size(store, memaddr)로 둡니다.
-
store를 mem_grow(store, memaddr, delta)로 둡니다.
-
store가 오류이면
RangeError예외를 던집니다. -
memaddr의 메모리 버퍼를 새로 고칩니다.
-
ret를 반환합니다.
grow(delta) 메서드는 호출되면
다음 단계를 수행합니다:
-
memaddr를 this.[[Memory]]로 둡니다.
-
(addrtype, limits)를 mem_type(store, memaddr)으로 둡니다.
-
delta64를 ? AddressValueToU64(delta, addrtype)으로 둡니다.
-
ret를 메모리 버퍼를 증가시킨 결과로 두며, memaddr에 연결된 버퍼를 delta64만큼 증가시킵니다.
-
U64ToAddressValue(ret, addrtype)를 반환합니다.
WebAssembly memory.grow x 명령어가 실행된 직후 다음 단계를 수행합니다:
toFixedLengthBuffer() 메서드는 호출될 때
다음 단계를 수행합니다:
-
buffer를 this.[[BufferObject]]로 둡니다.
-
IsFixedLengthArrayBuffer(buffer)가 true이면 buffer를 반환합니다.
-
memaddr를 this.[[Memory]]로 둡니다.
-
fixedBuffer를 memaddr에서 고정 길이 메모리 버퍼를 생성한 결과로 둡니다.
-
! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.
-
this.[[BufferObject]]를 fixedBuffer로 설정합니다.
-
fixedBuffer를 반환합니다.
toResizableBuffer() 메서드는 호출될 때 다음
단계를 수행합니다:
-
memaddr를 this.[[Memory]]로 둡니다.
-
memtype을 mem_type(store, memaddr)로 둡니다.
-
memtype에 max가 없으면,
-
buffer를 this.[[BufferObject]]로 둡니다.
-
IsFixedLengthArrayBuffer(buffer)가 false이면 buffer를 반환합니다.
-
단언: memtype에는 max가 있습니다.
-
maxsize를 memtype의 max 값 * 65536으로 둡니다.
-
resizableBuffer를 memaddr 및 maxsize에서 크기 조정 가능한 메모리 버퍼를 생성한 결과로 둡니다.
-
! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.
-
this.[[BufferObject]]를 resizableBuffer로 설정합니다.
-
resizableBuffer를 반환합니다.
ArrayBuffer
객체가 Memory 객체에서 반환될
때에는
크기가 WebAssembly 페이지
크기(상수 65536)의 배수여야 합니다. 이러한 이유로 HostResizeArrayBuffer를 다음과 같이 다시 정의합니다.
추상
연산 HostResizeArrayBuffer는 인수
buffer(ArrayBuffer)
및 newLength를 받습니다. 호출될 때 다음 단계를 수행합니다.
-
buffer.[[ArrayBufferDetachKey]]가 "WebAssembly.Memory"이면,
-
map을 주변 에이전트의 연결된 Memory 객체 캐시로 둡니다.
-
단언: buffer는 map에 있는 정확히 하나의 값의 [[BufferObject]]입니다.
-
각각에 대해 map의 memaddr → mem에 대해,
-
SameValue(mem.[[BufferObject]], buffer)가 true이면,
-
단언: buffer.[[ArrayBufferByteLength]] modulo 65536은 0입니다.
-
lengthDelta를 newLength - buffer.[[ArrayBufferByteLength]]로 둡니다.
-
lengthDelta < 0이거나 lengthDelta modulo 65536이 0이 아니면,
-
RangeError예외를 발생시킵니다.
-
-
delta를 lengthDelta ÷ 65536으로 둡니다.
-
memaddr과 연결된 메모리 버퍼를 delta만큼 확장합니다.
-
-
-
handled 를 반환합니다.
-
-
그렇지 않으면
unhandled 를 반환합니다.
Memory의 buffer 속성의 getter는
this.[[BufferObject]]를 반환합니다.
5.4. 테이블
enum {TableKind ,"externref" , // 참고: 향후 반복에서 더 많은 값이 추가될 수 있음, // 예: typed function references, typed GC references };"anyfunc" 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]] 내부 슬롯을 가지며, 이는 하나의 테이블 주소이다.
-
map을 현재 agent에 연관된 Table 객체 캐시라고 하자.
-
단언: map[tableaddr]는 존재하지 않는다.
-
table.[[Table]]를 tableaddr로 설정한다.
-
Set map[tableaddr]를 table로 설정한다.
Table(descriptor, value) 생성자는 호출되면
다음 단계를 수행합니다:
-
elementtype을 ToValueType(descriptor["element"])으로 둡니다.
-
elementtype이 reftype이 아니면,
-
다음 예외를 던집니다:
TypeError예외입니다.
-
-
descriptor["address"]가 존재하면, addrtype을 ToValueType(descriptor["address"])으로 두고, 그렇지 않으면 addrtype을 i32로 둡니다.
-
initial을 ? AddressValueToU64(descriptor["initial"], addrtype)으로 둡니다.
-
descriptor["maximum"]이 존재하면, maximum을 ? AddressValueToU64(descriptor["maximum"], addrtype)으로 두고, 그렇지 않으면 maximum을 비어 있는 값으로 둡니다.
-
type을 테이블 타입 addrtype [initial .. maximum] elementtype으로 둡니다.
-
type이 유효하지 않으면
RangeError예외를 던집니다. -
value가 제공되지 않았다면,
-
ref를 DefaultValue(elementtype)로 둡니다.
-
단언: ref는 오류가 아닙니다.
-
-
그렇지 않으면,
-
ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.
-
-
(store, tableaddr)를 table_alloc(store, type, ref)로 둡니다. 할당에 실패하면
RangeError예외를 던집니다. -
초기화할 대상은 this이며, tableaddr를 사용합니다.
grow(delta, value) 메서드는 호출되면
다음 단계를 수행합니다:
-
tableaddr를 this.[[Table]]로 둡니다.
-
initialSize를 table_size(store, tableaddr)로 둡니다.
-
(addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.
-
delta64를 ? AddressValueToU64(delta, addrtype)으로 둡니다.
-
value가 제공되지 않았다면,
-
ref를 DefaultValue(elementtype)로 둡니다.
-
-
그렇지 않으면,
-
ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.
-
-
result를 table_grow(store, tableaddr, delta64, ref)로 둡니다.
-
result가 오류이면
RangeError예외를 던집니다.참고: 위 예외는 메모리 부족이나 잘못된 크기 매개변수 때문에 발생할 수 있습니다.
-
U64ToAddressValue(initialSize, addrtype)을 반환합니다.
Table의
length 속성의 getter는 호출되면
다음 단계를 수행합니다:
-
tableaddr를 this.[[Table]]로 둡니다.
-
(addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.
-
length64를 table_size(store, tableaddr)로 둡니다.
-
U64ToAddressValue(length64, addrtype)을 반환합니다.
get(index) 메서드는 호출되면 다음
단계를 수행합니다:
-
tableaddr를 this.[[Table]]로 둡니다.
-
(addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.
-
-
TypeError예외를 던집니다.
-
-
index64를 ? AddressValueToU64(index, addrtype)으로 둡니다.
-
result를 table_read(store, tableaddr, index64)로 둡니다.
-
result가 오류이면
RangeError예외를 던집니다. -
ToJSValue(result)를 반환합니다.
set(index, value) 메서드는 호출되면
다음 단계를 수행합니다:
-
tableaddr를 this.[[Table]]로 둡니다.
-
(addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.
-
-
TypeError예외를 던집니다.
-
-
index64를 ? AddressValueToU64(index, addrtype)으로 둡니다.
-
value가 제공되지 않았다면,
-
ref를 DefaultValue(elementtype)로 둡니다.
-
-
그렇지 않으면,
-
ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.
-
-
store를 table_write(store, tableaddr, index64, ref)로 둡니다.
-
store가 오류이면
RangeError예외를 던집니다.
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 객체는
하나의 내부 슬롯을 가진다:
-
[[Global]] : 하나의 전역 주소
-
map을 현재 agent에 연관된 Global 객체 캐시라고 하자.
-
단언: map[globaladdr]는 존재하지 않는다.
-
global.[[Global]]를 globaladdr로 설정한다.
-
Set map[globaladdr]를 global로 설정한다.
-
valuetype이 externref와 같으면 ! ToWebAssemblyValue(undefined, valuetype)를 반환합니다.
-
val_default(valuetype)를 반환합니다.
Global(descriptor, v) 생성자는
호출되면 다음 단계를 수행합니다:
-
mutable을 descriptor["mutable"]로 둡니다.
-
valuetype을 ToValueType(descriptor["value"])으로 둡니다.
-
valuetype이 일치하면 v128 또는 exnref와,
-
TypeError예외를 던집니다.
-
-
v가 제공되지 않았다면,
-
value를 DefaultValue(valuetype)로 둡니다.
-
단언: value는 오류가 아닙니다.
-
-
그렇지 않으면,
-
value를 ? ToWebAssemblyValue(v, valuetype)으로 둡니다.
-
-
mutable이 true이면 globaltype을 mut valuetype으로 두고, 그렇지 않으면 globaltype을 valuetype으로 둡니다.
-
(store, globaladdr)을 global_alloc(store, globaltype, value)로 둡니다.
-
globaladdr로부터 this를 초기화합니다.
Global
global)은 다음 단계를 수행합니다:
-
globaladdr를 global.[[Global]]로 둡니다.
-
globaltype을 global_type(store, globaladdr)으로 둡니다.
-
globaltype이 mut valuetype 형식이고 valuetype이 일치하면 v128 또는 exnref와,
TypeError를 던집니다. -
value를 global_read(store, globaladdr)로 둡니다.
-
ToJSValue(value)를 반환합니다.
Global의 value 속성
setter는
호출되면 다음 단계를 수행합니다:
-
globaladdr를 this.[[Global]]로 둡니다.
-
mut valuetype을 global_type(store, globaladdr)으로 둡니다.
-
mut가 비어 있으면
TypeError를 던집니다. -
value를 ? ToWebAssemblyValue(주어진 값, valuetype)으로 둡니다.
-
store를 global_write(store, globaladdr, value)로 둡니다.
-
store가 오류이면
RangeError예외를 던집니다.
valueOf() 메서드는 호출되면 다음 단계를 수행합니다:
-
GetGlobalValue(this)를 반환합니다.
5.6. 내보낸 함수
WebAssembly 함수는 JavaScript에서 내보낸 함수로 제공된다. 내보낸 함수는 생성자가 아닌 내장 함수 객체이며, [[FunctionAddress]] 내부 슬롯을 가진다. 이 슬롯은 함수 주소를 저장하며, 이는 현재 agent의 연관 저장소에 상대적이다.
-
funcinst를 store.funcs[funcaddr]로 둡니다.
-
funcinst가 {type functype, hostcode hostfunc} 형식이면,
-
단언: hostfunc는 JavaScript 객체이며 IsCallable(hostfunc)은 true입니다.
-
index를 funcaddr의 호스트 함수 인덱스로 둡니다.
-
-
그렇지 않으면,
-
moduleinst를 funcinst.module로 둡니다.
-
단언: funcaddr는 moduleinst.funcs에 포함됩니다.
-
index를 moduleinst.funcs에서 funcaddr가 발견되는 인덱스로 둡니다.
-
-
map[funcaddr]가 존재하면,
-
map[funcaddr]를 반환합니다.
-
-
steps를 "내보낸 함수를 호출 funcaddr 인수를 사용하여."로 둡니다.
-
realm을 현재 Realm으로 둡니다.
-
functype을 func_type(store, funcaddr)으로 둡니다.
-
arity를 paramTypes의 크기로 둡니다.
-
name을 WebAssembly 함수의 이름 funcaddr로 둡니다.
-
function을 CreateBuiltinFunction(steps, arity, name, « [[FunctionAddress]] », realm)으로 둡니다.
-
function.[[FunctionAddress]]를 funcaddr로 설정합니다.
-
설정합니다: map[funcaddr]를 function으로 설정합니다.
-
function을 반환합니다.
-
functype을 func_type(store, funcaddr)으로 둡니다.
-
parameters 또는 results의 어떤 타입이든 일치하면 v128 또는 exnref와,
TypeError를 던집니다.참고: 위 오류는 [[Call]] 메서드가 호출될 때마다 발생합니다.
-
args를 « »로 둡니다.
-
i를 0으로 둡니다.
-
parameters의 각 t에 대해,
-
argValues의 크기가 i보다 크면 arg를 argValues[i]로 둡니다.
-
그렇지 않으면 arg를 undefined로 둡니다.
-
추가합니다: ? ToWebAssemblyValue(arg, t)를 args에 추가합니다.
-
i를 i + 1로 설정합니다.
-
-
(store, ret)를 func_invoke(store, funcaddr, args)의 결과로 둡니다.
-
ret가 오류이면 예외를 던집니다. 이 예외는 WebAssembly
RuntimeError예외여야 하지만, WebAssembly 오류 매핑에서 달리 지정한 경우는 제외합니다. -
ret가 exception exnaddr 형식이면,
-
tagaddr를 exn_tag(store, exnaddr)로 둡니다.
-
payload를 exn_read(store, exnaddr)로 둡니다.
-
jsTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.
-
tagaddr가 jsTagAddr와 같으면,
-
ToJSValue(payload[0])를 던집니다.
-
-
그렇지 않으면,
-
exception을 exnaddr에서 생성한 새로운 Exception으로 둡니다.
-
exception을 던집니다.
-
-
-
outArity를 ret의 크기로 둡니다.
-
outArity가 0이면 undefined를 반환합니다.
-
그렇지 않고 outArity가 1이면 ToJSValue(ret[0])를 반환합니다.
-
그렇지 않으면,
-
values를 « »로 둡니다.
-
ret의 각 r에 대해,
-
CreateArrayFromList(values)를 반환합니다.
-
참고: 내보낸 함수를 호출하는 작업은 내장 함수 객체의 정의에 따라 피호출자 내보낸 함수의 [[Realm]]에서 실행됩니다.
참고: 내보낸 함수에는 [[Construct]]
메서드가 없으므로 new 연산자로 호출할 수 없습니다.
-
parameters 또는 results의 어떤 타입이든 일치하면 v128 또는 exnref와,
TypeError를 던집니다. -
jsArguments를 « »로 둡니다.
-
arguments의 각 arg에 대해,
-
resultsSize를 results의 크기로 둡니다.
-
resultsSize가 0이면 « »를 반환합니다.
-
그렇지 않고 resultsSize가 1이면 « ? ToWebAssemblyValue(ret, results[0]) »를 반환합니다.
-
그렇지 않으면,
-
method를 ? GetMethod(ret,
%Symbol.iterator%)로 둡니다. -
values를 ? IteratorToList(? GetIteratorFromMethod(ret, method))로 둡니다.
-
wasmValues를 새로운 빈 목록으로 둡니다.
-
values와 results에서 value와 resultType을 순서대로 쌍으로 묶어 각각에 대해 다음을 수행합니다.
-
추가합니다: ? ToWebAssemblyValue(value, resultType)을 wasmValues에 추가합니다.
-
-
wasmValues를 반환합니다.
-
-
단언: IsCallable(func).
-
stored settings를 현직 설정 객체로 둡니다.
-
hostfunc을 다음 단계를 수행하는 호스트 함수로 둡니다. 이 함수는 인수 arguments로 호출될 때 다음을 수행합니다.
-
realm을 func의 연결된 Realm으로 둡니다.
-
relevant settings를 realm의 설정 객체로 둡니다.
-
relevant settings를 사용하여 스크립트 실행을 준비합니다.
-
stored settings를 사용하여 콜백 실행을 준비합니다.
-
result를 func, functype 및 arguments로 호스트 함수를 실행한 결과로 둡니다.
-
stored settings를 사용하여 콜백 실행 후 정리합니다.
-
relevant settings를 사용하여 스크립트 실행 후 정리합니다.
-
단언: result.[[Type]]은
throw 또는normal 입니다. -
result.[[Type]]이
throw 이면,-
v를 result.[[Value]]로 둡니다.
-
-
address를 v.[[Address]]로 둡니다.
-
-
그렇지 않으면,
-
type을 JavaScript 예외 태그를 가져온 결과로 둡니다.
-
payload를 ! ToWebAssemblyValue(v, externref)로 둡니다.
-
(store, address)를 exn_alloc(store, type, « payload »)로 둡니다.
-
-
-
그렇지 않으면 result.[[Value]]를 반환합니다.
-
-
(store, funcaddr)를 func_alloc(store, functype, hostfunc)로 둡니다.
-
funcaddr를 반환합니다.
-
단언: w는 v128.const v128 형식이 아닙니다.
-
단언: w는 ref.exn exnaddr 형식이 아닙니다.
-
w가 i64.const u64 형식이면,
-
w가 i32.const u32 형식이면,
-
w가 f32.const f32 형식이면,
-
w가 f64.const f64 형식이면,
-
w가 ref.null 형식이면 null을 반환합니다.
-
w가 ref.i31 u31 형식이면,
-
w가 ref.struct structaddr 형식이면 새로운 내보낸 GC 객체를 생성한 결과를 반환하며, structaddr와 "struct"를 사용합니다.
-
w가 ref.array arrayaddr 형식이면 새로운 내보낸 GC 객체를 생성한 결과를 반환하며, arrayaddr와 "array"를 사용합니다.
-
w가 ref.func funcaddr 형식이면 새로운 내보낸 함수를 funcaddr에서 생성한 결과를 반환합니다.
-
w가 ref.host hostaddr 형식이면 호스트 값을 가져온 결과를 hostaddr에서 반환합니다.
-
w가 ref.extern ref 형식이면 ToJSValue(ref)를 반환합니다.
참고: NaN과 같은 Number 값에는 관찰 가능한 다양한 NaN 페이로드가 있을 수 있습니다. 자세한 내용은 NumericToRawBytes를 참조하세요.
호스트 주소 hostaddr에서 호스트 값을 가져오려면 다음 단계를 수행합니다:
-
단언: type은 v128이 아닙니다.
-
type이 i64이면,
-
i64를 ? ToBigInt64(v)로 둡니다.
-
u64를 i64가 signed_64(u64)가 되는 부호 없는 정수로 둡니다.
-
i64.const u64를 반환합니다.
-
-
type이 i32이면,
-
type이 f32이면,
-
type이 f64이면,
-
type이 ref null heaptype 형식이면,
-
v가 null이면,
-
r을 ref.null로 둡니다.
-
-
그렇지 않고 match_valtype(type, ref null extern)이 true이면,
-
ref를 ! ToWebAssemblyValue(v, ref any)로 둡니다.
-
r을 ref.extern ref로 둡니다.
-
-
그렇지 않고 v가 내보낸 함수이며 match_valtype(type, ref null func)가 true이면,
-
funcaddr를 v의 [[FunctionAddress]] 내부 슬롯 값으로 둡니다.
-
r을 ref.func funcaddr로 둡니다.
-
-
그렇지 않고 v가 Number이며 v가 ? ToInt32(v)와 같고 ℝ(v) < 230이며 ℝ(v) ⩾ -230이면,
-
그렇지 않고 v가 내보낸 GC 객체이면,
-
objectaddr를 v의 [[ObjectAddress]] 내부 슬롯 값으로 둡니다.
-
objectkind를 v의 [[ObjectKind]] 내부 슬롯 값으로 둡니다.
-
objectkind가 "array"이면,
-
r을 ref.array objectaddr로 둡니다.
-
-
그렇지 않고 objectkind가 "struct"이면,
-
r을 ref.struct objectaddr로 둡니다.
-
-
-
그렇지 않으면,
-
actualtype을 ref_type(store, r)으로 둡니다.
-
match_valtype(actualtype, type)이 false이면,
-
TypeError를 던집니다.
-
-
r을 반환합니다.
-
-
단언: 이 단계에는 도달하지 않습니다.
AddressType
"i32"에 대해 [EnforceRange] unsigned
long처럼 동작하고, AddressType
"i64"에도 이러한 의미 체계를 확장하도록 설계되었으며, 다음 단계를 수행합니다:
-
jsValue를 v를 JavaScript 값으로 변환한 값으로 둡니다.
참고: IDL
any타입은 JavaScript 값을 단순히 감싸는 래퍼가 아니라 구별된 유니언입니다. -
addrtype이 i32이면,
-
n을 ? ConvertToInt(jsValue, 32, "unsigned")로 두며, 대상 타입에는 [EnforceRange]가 연결되어 있습니다.
참고: 이는 JavaScript 변환 규칙과 동일하며, [EnforceRange] unsigned long에 적용됩니다.
-
-
addrtype이 i64이면,
-
단언: 이 단계에는 도달하지 않습니다.
AddressType에
맞는 AddressValue
변형으로 변환하며,
다음 단계를 수행합니다:
5.7. 태그
5.7.1. 태그 타입
dictionary {TagType required sequence <ValueType >; }; [parameters LegacyNamespace =WebAssembly , Exposed=*]interface {Tag constructor (TagType ); };type
Tag 값은
예외 태그를 나타낸다.
Tag 객체를 초기화하려면, 태그 주소 tagAddress로부터 tag에 대해 다음 단계를 수행한다:
다음 new Tag(type)
생성자 단계는 다음과 같습니다:
-
parameters를 type["parameters"]로 둡니다.
-
wasmParameters를 «»로 둡니다.
-
각각에 대해 paramType을 parameters에서 가져와,
-
추가: ToValueType(paramType)을 wasmParameters에 추가합니다.
-
-
tagtype을 다음 조건을 만족하는 정의된 타입으로 둡니다. 즉, func wasmParameters → « »가 확장 결과인 tagtype입니다.
-
(store, tagAddress)를 tag_alloc(store, tagtype)로 둡니다.
-
초기화를 수행하며 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의 내부 메서드는 다음 구현을 사용한다.
-
null을 반환한다.
-
false를 반환한다.
-
false를 반환한다.
-
false를 반환한다.
-
undefined를 반환한다.
-
false를 반환한다.
-
false를 반환한다.
-
undefined를 반환한다.
-
TypeError를 던진다.
-
TypeError를 던진다.
-
« »를 반환합니다.
-
단언: objectkind는 "array" 또는 "struct" 중 하나이다.
-
map을 현재 agent에 연관된 exported GC object cache라고 하자.
-
만약 map[objectaddr]가 존재하면,
-
map[objectaddr]를 반환한다.
-
-
object를 MakeBasicObject(« [[ObjectAddress]], [[ObjectKind]] »)라고 하자.
-
object.[[ObjectAddress]]를 objectaddr로 설정한다.
-
object.[[ObjectKind]]를 objectkind로 설정한다.
-
object.[[GetPrototypeOf]]를 Exported GC Object의 [[GetPrototypeOf]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[SetPrototypeOf]]를 Exported GC Object의 [[SetPrototypeOf]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[IsExtensible]]를 Exported GC Object의 [[IsExtensible]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[PreventExtensions]]를 Exported GC Object의 [[PreventExtensions]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[GetOwnProperty]]를 Exported GC Object의 [[GetOwnProperty]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[DefineOwnProperty]]를 Exported GC Object의 [[DefineOwnProperty]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[HasProperty]]를 Exported GC Object의 [[HasProperty]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[Get]]를 Exported GC Object의 [[Get]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[Set]]를 Exported GC Object의 [[Set]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[Delete]]를 Exported GC Object의 [[Delete]] 내부 메서드에 명시된 대로 설정한다.
-
object.[[OwnPropertyKeys]]를 Exported GC Object의 [[OwnPropertyKeys]] 내부 메서드에 명시된 대로 설정한다.
-
Set map[objectaddr]를 object로 설정한다.
-
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에 대해 다음 단계를 수행한다:
-
map을 현재 agent에 연관된 Exception 객체 캐시라고 하자.
-
단언: map[exnAddress]는 존재하지 않는다.
-
exn.[[Address]]를 exnAddress로 설정한다.
-
Set map[exnAddress]를 exn로 설정한다.
-
tagaddr를 exn_tag(store, exnAddress)라고 하자.
-
payload를 exn_read(store, exnAddress)라고 하자.
-
exn.[[Type]]를 tagaddr로 설정한다.
-
exn.[[Payload]]를 payload로 설정한다.
-
exn.[[Stack]]를 undefined로 설정한다.
Exception 객체를 생성하려면, exception address exnAddress로부터 다음 단계를 수행한다:
new Exception(exceptionTag, payload, options)
생성자의 단계는 다음과 같습니다:
-
JSTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.
-
exceptionTag.[[Address]]가 JSTagAddr와 같으면,
-
TypeError를 던집니다.
-
-
func types → « »를 확장 결과로 두며, 이는 tag_type(store, exceptionTag.[[Address]])를 확장한 값입니다.
-
-
TypeError를 던집니다.
-
-
wasmPayload를 « »로 둡니다.
-
각 value와 resultType을 payload와 types에서 순서대로 짝지어,
-
(store, exceptionAddr)를 exn_alloc(store, exceptionTag.[[Address]], wasmPayload)로 둡니다.
-
초기화할 대상은 this이며, exceptionAddr를 사용합니다.
-
options["traceStack"]이 true이면,
-
this.[[Stack]]을 현재 호출 스택의
DOMString표현 또는 undefined로 설정합니다.
-
getArg(exceptionTag, index)
메서드의 단계는 다음과 같습니다:
-
this.[[Type]]이 exceptionTag.[[Address]]와 같지 않으면,
-
TypeError를 던집니다.
-
-
tagaddr를 exn_tag(store, this.[[Address]])로 둡니다.
-
payload를 exn_read(store, this.[[Address]])로 둡니다.
-
단언: tagaddr는 this.[[Type]]과 같습니다.
-
index ≥ payload의 크기이면,
-
RangeError를 던집니다.
-
-
func types → « »를 확장 결과로 두며, 이는 tag_type(store, tagaddr)를 확장한 값입니다.
-
types[index]가 일치하는 대상이 v128 또는 exnref이면,
-
TypeError를 던집니다.
-
-
ToJSValue(payload[index])를 반환합니다.
is(exceptionTag) 메서드의 단계는 다음과 같습니다:
-
this.[[Type]]이 exceptionTag.[[Address]]와 같지 않으면,
-
false를 반환합니다.
-
-
true를 반환합니다.
stack getter의 단계는 다음과 같습니다:
-
this.[[Stack]]을 반환합니다.
5.9.1. JavaScript 예외
JavaScript 예외 태그는 태그 주소이며 주변 에이전트에 연결됩니다. 이 태그는 에이전트의 연결된 저장소에 처음 사용될 때 할당되어 캐시됩니다. 이 태그의 태그 타입은 항상 « externref » → « »입니다.
JavaScript 예외 태그를 가져오려면, 다음 단계를 수행합니다:
-
주변 에이전트에 연결된 JavaScript 예외 태그가 초기화되어 있다면,
-
다음 주변 에이전트에 연결된 JavaScript 예외 태그를 반환합니다.
-
-
tagtype을 다음 조건을 만족하는 정의된 타입으로 둡니다. 즉, func « externref » → « »가 확장 결과가 되는 tagtype입니다.
-
(store, tagAddress)를 tag_alloc(store, tagtype)로 둡니다.
-
주변 에이전트에 연결된 JavaScript 예외 태그를 tagAddress로 설정합니다.
-
tagAddress를 반환합니다.
5.10. 오류 객체
WebAssembly는 다음 Error 클래스를 정의한다: CompileError, LinkError, 그리고 RuntimeError.
WebAssembly
네임스페이스의 namespace object가 생성될 때, 다음 단계를 실행해야 한다:
-
namespaceObject를 그 namespace object라고 하자.
-
각각에 대해 error of « "CompileError", "LinkError", "RuntimeError" »,
-
constructor를 새 객체라고 하자. 이 객체는 NativeError Object Structure를 구현하며, NativeError가 error로 설정된다.
-
! 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으로 수행하려면, 다음 단계를 수행한다:
-
이 절 안에서 정의된 이름 builtinSetName을 가진 집합에 대해, (name, funcType, steps)의 리스트를 반환한다.
빌트인 찾기를 import와 활성화된 빌트인 builtinSetNames로 수행하려면, 다음 단계를 수행한다:
-
단언: 빌트인 집합 이름 검증 builtinSetNames는 true이다.
-
importModuleName을 import[0]이라고 하자.
-
importName을 import[1]이라고 하자.
-
각각에 대해 builtinSetName of builtinSetNames,
-
만약 builtinSetName이 빌트인 집합을 가리키지 않으면, continue한다.
-
builtinSetQualifiedName을 builtinSetName 앞에 "wasm:"를 붙인 것이라고 하자.
-
만약 importModuleName이 builtinSetQualifiedName과 같으면,
-
builtins를 빌트인 집합의 빌트인 가져오기 builtinSetName의 결과라고 하자.
-
각각에 대해 builtin of builtins,
-
builtinName을 builtin[0]이라고 하자.
-
만약 importName이 builtinName과 같으면, (builtinSetName, builtin)를 반환한다.
-
-
-
-
null을 반환한다.
빌트인 집합 이름 검증을 builtinSetNames로 수행하려면, 다음 단계를 수행한다:
-
만약 builtinSetNames가 중복을 하나라도 포함하면, false를 반환한다.
-
true를 반환한다.
빌트인 함수 생성을 타입 funcType 및 실행 단계 steps로부터 수행하려면, 다음 단계를 수행한다:
이름이 builtinSetName인 내장 집합을 인스턴스화하려면 다음 단계를 수행합니다:
-
builtins를 builtinSetName에 대해 내장 집합의 내장 기능을 가져온 결과로 둡니다.
-
exportsObject를 OrdinaryObjectCreate(null)로 둡니다.
-
builtins의 각 (name, funcType, steps)에 대해 각각에 대해,
-
funcaddr를 funcType 및 steps를 사용하여 내장 함수를 생성한 결과로 둡니다.
-
func를 funcaddr에서 새 내보낸 함수를 생성한 결과로 둡니다.
-
value를 func로 둡니다.
-
status를 ! CreateDataProperty(exportsObject, name, value)로 둡니다.
-
단언: status는 true입니다.
-
-
exportsObject를 반환합니다.
import 및 활성화된 내장 기능 builtinSetNames을 사용하여 내장 기능에 대한 가져오기를 검증하려면 다음 단계를 수행합니다:
-
단언: 내장 집합 이름을 검증한 builtinSetNames의 결과는 true입니다.
-
maybeBuiltin을 import 및 builtinSetNames에 대해 내장 기능을 찾은 결과로 둡니다.
-
maybeBuiltin이 null이면 true를 반환합니다.
-
importExternType을 import[2]로 둡니다.
-
builtinFuncType을 maybeBuiltin[1][1]로 둡니다.
-
builtinExternType을
func |builtinFuncType|으로 둡니다. -
match_externtype(builtinExternType, importExternType)을 반환합니다.
6.1. 문자열 빌트인
문자열 빌트인은 String 빌트인
객체의 인터페이스를 조정한다. 이 집합의 이름은
js-string이고, 정규화된 이름은 wasm:js-string이다.
참고: 이 절의 알고리즘은 JS 빌트인으로서 String에 정의된 것들을 참조한다. 이들은 실제 빌트인을 가리키며, String 객체에 대해 동적 조회를 수행하지 않는다.
6.1.1. 추상 연산
추상 연산 UnwrapString(v)은 호출되면, 다음 단계를 수행한다:
-
만약 v가 String이 아니면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
v를 반환한다
FromCharCode(v) 추상 연산은 호출되면 다음 단계를 수행합니다:
-
단언: v는 i32 타입입니다.
-
! Call(String.fromCharCode, undefined, « ToJSValue(v) »)를 반환합니다.
CharCodeAt(string, index) 추상 연산은 호출되면 다음 단계를 수행합니다:
-
단언: index는 i32 타입입니다.
-
! Call(String.prototype.charCodeAt, string, « ToJSValue(index) »)를 반환합니다.
6.1.2. cast
이 빌트인의 funcType은
(rec (type (func (param externref) (result (ref extern))))).0이다.
이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:
-
? UnwrapString(v)를 반환한다
6.1.3. test
이 빌트인의 funcType은 (rec (type (func (param externref) (result i32)))).0이다.
이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:
-
만약 v가 String이 아니면,
-
0을 반환한다.
-
-
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와 함께 호출되면, 다음 단계를 실행해야 한다:
-
만약 array가 null이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
length를 array 안의 원소 수라고 하자.
-
만약 start > end 또는 end > length이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
result를 빈 문자열이라고 하자.
-
i를 start라고 하자.
-
i < end인 동안:
-
charCode를 array의 인덱스 i에 저장된 원소의 값이라고 하자.
-
charCodeString을 FromCharCode(charCode)라고 하자.
-
result를 result와 charCodeString의 연결이라고 하자.
-
i를 i + 1로 설정한다.
-
-
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와 함께 호출되면, 다음 단계를 실행해야 한다:
-
만약 array가 null이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
string을 ? UnwrapString(string)라고 하자.
-
stringLength를 string의 길이라고 하자.
-
arrayLength를 array 안의 원소 수라고 하자.
-
만약 start + stringLength > arrayLength이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
i를 0이라고 하자.
-
i < stringLength인 동안:
-
charCode를 CharCodeAt(string, i)라고 하자.
-
array 안의 인덱스 start + i 위치의 원소를 ToWebAssemblyValue(charCode, i32)로 설정한다.
-
i를 i + 1로 설정한다.
-
-
stringLength를 반환한다.
6.1.6. fromCharCode
이 빌트인의 funcType은
(rec (type (func (param i32) (result (ref extern))))).0이다.
이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:
-
FromCharCode(v)를 반환한다.
6.1.7. fromCodePoint
이 빌트인의 funcType은 (rec (type (func (param i32) (result externref)))).0이다.
이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:
-
만약 v > 0x10ffff이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
! Call(String.fromCodePoint, undefined, « ToJSValue(v) »)를 반환한다.
6.1.8. charCodeAt
이 함수의 타입은 (rec (type (func (param externref i32) (result i32)))).0이다.
이 빌트인이 매개변수 string 및 index와 함께 호출되면, 다음 단계를 실행해야 한다:
-
string을 ? UnwrapString(string)라고 하자.
-
length를 string의 길이 라고 하자.
-
만약 index >= length이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
CharCodeAt(string, index)를 반환한다.
6.1.9. codePointAt
이 함수의 타입은 (rec (type (func (param externref i32) (result i32)))).0이다.
이 빌트인이 매개변수 string 및 index와 함께 호출되면, 다음 단계를 실행해야 한다:
-
string을 ? UnwrapString(string)라고 하자.
-
length를 string의 길이 라고 하자.
-
만약 index >= length이면,
-
트랩이 실행된 것처럼
RuntimeError예외를 던진다.
-
-
! Call(String.prototype.codePointAt, string, « ToJSValue(index) »)를 반환한다.
6.1.10. length
이 빌트인의 funcType은 (rec (type (func (param externref) (result i32)))).0이다.
이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:
-
string을 ? UnwrapString(v)라고 하자.
-
string의 길이를 반환한다.
6.1.11. concat
이 빌트인의 funcType은
(rec (type (func (param externref externref) (result (ref extern))))).0이다.
이 내장 기능이 매개변수 first 및 second와 함께 호출되면 다음 단계를 반드시 실행해야 합니다:
-
first를 ? UnwrapString(first)으로 둡니다.
-
second를 ? UnwrapString(second)으로 둡니다.
-
! 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와 함께 호출되면 다음 단계를 반드시 실행해야 합니다:
-
string을 ? UnwrapString(string)으로 둡니다.
-
length를 string의 길이로 둡니다.
-
start > end이거나 start > length이면,
-
빈 문자열을 반환합니다.
-
-
! 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와 함께 호출되면, 다음 단계를 반드시 실행해야 합니다:
-
first가 null이 아니고 first가 String이 아니면,
-
트랩이 실행된 것처럼
RuntimeError예외를 발생시킵니다.
-
-
second가 null이 아니고 second가 String이 아니면,
-
트랩이 실행된 것처럼
RuntimeError예외를 발생시킵니다.
-
-
IsStrictlyEqual(first, second)이 true이면,
-
1을 반환합니다.
-
-
0을 반환합니다.
6.1.14. compare
이 빌트인의 funcType은
(rec (type (func (param externref externref) (result i32)))).0이다.
이 내장 기능이 매개변수 first 및 second와 함께 호출되면, 다음 단계를 반드시 실행해야 합니다:
-
first를 ? UnwrapString(first)으로 둡니다.
-
second를 ? UnwrapString(second)으로 둡니다.
-
IsStrictlyEqual(first, second)이 true이면,
-
0을 반환합니다.
-
-
! IsLessThan(first, second, true)가 true이면,
-
-1을 반환합니다.
-
-
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를 던지거나 충돌하는 것으로 관찰되었다. 여기서는 둘 다 유효하다.
-
RangeError, 이는Memorygrow()및Tablegrow()연산에서 명시된다 -
memory.grow 명령의 결과로 -1을 반환하는 것
-
이 절에서 설명한 UA별 OOM 동작.
추가 논의는 Issue 879를 참조하라.
8. 구현 정의 한계
WebAssembly 코어 명세는 구현이 모듈의 구문 구조에 대한 한계를 정의할 수 있도록 허용한다.
WebAssembly의 각 임베딩은 자체 한계를 선택해 정의할 수 있지만, 예측 가능성을 위해
이 문서에서 설명하는 표준 WebAssembly JavaScript Interface는 다음과 같은 정확한 한계를 정의한다.
구현은 다음 한계 중 하나를 초과하는 모듈을 CompileError와
함께 거부해야 한다.
실제로는 구현이 이러한 한계보다 작은 유효한 모듈에 대해서도 리소스가 부족해질 수 있다.
- 모듈의 최대 크기는 1,073,741,824바이트(1 GiB)이다.
- types section에 정의될 수 있는 최대 타입 수는 1,000,000이다.
- types sections에 정의될 수 있는 최대 재귀 그룹 수는 1,000,000이다.
- 재귀 그룹에 정의될 수 있는 최대 타입 수는 1,000,000이다.
- 정의된 subtype 계층 구조의 최대 깊이는 63이다 (슈퍼타입 없이 정의된 타입의 깊이는 0이다).
- 모듈에 정의될 수 있는 최대 함수 수는 1,000,000이다.
- 모듈에 선언될 수 있는 최대 import 수는 1,000,000이다.
- 모듈에 선언될 수 있는 최대 export 수는 1,000,000이다.
- 모듈에 정의될 수 있는 최대 global 수는 1,000,000이다.
- 모듈에 정의될 수 있는 최대 tag 수는 1,000,000이다.
- 모듈에 정의될 수 있는 최대 data segment 수는 100,000이다.
- 선언되거나 import된 테이블을 포함한 최대 테이블 수는 100,000이다.
- 테이블의 최대 크기는 10,000,000이다.
- 임의의 테이블 초기화에서 테이블 엔트리의 최대 수는 10,000,000이다.
- 정의되거나 import된 메모리를 포함한 최대 메모리 수는 100이다.
- 32비트 메모리의 최대
min또는max필드는 65,536페이지(4 GiB)이다. - 64비트 메모리의 최대
min또는max필드는 2^37-1페이지(2^53 - 2^16 바이트)이다. - 임의의 함수 또는 블록에 대한 최대 매개변수 수는 1,000이다.
- 임의의 함수 또는 블록에 대한 최대 반환값 수는 1,000이다.
- 지역 변수 선언을 포함한 함수 본문의 최대 크기는 7,654,321바이트이다.
- 매개변수로 암묵적으로 선언된 것을 포함한 함수 내 선언 가능한 최대 지역 변수 수는 50,000이다.
- struct의 최대 필드 수는 10,000이다.
array.new_fixed의 최대 피연산자 수는 10,000이다.
구현은 런타임 중 다음 한계 중 하나가 초과되면 RuntimeError를
던져야 한다:
실제로는 구현이 이러한 한계보다 작은 유효한 모듈에 대해서도 리소스가 부족해질 수 있다.
- 테이블의 최대 크기는 10,000,000이다.
- 32비트 메모리의 최대 크기는 65,536페이지(4 GiB)이다.
- 64비트 메모리의 최대 크기는 262,144페이지(16 GiB)이다.
9. 보안 및 개인정보 보호 고려 사항
이 절은 비규범적이다.
이 문서는 WebAssembly를 위한 호스트 환경을 정의한다. 이는 WebAssembly 인스턴스가 import를 통해 JavaScript 객체와 함수를 import object로부터 가져올 수 있게 하지만, 그 외에는 임베딩 환경에 대한 접근을 제공하지 않는다. 따라서 WebAssembly 인스턴스는 JavaScript와 동일한 제약에 묶인다.
10. 변경 이력
이 절은 비규범적이다.
WebAssembly 명세의 원래 1.0 릴리스 이후, 여러 확장 제안이 통합되었다. 다음 절에서는 무엇이 변경되었는지에 대한 개요를 제공한다.