Skip to content

Commit

Permalink
Add alternate proposal for segment init. (#79)
Browse files Browse the repository at this point in the history
This solution introduces new instructions to initialize segments programmatically, but only in the start function.
  • Loading branch information
binji authored Nov 18, 2017
1 parent 5d2ad6e commit 4b0f677
Showing 1 changed file with 77 additions and 0 deletions.
77 changes: 77 additions & 0 deletions proposals/threads/ConditionalSegmentInitialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,80 @@ elem ::= 0x01 e_o:expr e_a:expr y*:vec(funcindex) => {table 0, offset e_o, ap
As with data segments, the `apply` initializer expression is evaluated during
instantiation, and will be applied only if the expression evaluates to a
non-zero value.

## Solution 3: New instructions to initialize data and element segments

Similar to solution 2, we repurpose the memory index as a flags field. Unlike
solution 2, the flags field specifies whether this segment is _inactive_. An
inactive segment will not be automatically copied into the memory or table on
instantiation, and must instead be applied manually using two new instructions:
`init_memory` and `init_table`.

When the least-significant bit of the flags field is `1`, the segment is
inactive. The rest of the bits of the flags field must be zero.

An inactive segment has no initializer expression, since it will be specified
as an operand to `init_memory` or `init_table`.

The data section is encoded as follows:

```
datasec ::= seg*:section\_11(vec(data)) => seg
data ::= 0x00 e:expr b*:vec(byte) => {data 0, offset e, init b*, active true}
data ::= 0x01 b*:vec(byte) => {data 0, offset empty, init b*, active false}
```

The element section is encoded similarly.

### `init_memory` instruction

The `init_memory` instruction copies data from a given segment into a target
memory. The source segment and target memory are given as immediates. The
instruction also has three i32 operands: an offset into the source segment, an
offset into the target memory, and a length to copy.

When `init_memory` is executed, its behavior matches the steps described in
step 11 of
[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation),
but it behaves as though the segment were specified with the source offset,
target offset, and length as given by the `init_memory` operands.

`init_memory` may only be used during
[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation)
when the start function is being invoked. At any other times, the instructions
will trap.

A trap occurs if any of the accessed bytes lies outside the source data segment
or the target memory.

Note that it is allowed to use `init_memory` on the same data segment more than
once, or with an active data segment.

### `init_table` instruction

The `init_table` instruction behaves similary to the `init_memory` instruction,
with the difference that it operates on element segments and tables, instead of
data segments and memories. The offset and length operands of `init_table` have
element units instead of bytes as well.

### Example

Consider the example given in solution 2; there are two data sections, the
first is always active and the second is conditionally active if global 0 has a
non-zero value. This could be implemented as follows:

```
(import "a" "global" (global i32)) ;; global 0
(memory 1)
(data (i32.const 0) "hello") ;; data segment 0, is active so always copied
(data inactive "goodbye") ;; data segment 1, is inactive
(func $start
(if (get\_global 0)
;; copy data segment 1 into memory
(init\_memory 1
(i32.const 0) ;; source offset
(i32.const 16) ;; target offset
(i32.const 7))) ;; length
)
```

0 comments on commit 4b0f677

Please sign in to comment.