diff --git a/document/js-api/index.bs b/document/js-api/index.bs
index f99f9f578..2f3588843 100644
--- a/document/js-api/index.bs
+++ b/document/js-api/index.bs
@@ -82,6 +82,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT
text: SetFunctionName; url: sec-setfunctionname
text: SetFunctionLength; url: sec-setfunctionlength
text: the Number value; url: sec-ecmascript-language-types-number-type
+ text: is a Number; url: sec-ecmascript-language-types-number-type
text: NumberToRawBytes; url: sec-numbertorawbytes
text: Built-in Function Objects; url: sec-built-in-function-objects
text: NativeError Object Structure; url: sec-nativeerror-object-structure
@@ -90,6 +91,8 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT
text: IterableToList; url: sec-iterabletolist
text: ToBigInt64; url: #sec-tobigint64
text: BigInt; url: #sec-ecmascript-language-types-bigint-type
+ text: MakeBasicObject; url: #sec-makebasicobject
+ text: ℝ; url: #ℝ
type: abstract-op
text: CreateMethodProperty; url: sec-createmethodproperty
urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: dfn
@@ -113,6 +116,11 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: ref.null
text: ref.func
text: ref.extern
+
+ text: ref.i31
+ text: ref.array
+ text: ref.struct
+ text: ref.host
text: function index; url: syntax/modules.html#syntax-funcidx
text: function instance; url: exec/runtime.html#function-instances
text: store_init; url: appendix/embedding.html#embed-store-init
@@ -142,6 +150,14 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: global_read; url: appendix/embedding.html#embed-global-read
text: global_write; url: appendix/embedding.html#embed-global-write
text: error; url: appendix/embedding.html#embed-error
+
+ text: i31_new; url: appendix/embedding.html#embed-gc
+ text: i31_get; url: appendix/embedding.html#embed-gc
+ text: ref_test; url: appendix/embedding.html#embed-gc
+ text: extern_internalize; url: appendix/embedding.html#embed-gc; for: embedder
+ text: extern_externalize; url: appendix/embedding.html#embed-gc; for: embedder
+ text: extern.internalize; url: syntax/instructions.html#reference-instructions
+ text: extern.externalize; url: syntax/instructions.html#reference-instructions
text: store; url: exec/runtime.html#syntax-store
text: table type; url: syntax/types.html#syntax-tabletype
text: table address; url: exec/runtime.html#syntax-tableaddr
@@ -149,6 +165,8 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: memory address; url: exec/runtime.html#syntax-memaddr
text: global address; url: exec/runtime.html#syntax-globaladdr
text: extern address; url: exec/runtime.html#syntax-externaddr
+
+ text: object address; url: exec/runtime.html#syntax-objectaddr
url: syntax/types.html#syntax-numtype
text: i32
text: i64
@@ -159,6 +177,12 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: reftype
text: funcref
text: externref
+ text: ref
+ url: syntax/types.html#heap-types; for: heap-type
+ text: extern
+ text: func
+ text: i31
+ text: any
text: function element; url: exec/runtime.html#syntax-funcelem
text: import component; url: syntax/modules.html#imports
text: external value; url: exec/runtime.html#syntax-externval
@@ -167,7 +191,7 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: module; url: syntax/modules.html#syntax-module
text: imports; url: syntax/modules.html#syntax-module
text: import; url: syntax/modules.html#syntax-import
- url: syntax/types.html#external-types
+ url: syntax/types.html#external-types; for: external-type
text: external type
text: func
text: table
@@ -267,6 +291,7 @@ Each [=agent=] is associated with the following [=ordered map=]s:
* The Memory object cache, mapping [=memory address=]es to {{Memory}} objects.
* The Table object cache, mapping [=table address=]es to {{Table}} objects.
* The Exported Function cache, mapping [=function address=]es to [=Exported Function=] objects.
+ * The Exported GC Object cache, mapping [=object address=]es to [=Exported GC Object=] objects.
* The Global object cache, mapping [=global address=]es to {{Global}} objects.
* The Extern value cache, mapping [=extern address=]es to values.
@@ -358,7 +383,7 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje
1. Let |o| be ? [=Get=](|importObject|, |moduleName|).
1. If [=Type=](|o|) is not Object, throw a {{TypeError}} exception.
1. Let |v| be ? [=Get=](|o|, |componentName|).
- 1. If |externtype| is of the form [=func=] |functype|,
+ 1. If |externtype| is of the form [=external-type/func=] |functype|,
1. If [=IsCallable=](|v|) is false, throw a {{LinkError}} exception.
1. If |v| has a \[[FunctionAddress]] internal slot, and therefore is an [=Exported Function=],
1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot.
@@ -407,7 +432,7 @@ The verification of WebAssembly type requirements is deferred to the
1. [=list/iterate|For each=] (|name|, |externtype|) of [=module_exports=](|module|),
1. Let |externval| be [=instance_export=](|instance|, |name|).
1. Assert: |externval| is not [=error=].
- 1. If |externtype| is of the form [=func=] functype,
+ 1. If |externtype| is of the form [=external-type/func=] functype,
1. Assert: |externval| is of the form [=external value|func=] |funcaddr|.
1. Let [=external value|func=] |funcaddr| be |externval|.
1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|.
@@ -544,7 +569,7 @@ interface Module {
The string value of the extern type |type| is
- * "function" if |type| is of the form [=func=] functype
+ * "function" if |type| is of the form [=external-type/func=] functype
* "table" if |type| is of the form [=table=] tabletype
* "memory" if |type| is of the form [=mem=] memtype
* "global" if |type| is of the form [=global=] globaltype
@@ -1090,6 +1115,8 @@ The algorithm ToJSValue(|w|) coerces a [=WebAssembly value=] to a Jav
1. If |w| is of the form [=ref.null=] t, return null.
1. If |w| is of the form [=ref.func=] |funcaddr|, return the result of creating [=a new Exported Function=] from |funcaddr|.
1. If |w| is of the form [=ref.extern=] |externaddr|, return the result of [=retrieving an extern value=] from |externaddr|.
+1. If |w| is of the form [=ref.array=] arrayaddr, [=ref.struct=] structaddr, [=ref.i31=] i31addr, or [=ref.host=] hostaddr,
+ 1. Return the result of [=extern_externalize=](|w|).
Note: Number values which are equal to NaN may have various observable NaN payloads; see [=NumberToRawBytes=] for details.
@@ -1120,26 +1147,142 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript va
1. If |type| is [=f64=],
1. Let |f64| be ? [=ToNumber=](|v|).
1. Return [=f64.const=] |f64|.
-1. If |type| is [=funcref=],
- 1. If |v| is null,
- 1. Return [=ref.null=] [=funcref=].
- 1. If |v| is an [=Exported Function=],
- 1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot.
- 1. Return [=ref.func=] |funcaddr|.
- 1. Throw a {{TypeError}}.
-1. If |type| is [=externref=],
+1. If |type| is of the form [=ref=] |null| |heaptype|,
1. If |v| is null,
- 1. Return [=ref.null=] [=externref=].
- 1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=].
- 1. If a [=extern address=] |externaddr| exists such that |map|[|externaddr|] is the same as |v|,
+ 1. If |null| is present,
+ 1. Return [=ref.null=] |heaptype|.
+ 1. Otherwise,
+ 1. Throw a {{TypeError}}.
+ 1. If |type| is a subtype of [=ref=] |null| [=heap-type/func=],
+ 1. If |v| is an [=Exported Function=],
+ 1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot.
+ 1. Let |testresult| be [=ref_test=](|heaptype|, [=ref.func=] |funcaddr|).
+ 1. If |testresult| is true,
+ 1. Return [=ref.func=] |funcaddr|.
+ 1. Throw a {{TypeError}}.
+ 1. If |heaptype| is [=extern=],
+ 1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=].
+ 1. If a [=extern address=] |externaddr| exists such that |map|[|externaddr|] is the same as |v|,
+ 1. Return [=ref.extern=] |externaddr|.
+ 1. Let [=extern address=] |externaddr| be the smallest address such that |map|[|externaddr|] [=map/exists=] is false.
+ 1. [=map/Set=] |map|[|externaddr|] to |v|.
1. Return [=ref.extern=] |externaddr|.
- 1. Let [=extern address=] |externaddr| be the smallest address such that |map|[|externaddr|] [=map/exists=] is false.
- 1. [=map/Set=] |map|[|externaddr|] to |v|.
- 1. Return [=ref.extern=] |externaddr|.
+ 1. If |type| is a subtype of [=ref=] |null| [=any=],
+ 1. Let |externref| be [=ToWebAssemblyValue=](|v|, [=ref=] [=extern=]).
+ 1. Let |internref| be [=extern_internalize=](|externref|).
+ 1. Let |testresult| be [=ref_test=](|heaptype|, |internref|).
+ 1. If |testresult| is true,
+ 1. Return |internref|.
+ 1. Throw a {{TypeError}}.
1. Assert: This step is not reached.
+Garbage Collected Objects
+
+A WebAssembly struct or array is made available in JavaScript as an Exported GC Object.
+An [=Exported GC Object=] is an exotic object that wraps a garbage collected WebAssembly reference value.
+Most JavaScript operations on an [=Exported GC Object=] will throw an exception or return undefined.
+
+Note: These operations may be refined in the future to allow richer interactions in JavaScript with WebAssembly structs and arrays.
+
+An [=Exported GC Object=] contains an \[[ObjectAddress]] internal slot, which holds a [=object address=] relative to the [=surrounding agent=]'s [=associated store=],
+and an \[[ObjectKind]] internal slot, which holds the string value "struct" or "array".
+
+The internal methods of an [=Exported GC Object=] use the following implementations.
+
+
+ The \[[GetPrototypeOf]] internal method of an Exported GC Object O takes no arguments and returns null. It performs the following steps when called:
+
+ 1. Return null.
+
+
+
+ The \[[SetPrototypeOf]] internal method of an Exported GC Object O takes argument V (an Object or null) and returns a boolean. It performs the following steps when called:
+
+ 1. Return false.
+
+
+
+ The \[[IsExtensible]] internal method of an Exported GC Object O takes no arguments and returns a boolean. It performs the following steps when called:
+
+ 1. Return false.
+
+
+
+ The \[[PreventExtensions]] internal method of an Exported GC Object O takes no arguments and returns a boolean. It performs the following steps when called:
+
+ 1. Return false.
+
+
+
+ The \[[GetOwnProperty]] internal method of an Exported GC Object O takes argument P (a property key) and returns undefined. It performs the following steps when called:
+
+ 1. Return undefined.
+
+
+
+ The \[[DefineOwnProperty]] internal method of an Exported GC Object O takes arguments P (a property key) and Desc (a property descriptor) and returns a boolean. It performs the following steps when called:
+
+ 1. Return false.
+
+
+
+ The \[[HasProperty]] internal method of an Exported GC Object O takes argument P (a property key) and returns a boolean. It performs the following steps when called:
+
+ 1. Return false.
+
+
+
+ The \[[Get]] internal method of an Exported GC Object O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns undefined. It performs the following steps when called:
+
+ 1. Return undefined.
+
+
+
+ The \[[Set]] internal method of an Exported GC Object O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and throws an exception. It performs the following steps when called:
+
+ 1. Throw a {{TypeError}}.
+
+
+
+ The \[[Delete]] internal method of an Exported GC Object O takes argument P (a property key) and throws an exception. It performs the following steps when called:
+
+ 1. Throw a {{TypeError}}.
+
+
+
+ The \[[OwnPropertyKeys]] internal method of an Exported GC Object O takes no arguments and returns a list. It performs the following steps when called:
+
+ 1. Let keys be a new empty list.
+ 1. Return keys.
+
+
+
+ To create a new Exported GC Object from a WebAssembly [=object address=] |objectaddr| and a string |objectkind|, perform the following steps:
+
+ 1. Assert: |objectkind| is either "array" or "struct".
+ 1. Let |map| be the [=surrounding agent=]'s associated [=exported GC object cache=].
+ 1. If |map|[|objectaddr|] [=map/exists=],
+ 1. Return |map|[|objectaddr|].
+ 1. Let |object| be [=MakeBasicObject=](« \[[ObjectAddress]] »).
+ 1. Set |object|.\[[ObjectAddress]] to |objectaddr|.
+ 1. Set |object|.\[[ObjectKind]] to |objectkind|.
+ 1. Set |object|.\[[GetPrototypeOf]] as specified in [=[[GetPrototypeOf]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[SetPrototypeOf]] as specified in [=[[SetPrototypeOf]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[IsExtensible]] as specified in [=[[IsExtensible]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[PreventExtensions]] as specified in [=[[PreventExtensions]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[GetOwnProperty]] as specified in [=[[GetOwnProperty]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[DefineOwnProperty]] as specified in [=[[DefineOwnProperty]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[HasProperty]] as specified in [=[[HasProperty]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[Get]] as specified in [=[[Get]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[Set]] as specified in [=[[Set]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[Delete]] as specified in [=[[Delete]] internal method of an Exported GC Object=].
+ 1. Set |object|.\[[OwnPropertyKeys]] as specified in [=[[OwnPropertyKeys]] internal method of an Exported GC Object=].
+ 1. [=map/Set=] |map|[|objectaddr|] to |object|.
+ 1. Return |object|.
+
+
Error Objects
WebAssembly defines the following Error classes: CompileError, LinkError, and RuntimeError.
@@ -1202,6 +1345,49 @@ Note: ECMAScript doesn't specify any sort of behavior on out-of-memory condition
See [Issue 879](https://github.com/WebAssembly/spec/issues/879) for further discussion.
+Requirements on External Conversion Operations in WebAssembly
+
+The WebAssembly core specification defines the [=extern.externalize=] and [=extern.internalize=] instructions
+(exposed as [=embedder/extern_externalize=] and [=embedder/extern_internalize=] in the embedding API)
+for the purpose of converting internal WebAssembly references to or from an external host representation.
+The behavior of these operations is partially host-defined.
+
+A JavaScript host implementation must implement [=embedder/extern_internalize=] and [=embedder/extern_externalize=] as follows:
+
+
+The extern_internalize(|externref|) operation takes one argument |externref| and performs the following steps:
+
+1. Let [=ref.extern=] |externaddr| be |externref|.
+1. Let |v| be the result of [=retrieving an extern value=] from |externaddr|.
+1. If |v| [=is a Number=],
+ 1. Let |i32| be ? [=ToInt32=](|v|).
+ 1. If |v| is equal to |i32| and [=ℝ=](|v|) < 230 and [=ℝ=](|v|) ⩾ -230,
+ 1. Return [=i31_new=]([=i32.const=] |v|).
+1. If |v| is an [=Exported GC Object=],
+ 1. Let |objectaddr| be the value of |v|'s \[[ObjectAddress]] internal slot.
+ 1. Let |objecttype| be the value of |v|'s \[[ObjectType]] internal slot.
+ 1. If |objecttype| is "array",
+ 1. Return [=ref.array=] |objectaddr|.
+ 1. If |objecttype| is "struct",
+ 1. Return [=ref.struct=] |objectaddr|.
+1. Otherwise,
+ 1. Return [=ref.host=] |externaddr|.
+
+
+
+
+The extern_externalize(|internref|) operation takes one argument |internref| and performs the following steps:
+
+1. If |internref| is of the form [=ref.i31=] |i31addr|,
+ 1. Let |i32| be [=i31_get=](|i31addr|).
+ 1. Return [=the Number value=] for |i32|.
+1. If |internref| is of the form [=ref.struct=] |structaddr|, return the result of creating [=a new Exported GC Object=] from |structaddr| and "struct".
+1. If |internref| is of the form [=ref.array=] |arrayaddr|, return the result of creating [=a new Exported GC Object=] from |arrayaddr| and "array".
+1. If |internref| is of the form [=ref.host=] |externaddr|, return the result of [=retrieving an extern value=] from |externaddr|.
+1. Assert: This step is not reached.
+
+
+
Implementation-defined Limits
The WebAssembly core specification allows an implementation to define limits on the syntactic structure of the module.