@@ -175,3 +175,80 @@ elem ::= 0x01 e_o:expr e_a:expr y*:vec(funcindex) => {table 0, offset e_o, ap
175
175
As with data segments, the ` apply ` initializer expression is evaluated during
176
176
instantiation, and will be applied only if the expression evaluates to a
177
177
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