From 17001b5535500562a5c75d6b8da1c20d801bced0 Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Wed, 15 Nov 2017 14:51:02 -0800 Subject: [PATCH 1/3] Add alternate proposal for segment init. This solution introduces new instructions to initialize segments programmatically, but only in the start function. --- .../ConditionalSegmentInitialization.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/proposals/threads/ConditionalSegmentInitialization.md b/proposals/threads/ConditionalSegmentInitialization.md index 220e41e6..c7b2daad 100644 --- a/proposals/threads/ConditionalSegmentInitialization.md +++ b/proposals/threads/ConditionalSegmentInitialization.md @@ -175,3 +175,58 @@ 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. + +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 e:expr b*:vec(byte) => {data 0, offset e, init b*, active false} +``` + +The element section would be encoded similarly. + +### `init_memory` and `init_table` + +These instructions copy data from a given segment into the memory or table. The +segment index is provided as an immediate value. Both instructions have no +operands and return no results. If the segment index immediate is +out-of-bounds, it is a validation error. + +When `init_memory` is executed, its behavior exactly matches the steps +described in step 11 of +[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation). +Similarly, `init_table` has behavior matching step 10. + +These instructions may only be used in the [start +function](https://webassembly.github.io/spec/syntax/modules.html#start-function), +and only when the start function is called automatically during instantiation. +At any other times, the instructions will trap. + +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 +(data (i32.const 16) "goodbye") ;; data segment 1 + +(func $start + (init_memory 0) ;; copy data segment 0 into memory + (if (get_global 0) + (init_memory 1)) ;; copy data segment 1 into memory +) +``` From 5dce231179b9e1d396ee74e2d549b3eb6c8d16ad Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Fri, 17 Nov 2017 15:56:19 -0800 Subject: [PATCH 2/3] Address comments --- .../ConditionalSegmentInitialization.md | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/proposals/threads/ConditionalSegmentInitialization.md b/proposals/threads/ConditionalSegmentInitialization.md index c7b2daad..71187476 100644 --- a/proposals/threads/ConditionalSegmentInitialization.md +++ b/proposals/threads/ConditionalSegmentInitialization.md @@ -184,35 +184,49 @@ 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. +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 +datasec ::= seg*:section\_11(vec(data)) => seg data ::= 0x00 e:expr b*:vec(byte) => {data 0, offset e, init b*, active true} -data ::= 0x01 e:expr b*:vec(byte) => {data 0, offset e, init b*, active false} +data ::= 0x01 b*:vec(byte) => {data 0, offset empty, init b*, active false} ``` -The element section would be encoded similarly. +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. + +A trap occurs if any of the accessed bytes lies outside the source data segment +or the target memory. -### `init_memory` and `init_table` +Note that it is allowed to use `init_memory` on the same data segment more than +once, or with an active data segment. -These instructions copy data from a given segment into the memory or table. The -segment index is provided as an immediate value. Both instructions have no -operands and return no results. If the segment index immediate is -out-of-bounds, it is a validation error. +### `init_table` instruction -When `init_memory` is executed, its behavior exactly matches the steps -described in step 11 of -[instantiation](https://webassembly.github.io/spec/exec/modules.html#instantiation). -Similarly, `init_table` has behavior matching step 10. +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. -These instructions may only be used in the [start -function](https://webassembly.github.io/spec/syntax/modules.html#start-function), -and only when the start function is called automatically during instantiation. -At any other times, the instructions will trap. +### 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 @@ -221,12 +235,15 @@ 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 -(data (i32.const 16) "goodbye") ;; data segment 1 +(data (i32.const 0) "hello") ;; data segment 0, is active so always copied +(data inactive "goodbye") ;; data segment 1, is inactive (func $start - (init_memory 0) ;; copy data segment 0 into memory - (if (get_global 0) - (init_memory 1)) ;; copy data segment 1 into memory + (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 ) ``` From 116a479e6b09a242a907cb86d6ba8ab631f44b89 Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Fri, 17 Nov 2017 16:53:01 -0800 Subject: [PATCH 3/3] Re-add paragraph about init instrs+start function --- proposals/threads/ConditionalSegmentInitialization.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/threads/ConditionalSegmentInitialization.md b/proposals/threads/ConditionalSegmentInitialization.md index 71187476..5b6b3525 100644 --- a/proposals/threads/ConditionalSegmentInitialization.md +++ b/proposals/threads/ConditionalSegmentInitialization.md @@ -213,6 +213,11 @@ step 11 of 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.