Skip to content

Commit 4b0f677

Browse files
authored
Add alternate proposal for segment init. (#79)
This solution introduces new instructions to initialize segments programmatically, but only in the start function.
1 parent 5d2ad6e commit 4b0f677

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

proposals/threads/ConditionalSegmentInitialization.md

+77
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,80 @@ elem ::= 0x01 e_o:expr e_a:expr y*:vec(funcindex) => {table 0, offset e_o, ap
175175
As with data segments, the `apply` initializer expression is evaluated during
176176
instantiation, and will be applied only if the expression evaluates to a
177177
non-zero value.
178+
179+
## Solution 3: New instructions to initialize data and element segments
180+
181+
Similar to solution 2, we repurpose the memory index as a flags field. Unlike
182+
solution 2, the flags field specifies whether this segment is _inactive_. An
183+
inactive segment will not be automatically copied into the memory or table on
184+
instantiation, and must instead be applied manually using two new instructions:
185+
`init_memory` and `init_table`.
186+
187+
When the least-significant bit of the flags field is `1`, the segment is
188+
inactive. The rest of the bits of the flags field must be zero.
189+
190+
An inactive segment has no initializer expression, since it will be specified
191+
as an operand to `init_memory` or `init_table`.
192+
193+
The data section is encoded as follows:
194+
195+
```
196+
datasec ::= seg*:section\_11(vec(data)) => seg
197+
data ::= 0x00 e:expr b*:vec(byte) => {data 0, offset e, init b*, active true}
198+
data ::= 0x01 b*:vec(byte) => {data 0, offset empty, init b*, active false}
199+
```
200+
201+
The element section is encoded similarly.
202+
203+
### `init_memory` instruction
204+
205+
The `init_memory` instruction copies data from a given segment into a target
206+
memory. The source segment and target memory are given as immediates. The
207+
instruction also has three i32 operands: an offset into the source segment, an
208+
offset into the target memory, and a length to copy.
209+
210+
When `init_memory` is executed, its behavior matches the steps described in
211+
step 11 of
212+
[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation),
213+
but it behaves as though the segment were specified with the source offset,
214+
target offset, and length as given by the `init_memory` operands.
215+
216+
`init_memory` may only be used during
217+
[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation)
218+
when the start function is being invoked. At any other times, the instructions
219+
will trap.
220+
221+
A trap occurs if any of the accessed bytes lies outside the source data segment
222+
or the target memory.
223+
224+
Note that it is allowed to use `init_memory` on the same data segment more than
225+
once, or with an active data segment.
226+
227+
### `init_table` instruction
228+
229+
The `init_table` instruction behaves similary to the `init_memory` instruction,
230+
with the difference that it operates on element segments and tables, instead of
231+
data segments and memories. The offset and length operands of `init_table` have
232+
element units instead of bytes as well.
233+
234+
### Example
235+
236+
Consider the example given in solution 2; there are two data sections, the
237+
first is always active and the second is conditionally active if global 0 has a
238+
non-zero value. This could be implemented as follows:
239+
240+
```
241+
(import "a" "global" (global i32)) ;; global 0
242+
(memory 1)
243+
(data (i32.const 0) "hello") ;; data segment 0, is active so always copied
244+
(data inactive "goodbye") ;; data segment 1, is inactive
245+
246+
(func $start
247+
(if (get\_global 0)
248+
;; copy data segment 1 into memory
249+
(init\_memory 1
250+
(i32.const 0) ;; source offset
251+
(i32.const 16) ;; target offset
252+
(i32.const 7))) ;; length
253+
)
254+
```

0 commit comments

Comments
 (0)