Skip to content

Commit 5fa0fbf

Browse files
committed
Clarify structured clone behavior for WebAssembly objects.
1 parent d1bd4a4 commit 5fa0fbf

File tree

2 files changed

+110
-29
lines changed

2 files changed

+110
-29
lines changed

JS.md

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ with the resulting `WebAssembly.Instance` object. On failure, the `Promise` is
164164
A `WebAssembly.Module` object represents the stateless result of compiling a
165165
WebAssembly binary-format module and contains one internal slot:
166166

167-
* [[Module]] : an [`Ast.module`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L176)
167+
* [[WebAssembly.Module]] : an [`Ast.module`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L176)
168168
which is the spec definition of a module
169169

170170
### `WebAssembly.Module` Constructor
@@ -190,7 +190,7 @@ Otherwise, this function performs synchronous compilation of the `BufferSource`:
190190
according to the rules in [spec/valid.ml](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/valid.ml#L415).
191191
1. The spec `string` values inside `Ast.module` are decoded as UTF8 as described in
192192
[Web.md](Web.md#names).
193-
1. On success, a new `WebAssembly.Module` object is returned with [[Module]] set to
193+
1. On success, a new `WebAssembly.Module` object is returned with [[WebAssembly.Module]] set to
194194
the validated `Ast.module`.
195195
1. On failure, a new `WebAssembly.CompileError` is thrown.
196196

@@ -214,7 +214,7 @@ is thrown.
214214

215215
This function returns a new `Array` every time it is called. Each such `Array` is produced by mapping each
216216
[`Ast.export`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L152)
217-
`e` of [moduleObject.[[Module]].exports](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L187)
217+
`e` of [moduleObject.[[WebAssemby.Module]].exports](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L187)
218218
to the Object `{ name: String(e.name), kind: e.ekind }` where `e.name` is [decoded as UTF8](Web.md#names)
219219
and `e.ekind` is mapped to one of the String values `"function"`, `"table"`, `"memory"`, `"global"`.
220220

@@ -235,7 +235,7 @@ is thrown.
235235

236236
This function returns a new `Array` every time it is called. Each such `Array` is produced by mapping each
237237
[`Ast.import`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L167)
238-
`i` of [moduleObject.[[Module]].imports](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L203)
238+
`i` of [moduleObject.[[WebAssembly.Module]].imports](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L203)
239239
to the Object `{ module: String(i.module_name), name: String(i.item_name), kind: i.ikind }` where
240240
`i.module_name` and `i.item_name` are [decoded as UTF8](Web.md#names) and
241241
`i.ikind` is mapped to one of the String values `"function"`, `"table"`, `"memory"`, `"global"`.
@@ -265,22 +265,6 @@ This function returns a new `Array` every time it is called. Each such `Array` i
265265

266266
The `Array` is populated in the same order custom sections appear in the WebAssembly binary.
267267

268-
### Structured Clone of a `WebAssembly.Module`
269-
270-
A `WebAssembly.Module` is a
271-
[cloneable object](https://html.spec.whatwg.org/multipage/infrastructure.html#cloneable-objects)
272-
which means it can be cloned between windows/workers and also
273-
stored/retrieved into/from an [IDBObjectStore](https://w3c.github.io/IndexedDB/#object-store).
274-
The semantics of a structured clone is as-if the binary source, from which the
275-
`WebAssembly.Module` was compiled, were cloned and recompiled into the target realm.
276-
Engines should attempt to share/reuse internal compiled code when performing
277-
a structured clone although, in corner cases like CPU upgrade or browser
278-
update, this may not be possible and full recompilation may be necessary.
279-
280-
Given the above engine optimizations, structured cloning provides developers
281-
explicit control over both compiled-code caching and cross-window/worker code
282-
sharing.
283-
284268
## `WebAssembly.Instance` Objects
285269

286270
A `WebAssembly.Instance` object represents the instantiation of a
@@ -308,7 +292,7 @@ If `moduleObject` is not a `WebAssembly.Module`, a [`TypeError`](https://tc39.gi
308292
is thrown.
309293

310294
Let `module` be the [`Ast.module`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L176)
311-
`moduleObject.[[Module]]`.
295+
`moduleObject.[[WebAssembly.Module]]`.
312296

313297
If the `importObject` parameter is not `undefined` and `Type(importObject)` is
314298
not Object, a [`TypeError`](https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror)
@@ -366,7 +350,7 @@ For each [`import`](https://github.com/WebAssembly/spec/blob/master/interpreter/
366350
[`memory_type`](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#memory_type)
367351
by `Eval.init` below.)
368352
1. Append `v` to `memories`.
369-
1. Append `v.[[Memory]]` to `imports`.
353+
1. Append `v.[[WebAssembly.Memory]]` to `imports`.
370354
1. Otherwise (`i` is a table import):
371355
1. If `v` is not a [`WebAssembly.Table` object](#webassemblytable-objects),
372356
throw a `WebAssembly.LinkError`.
@@ -441,7 +425,7 @@ each [external](https://github.com/WebAssembly/spec/blob/master/interpreter/spec
441425
1. If `v` is an `i64`, throw a `WebAssembly.LinkError`.
442426
1. Return [`ToJSValue`](#tojsvalue)`(v)`.
443427
1. If `e` is a [memory](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/instance.ml#L14) `m`:
444-
1. If there is an element `memory` in `memories` whose `memory.[[Memory]]` is `m`, then return `memory`.
428+
1. If there is an element `memory` in `memories` whose `memory.[[WebAssembly.Memory]]` is `m`, then return `memory`.
445429
1. (Note: At most one `WebAssembly.Memory` object is created for any memory, so the above `memory` is unique, even if there are multiple occurrances in the list. Moreover, if the item was an import, the original object will be found.)
446430
1. Otherwise:
447431
1. Let `memory` be a new `WebAssembly.Memory` object created via [`CreateMemoryObject`](#creatememoryobject) from `m`.
@@ -532,9 +516,9 @@ A `WebAssembly.Memory` object contains a single [linear memory](Semantics.md#lin
532516
which can be simultaneously referenced by multiple `Instance` objects. Each
533517
`Memory` object has two internal slots:
534518

535-
* [[Memory]] : a [`Memory.memory`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/memory.mli)
536-
* [[BufferObject]] : the current `ArrayBuffer` whose [[ArrayBufferByteLength]]
537-
matches the current byte length of [[Memory]]
519+
* [[WebAssembly.Memory]] : a [`Memory.memory`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/memory.mli)
520+
* [[BufferObject]] : the current `ArrayBuffer` or `SharedArrayBuffer` whose [[ArrayBufferByteLength]]
521+
matches the current byte length of [[WebAssembly.Memory]]
538522

539523
### `WebAssembly.Memory` Constructor
540524

@@ -579,7 +563,7 @@ Any attempts to [`detach`](http://tc39.github.io/ecma262/#sec-detacharraybuffer)
579563
the detachment performed by [`m.grow`](#webassemblymemoryprototypegrow) shall throw a
580564
[`TypeError`](https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror)
581565

582-
Return a new `WebAssembly.Memory` instance with [[Memory]] set to `m` and
566+
Return a new `WebAssembly.Memory` instance with [[WebAssembly.Memory]] set to `m` and
583567
[[BufferObject]] set to `buffer`.
584568

585569
### `WebAssembly.Memory.prototype [ @@toStringTag ]` Property
@@ -614,9 +598,9 @@ Perform [`DetachArrayBuffer`](http://tc39.github.io/ecma262/#sec-detacharraybuff
614598

615599
Assign to `M.[[BufferObject]]` a new `ArrayBuffer` whose
616600
[[[ArrayBufferData]]](http://tc39.github.io/ecma262/#sec-properties-of-the-arraybuffer-prototype-object)
617-
aliases `M.[[Memory]]` and whose
601+
aliases `M.[[WebAssembly.Memory]]` and whose
618602
[[[ArrayBufferByteLength]]](http://tc39.github.io/ecma262/#sec-properties-of-the-arraybuffer-prototype-object)
619-
is set to the new byte length of `M.[[Memory]]`.
603+
is set to the new byte length of `M.[[WebAssembly.Memory]]`.
620604

621605
Return `ret` as a Number value.
622606

Web.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,103 @@ MIME type mismatch or `opaque` response types
124124
[reject](http://tc39.github.io/ecma262/#sec-rejectpromise) the Promise with a
125125
`WebAssembly.CompileError`.
126126

127+
### Structured serialization of a `WebAssembly.Memory`
128+
129+
A `WebAssembly.Memory` is a
130+
[serializable object](https://html.spec.whatwg.org/multipage/infrastructure.html#serializable-objects), and will require changes to the
131+
[HTML Standard](https://html.spec.whatwg.org/multipage/infrastructure.html#serialization-steps) as follows:
132+
133+
[StructuredSerializeInternal](https://html.spec.whatwg.org/multipage/infrastructure.html#structuredserializeinternal) adds a new step after step 12:
134+
135+
* Otherwise, if *value* has a [[WebAssembly.Memory]] internal slot, then:
136+
1. Let *size* be the number value.[[BufferObject]].[[ArrayBufferByteLength]].
137+
2. If ! [IsSharedArrayBuffer](https://tc39.github.io/ecma262/#sec-issharedarraybuffer)(*value*.[[BufferObject]]) is true, then:
138+
1. If *forStorage* is true, then throw a
139+
"`[DataCloneError](https://heycam.github.io/webidl/#datacloneerror)`"
140+
`[DOMException](https://heycam.github.io/webidl/#dfn-DOMException)`.
141+
2. Otherwise:
142+
1. Set *serialized* to { [[Type]]: "WebAssembly.Memory",
143+
[[ArrayBufferData]]: value.[[BufferObject]].[[ArrayBufferData]],
144+
[[ArrayBufferByteLength]]: size,
145+
[[AgentCluster]]: the [current Realm Record](https://tc39.github.io/ecma262/#current-realm)'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) }.
146+
2. Otherwise:
147+
1. Let *dataCopy* be [CreateByteDataBlock](https://tc39.github.io/ecma262/#sec-createbytedatablock)(size).
148+
NOTE: This can throw a RangeError exception on allocation failure.
149+
2. Perform [CopyDataBlockBytes](https://tc39.github.io/ecma262/#sec-copydatablockbytes)
150+
(dataCopy, 0,
151+
value.[[BufferObject]].[[ArrayBufferData]], 0, size).
152+
3. Set *serialized* to { [[Type]]: "WebAssembly.Memory",
153+
[[ArrayBufferData]]: dataCopy, [[ArrayBufferByteLength]]: size }.
154+
155+
[StructuredDeserialize](https://html.spec.whatwg.org/multipage/infrastructure.html#structureddeserialize) adds a new step after step 12:
156+
157+
* Otherwise, if *serialized*.[[Type]] is "WebAssembly.Memory", then:
158+
1. If *targetRealm*'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) is not
159+
*serialized*.[[AgentCluster]], then throw a
160+
"`[DataCloneError](https://heycam.github.io/webidl/#datacloneerror)`"
161+
`[DOMException](https://heycam.github.io/webidl/#dfn-DOMException)`.
162+
2. Otherwise,
163+
if ! [IsSharedArrayBuffer](https://tc39.github.io/ecma262/#sec-issharedarraybuffer)(*serialized*.[[ArrayBufferData]]) is true, then:
164+
Set *value* to a new WebAssembly.Memory object in *targetRealm*
165+
whose [[BufferObject]] internal slot is set to a new
166+
[[ArrayBufferData]] internal slot value is
167+
set to a new `SharedArrayBuffer`, where:
168+
1. The `SharedArrayBuffer`'s internal slot [[ArrayBufferData]]
169+
if set to *serialized*.[[BufferObject]].[[ArrayBufferData]].
170+
2. The `SharedArrayBuffer`'s internal slot [[ArrayBufferByteLength]]
171+
is set to *serialized*.[[BufferObject]].[[ArrayBufferByteLength]].
172+
3. Otherwise,
173+
Set *value* to a new WebAssembly.Memory object in *targetRealm*
174+
whose [[BufferObject]] internal slot is set to a new
175+
[[ArrayBufferData]] internal slot value is
176+
set to a new `ArrayBuffer` *mem*, where:
177+
1. *mem*'s internal slot [[ArrayBufferData]]
178+
is set to *serialized*.[[BufferObject]].[[ArrayBufferData]].
179+
2. *mem*'s internal slot [[ArrayBufferByteLength]]
180+
is set to *serialized*.[[BufferObject]].[[ArrayBufferByteLength]].
181+
182+
183+
### Structured serialization of a `WebAssembly.Module`
184+
185+
A `WebAssembly.Module` is a
186+
[serializable object](https://html.spec.whatwg.org/multipage/infrastructure.html#serializable-objects), and will require changes to the
187+
[HTML Standard](https://html.spec.whatwg.org/multipage/infrastructure.html#serialization-steps) as follows:
188+
189+
[StructuredSerializeInternal](https://html.spec.whatwg.org/multipage/infrastructure.html#structuredserializeinternal) adds a new step after step 12:
190+
191+
* Otherwise, if *value* has a [[WebAssembly.Module]] internal slot, then:
192+
1. If *forStorage* is true and the relevant settings
193+
object of *value* is not "Secure" per the
194+
["Is the environment settings object a secure context?"](https://w3c.github.io/webappsec-secure-contexts/#settings-object)
195+
algorithm, throw a
196+
"`[DataCloneError](https://heycam.github.io/webidl/#datacloneerror)`"
197+
`[DOMException](https://heycam.github.io/webidl/#dfn-DOMException)`.
198+
2. Otherwise:
199+
Set *serialized* to { [[Type]]: "WebAssembly.Module",
200+
[[Module]]: value.[[Module]],
201+
[[AgentCluster]]: the [current Realm Record](https://tc39.github.io/ecma262/#current-realm)'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) }.
202+
203+
[StructuredDeserialize](https://html.spec.whatwg.org/multipage/infrastructure.html#structureddeserialize) adds a new step after step 12:
204+
205+
* Otherwise, if *serialized*.[[Type]] is "WebAssembly.Module", then:
206+
1. If *targetRealm*'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) is not
207+
*serialized*.[[AgentCluster]], then throw a
208+
"`[DataCloneError](https://heycam.github.io/webidl/#datacloneerror)`"
209+
`[DOMException](https://heycam.github.io/webidl/#dfn-DOMException)`.
210+
2. Otherwise, set *value* to a new WebAssembly.Module object in *targetRealm*
211+
whose [[Module]] internal slot value is *serialized*.[[Module]].
212+
213+
The semantics of a structured serialization is as-if the binary source, from which the
214+
`WebAssembly.Module` was compiled, is serialized, then deserialized, and recompiled into the target realm.
215+
Engines should attempt to share/reuse internal compiled code when performing
216+
a structured seraialization, although in corner cases like CPU upgrade or browser
217+
update, this may not be possible and full recompilation may be necessary.
218+
219+
Given the above engine optimizations, structured serialization provides developers
220+
explicit control over both compiled-code caching and cross-window/worker code
221+
sharing.
222+
223+
127224
## Developer-facing display conventions
128225

129226
Browsers, JavaScript engines, and offline tools have common ways of referring to

0 commit comments

Comments
 (0)