Skip to content

Commit 10e0424

Browse files
committed
Clarify structured clone behavior for WebAssembly objects.
1 parent 29948ec commit 10e0424

File tree

2 files changed

+101
-31
lines changed

2 files changed

+101
-31
lines changed

JS.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ with the resulting `WebAssembly.Instance` object. On failure, the `Promise` is
169169
A `WebAssembly.Module` object represents the stateless result of compiling a
170170
WebAssembly binary-format module and contains one internal slot:
171171

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

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

@@ -219,7 +219,7 @@ is thrown.
219219

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

@@ -240,7 +240,7 @@ is thrown.
240240

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

271271
The `Array` is populated in the same order custom sections appear in the WebAssembly binary.
272272

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

291275
A `WebAssembly.Instance` object represents the instantiation of a
@@ -313,7 +297,7 @@ If `moduleObject` is not a `WebAssembly.Module`, a [`TypeError`](https://tc39.gi
313297
is thrown.
314298

315299
Let `module` be the [`Ast.module`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/ast.ml#L176)
316-
`moduleObject.[[Module]]`.
300+
`moduleObject.[[WebAssembly.Module]]`.
317301

318302
If the `importObject` parameter is not `undefined` and `Type(importObject)` is
319303
not Object, a [`TypeError`](https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror)
@@ -371,7 +355,7 @@ For each [`import`](https://github.com/WebAssembly/spec/blob/master/interpreter/
371355
[`memory_type`](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#memory_type)
372356
by `Eval.init` below.)
373357
1. Append `v` to `memories`.
374-
1. Append `v.[[Memory]]` to `imports`.
358+
1. Append `v.[[WebAssembly.Memory]]` to `imports`.
375359
1. Otherwise (`i` is a table import):
376360
1. If `v` is not a [`WebAssembly.Table` object](#webassemblytable-objects),
377361
throw a `WebAssembly.LinkError`.
@@ -446,7 +430,7 @@ each [external](https://github.com/WebAssembly/spec/blob/master/interpreter/spec
446430
1. If `v` is an `i64`, throw a `WebAssembly.LinkError`.
447431
1. Return [`ToJSValue`](#tojsvalue)`(v)`.
448432
1. If `e` is a [memory](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/instance.ml#L14) `m`:
449-
1. If there is an element `memory` in `memories` whose `memory.[[Memory]]` is `m`, then return `memory`.
433+
1. If there is an element `memory` in `memories` whose `memory.[[WebAssembly.Memory]]` is `m`, then return `memory`.
450434
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.)
451435
1. Otherwise:
452436
1. Let `memory` be a new `WebAssembly.Memory` object created via [`CreateMemoryObject`](#creatememoryobject) from `m`.
@@ -537,9 +521,9 @@ A `WebAssembly.Memory` object contains a single [linear memory](Semantics.md#lin
537521
which can be simultaneously referenced by multiple `Instance` objects. Each
538522
`Memory` object has two internal slots:
539523

540-
* [[Memory]] : a [`Memory.memory`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/memory.mli)
541-
* [[BufferObject]] : the current `ArrayBuffer` whose [[ArrayBufferByteLength]]
542-
matches the current byte length of [[Memory]]
524+
* [[WebAssembly.Memory]] : a [`Memory.memory`](https://webassembly.github.io/spec/exec/runtime.html#memory-instances)
525+
* [[BufferObject]] : the current `ArrayBuffer` or `SharedArrayBuffer` whose [[ArrayBufferByteLength]]
526+
matches the current byte length of [[WebAssembly.Memory]]
543527

544528
### `WebAssembly.Memory` Constructor
545529

@@ -571,7 +555,7 @@ Return the result of [`CreateMemoryObject`](#creatememoryobject)(`memory`).
571555

572556
### CreateMemoryObject
573557

574-
Given a [`Memory.memory`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/memory.mli#L1)
558+
Given a [`Memory.memory`](https://webassembly.github.io/spec/exec/runtime.html#memory-instances)
575559
`m`, to create a `WebAssembly.Memory`:
576560

577561
Let `buffer` be a new `ArrayBuffer` whose
@@ -584,7 +568,7 @@ Any attempts to [`detach`](http://tc39.github.io/ecma262/#sec-detacharraybuffer)
584568
the detachment performed by [`m.grow`](#webassemblymemoryprototypegrow) shall throw a
585569
[`TypeError`](https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror)
586570

587-
Return a new `WebAssembly.Memory` instance with [[Memory]] set to `m` and
571+
Return a new `WebAssembly.Memory` instance with [[WebAssembly.Memory]] set to `m` and
588572
[[BufferObject]] set to `buffer`.
589573

590574
### `WebAssembly.Memory.prototype [ @@toStringTag ]` Property
@@ -619,9 +603,9 @@ Perform [`DetachArrayBuffer`](http://tc39.github.io/ecma262/#sec-detacharraybuff
619603

620604
Assign to `M.[[BufferObject]]` a new `ArrayBuffer` whose
621605
[[[ArrayBufferData]]](http://tc39.github.io/ecma262/#sec-properties-of-the-arraybuffer-prototype-object)
622-
aliases `M.[[Memory]]` and whose
606+
aliases `M.[[WebAssembly.Memory]]` and whose
623607
[[[ArrayBufferByteLength]]](http://tc39.github.io/ecma262/#sec-properties-of-the-arraybuffer-prototype-object)
624-
is set to the new byte length of `M.[[Memory]]`.
608+
is set to the new byte length of `M.[[WebAssembly.Memory]]`.
625609

626610
Return `ret` as a Number value.
627611

@@ -639,7 +623,7 @@ A `WebAssembly.Table` object contains a single [table](Semantics.md#table)
639623
which can be simultaneously referenced by multiple `Instance` objects. Each
640624
`Table` object has two internal slots:
641625

642-
* [[Table]] : a [`Table.table`](https://github.com/WebAssembly/spec/blob/master/interpreter/spec/table.mli#L1)
626+
* [[Table]] : a [`Table.table`](https://webassembly.github.io/spec/exec/runtime.html#table-instances)
643627
* [[Values]] : an array whose elements are either `null` or [Exported Function Exotic Object](#exported-function-exotic-objects)
644628

645629
### `WebAssembly.Table` Constructor

Web.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,92 @@ Given these values, to process a potential WebAssembly response:
202202
_reason_.
203203
1. Return _returnValue_.
204204

205+
### Structured serialization of a `WebAssembly.Memory`
206+
207+
A `WebAssembly.Memory` is a
208+
[serializable object](https://html.spec.whatwg.org/multipage/infrastructure.html#serializable-objects), and will require changes to the
209+
[HTML Standard](https://html.spec.whatwg.org/multipage/infrastructure.html#serialization-steps) as follows:
210+
211+
[StructuredSerializeInternal](https://html.spec.whatwg.org/multipage/infrastructure.html#structuredserializeinternal) adds a new step after step 12:
212+
213+
* Otherwise, if *value* has a [[WebAssembly.Memory]] internal slot, then:
214+
1. Let *size* be *value*.[[BufferObject]].[[ArrayBufferByteLength]].
215+
2. Let *maximum* be the value of *value*.[[WebAssembly.Memory]]'s `max` field (which is an optional u32).
216+
3. If *value*.[[BufferObject]] is a Shared Data Block, then:
217+
1. If *forStorage* is true, then throw a
218+
"[`DataCloneError`](https://heycam.github.io/webidl/#datacloneerror)"
219+
[`DOMException`](https://heycam.github.io/webidl/#dfn-DOMException).
220+
2. Otherwise,
221+
set *serialized* to { [[Type]]: "WebAssembly.Memory",
222+
[[ArrayBufferData]]: *value*.[[BufferObject]].[[ArrayBufferData]],
223+
[[ArrayBufferByteLength]]: *size*,
224+
[[MemoryMaximum]]: *maximum*,
225+
[[AgentCluster]]: the [current Realm Record](https://tc39.github.io/ecma262/#current-realm)'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) }.
226+
4. Otherwise throw a
227+
"[`DataCloneError`](https://heycam.github.io/webidl/#datacloneerror)"
228+
[`DOMException`](https://heycam.github.io/webidl/#dfn-DOMException).
229+
230+
[StructuredDeserialize](https://html.spec.whatwg.org/multipage/infrastructure.html#structureddeserialize) adds a new step after step 12:
231+
232+
* Otherwise, if *serialized*.[[Type]] is "WebAssembly.Memory", then:
233+
1. Assert [IsSharedArrayBuffer](https://tc39.github.io/ecma262/#sec-issharedarraybuffer)(*serialized*.[[ArrayBufferData]]) is true.
234+
2. If *targetRealm*'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) is not
235+
*serialized*.[[AgentCluster]], then throw a
236+
"[`DataCloneError`](https://heycam.github.io/webidl/#datacloneerror)"
237+
[`DOMException`](https://heycam.github.io/webidl/#dfn-DOMException).
238+
3. Set *value* to a new WebAssembly.Memory object in *targetRealm*, where:
239+
1. *value*'s internal slot [[WebAssembly.Memory]] is set to a new `Memory.memory` *mem*, where:
240+
1. *mem*'s linear memory is set to *serialized*.[[BufferObject]].[[ArrayBufferData]].
241+
2. *mem*'s linear memory has a byte length of *serialized*.[[BufferObject]].[[ArrayBufferByteLength]].
242+
3. *mem*'s `max` size is set tof *serialized*.[[MemoryMaximum]].
243+
2. *value*'s internal slot [[BufferObject]] is set to a new `SharedArrayBuffer` *buf*, where:
244+
1. *buf*'s internal slot [[ArrayBufferData]]
245+
aliases *mem*'s linear memory.
246+
2. *buf*'s internal slot [[ArrayBufferByteLength]]
247+
is set to the byte length of *mem*'s linear memory.
248+
249+
250+
### Structured serialization of a `WebAssembly.Module`
251+
252+
A `WebAssembly.Module` is a
253+
[serializable object](https://html.spec.whatwg.org/multipage/infrastructure.html#serializable-objects), and will require changes to the
254+
[HTML Standard](https://html.spec.whatwg.org/multipage/infrastructure.html#serialization-steps) as follows:
255+
256+
[StructuredSerializeInternal](https://html.spec.whatwg.org/multipage/infrastructure.html#structuredserializeinternal) adds a new step after step 12:
257+
258+
* Otherwise, if *value* has a [[WebAssembly.Module]] internal slot, then:
259+
1. If *forStorage* is true and the relevant settings
260+
object of *value* is not "Secure" per the
261+
["Is the environment settings object a secure context?"](https://w3c.github.io/webappsec-secure-contexts/#settings-object)
262+
algorithm, throw a
263+
"[`DataCloneError`](https://heycam.github.io/webidl/#datacloneerror)"
264+
[`DOMException`](https://heycam.github.io/webidl/#dfn-DOMException).
265+
2. Otherwise,
266+
set *serialized* to { [[Type]]: "WebAssembly.Module",
267+
[[WebAssembly.Module]]: *value*.[[WebAssembly.Module]],
268+
[[AgentCluster]]: the [current Realm Record](https://tc39.github.io/ecma262/#current-realm)'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) }.
269+
270+
[StructuredDeserialize](https://html.spec.whatwg.org/multipage/infrastructure.html#structureddeserialize) adds a new step after step 12:
271+
272+
* Otherwise, if *serialized*.[[Type]] is "WebAssembly.Module", then:
273+
1. If *targetRealm*'s corresponding [agent cluster](https://tc39.github.io/ecma262/#sec-agent-clusters) is not
274+
*serialized*.[[AgentCluster]], then throw a
275+
"[`DataCloneError`](https://heycam.github.io/webidl/#datacloneerror)"
276+
[`DOMException`](https://heycam.github.io/webidl/#dfn-DOMException).
277+
2. Otherwise, set *value* to a new WebAssembly.Module object in *targetRealm*
278+
whose [[WebAssembly.Module]] internal slot *value* is *serialized*.[[WebAssembly.Module]].
279+
280+
The semantics of a structured serialization is as-if the binary source, from which the
281+
`WebAssembly.Module` was compiled, is serialized, then deserialized, and recompiled into the target realm.
282+
Engines should attempt to share/reuse internal compiled code when performing
283+
a structured serialization, although in corner cases like CPU upgrade or browser
284+
update, this may not be possible and full recompilation may be necessary.
285+
286+
Given the above engine optimizations, structured serialization provides developers
287+
explicit control over both compiled-code caching and cross-window/worker code
288+
sharing.
289+
290+
205291
## Developer-facing display conventions
206292

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

0 commit comments

Comments
 (0)