Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add alternate proposal for segment init. #79

Merged
merged 3 commits into from
Nov 18, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
)
```