Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Commit d97e8fb

Browse files
authored
[Interpreter] New syntax for passive elem segments (#65)
It uses instruction encoding instead of assuming that each element is a function variable: ``` 0xd0 -> ref.null 0xd2 x -> ref.func x ```
1 parent f574364 commit d97e8fb

File tree

9 files changed

+103
-29
lines changed

9 files changed

+103
-29
lines changed

interpreter/binary/decode.ml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,25 +612,36 @@ let code_section s =
612612

613613
(* Element section *)
614614

615-
let segment dat s =
615+
let segment active passive s =
616616
match vu32 s with
617617
| 0l ->
618618
let index = Source.(0l @@ Source.no_region) in
619619
let offset = const s in
620-
let init = dat s in
620+
let init = active s in
621621
Active {index; offset; init}
622622
| 1l ->
623-
let init = dat s in
623+
let init = passive s in
624624
Passive init
625625
| 2l ->
626626
let index = at var s in
627627
let offset = const s in
628-
let init = dat s in
628+
let init = active s in
629629
Active {index; offset; init}
630630
| _ -> error s (pos s - 1) "invalid segment kind"
631631

632+
let active_elem s = Func (at var s)
633+
634+
let passive_elem s =
635+
match u8 s with
636+
| 0xd0 -> end_ s; Null
637+
| 0xd2 ->
638+
let x = at var s in
639+
end_ s;
640+
Func x
641+
| _ -> error s (pos s - 1) "invalid elem"
642+
632643
let table_segment s =
633-
segment (vec (at var)) s
644+
segment (vec (at active_elem)) (vec (at passive_elem)) s
634645

635646
let elem_section s =
636647
section `ElemSection (vec (at table_segment)) [] s
@@ -639,7 +650,7 @@ let elem_section s =
639650
(* Data section *)
640651

641652
let memory_segment s =
642-
segment string s
653+
segment string string s
643654

644655
let data_section s =
645656
section `DataSection (vec (at memory_segment)) [] s

interpreter/binary/encode.ml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ let encode m =
477477
section 10 (vec code) fs (fs <> [])
478478

479479
(* Element section *)
480-
let segment dat seg =
480+
let segment active passive seg =
481481
match seg.it with
482482
| Active {index; offset; init} ->
483483
if index.it = 0l then
@@ -486,19 +486,29 @@ let encode m =
486486
u8 0x02; var index
487487
end;
488488
const offset;
489-
dat init
489+
active init
490490
| Passive init ->
491-
u8 0x01; dat init
491+
u8 0x01; passive init
492+
493+
let active_elem el =
494+
match el.it with
495+
| Null -> assert false
496+
| Func x -> var x
497+
498+
let passive_elem el =
499+
match el.it with
500+
| Null -> u8 0xd0; end_ ()
501+
| Func x -> u8 0xd2; var x; end_ ()
492502

493503
let table_segment seg =
494-
segment (vec var) seg
504+
segment (vec active_elem) (vec passive_elem) seg
495505

496506
let elem_section elems =
497507
section 9 (vec table_segment) elems (elems <> [])
498508

499509
(* Data section *)
500510
let memory_segment seg =
501-
segment string seg
511+
segment string string seg
502512

503513
let data_section data =
504514
section 11 (vec memory_segment) data (data <> [])

interpreter/exec/eval.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,11 @@ let create_export (inst : module_inst) (ex : export) : export_inst =
436436
in name, ext
437437

438438
let elems_list inst init =
439-
List.map (fun x -> (FuncElem (func inst x))) init
439+
let to_elem el =
440+
match el.it with
441+
| Null -> Table.Uninitialized
442+
| Func x -> FuncElem (func inst x)
443+
in List.map to_elem init
440444

441445
let create_elems (inst : module_inst) (seg : table_segment) : elems_inst =
442446
match seg.it with

interpreter/syntax/ast.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,12 @@ and 'data segment' =
145145
| Active of {index : var; offset : const; init : 'data}
146146
| Passive of 'data
147147

148-
type table_segment = var list segment
148+
type elem = elem' Source.phrase
149+
and elem' =
150+
| Null
151+
| Func of var
152+
153+
type table_segment = elem list segment
149154
type memory_segment = string segment
150155

151156

@@ -191,7 +196,7 @@ and module_' =
191196
memories : memory list;
192197
funcs : func list;
193198
start : var option;
194-
elems : var list segment list;
199+
elems : elem list segment list;
195200
data : string segment list;
196201
imports : import list;
197202
exports : export list;

interpreter/text/arrange.ml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,27 @@ let memory off i mem =
296296
let {mtype = MemoryType lim} = mem.it in
297297
Node ("memory $" ^ nat (off + i) ^ " " ^ limits nat32 lim, [])
298298

299-
let segment head dat seg =
299+
let segment head active passive seg =
300300
match seg.it with
301301
| Active {index; offset; init} ->
302-
Node (head, atom var index :: Node ("offset", const offset) :: dat init)
303-
| Passive init -> Node (head ^ " passive", dat init)
302+
Node (head, atom var index :: Node ("offset", const offset) :: active init)
303+
| Passive init -> Node (head ^ " passive", passive init)
304+
305+
let active_elem el =
306+
match el.it with
307+
| Null -> assert false
308+
| Func x -> atom var x
309+
310+
let passive_elem el =
311+
match el.it with
312+
| Null -> Node ("ref.null", [])
313+
| Func x -> Node ("ref.func", [atom var x])
304314

305315
let elems seg =
306-
segment "elem" (list (atom var)) seg
316+
segment "elem" (list active_elem) (list passive_elem) seg
307317

308318
let data seg =
309-
segment "data" break_bytes seg
319+
segment "data" break_bytes break_bytes seg
310320

311321

312322
(* Modules *)

interpreter/text/lexer.mll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ rule token = parse
325325
| "elem.drop" { ELEM_DROP }
326326
| "table.copy" { TABLE_COPY }
327327

328+
| "ref.null" { REF_NULL }
329+
| "ref.func" { REF_FUNC }
330+
328331
| "passive" { PASSIVE }
329332

330333
| "type" { TYPE }

interpreter/text/parser.mly

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ let inline_type_explicit (c : context) x ft at =
163163
%token UNREACHABLE MEMORY_SIZE MEMORY_GROW
164164
%token MEMORY_INIT DATA_DROP MEMORY_COPY MEMORY_FILL
165165
%token TABLE_INIT ELEM_DROP TABLE_COPY
166+
%token REF_NULL REF_FUNC
166167
%token FUNC START TYPE PARAM RESULT LOCAL GLOBAL
167168
%token TABLE ELEM MEMORY DATA OFFSET IMPORT EXPORT TABLE
168169
%token PASSIVE
@@ -568,22 +569,35 @@ offset :
568569
| LPAR OFFSET const_expr RPAR { $3 }
569570
| expr { let at = at () in fun c -> $1 c @@ at } /* Sugar */
570571
572+
elemref :
573+
| LPAR REF_NULL RPAR { let at = at () in fun c -> Null @@ at }
574+
| LPAR REF_FUNC var RPAR { let at = at () in fun c -> Func ($3 c func) @@ at }
575+
576+
passive_elemref_list :
577+
| /* empty */ { fun c -> [] }
578+
| elemref passive_elemref_list { fun c -> $1 c :: $2 c }
579+
580+
active_elemref_list :
581+
| var_list
582+
{ let f = function {at; _} as x -> Func x @@ at in
583+
fun c lookup -> List.map f ($1 c lookup) }
584+
571585
elem :
572-
| LPAR ELEM bind_var_opt PASSIVE var_list RPAR
586+
| LPAR ELEM bind_var_opt PASSIVE passive_elemref_list RPAR
573587
{ let at = at () in
574588
fun c -> ignore ($3 c anon_elem bind_elem);
575-
fun () -> Passive ($5 c func) @@ at }
576-
| LPAR ELEM bind_var var offset var_list RPAR
589+
fun () -> Passive ($5 c) @@ at }
590+
| LPAR ELEM bind_var var offset active_elemref_list RPAR
577591
{ let at = at () in
578592
fun c -> ignore (bind_elem c $3);
579593
fun () ->
580594
Active {index = $4 c table; offset = $5 c; init = $6 c func} @@ at }
581-
| LPAR ELEM var offset var_list RPAR
595+
| LPAR ELEM var offset active_elemref_list RPAR
582596
{ let at = at () in
583597
fun c -> ignore (anon_elem c);
584598
fun () ->
585599
Active {index = $3 c table; offset = $4 c; init = $5 c func} @@ at }
586-
| LPAR ELEM offset var_list RPAR /* Sugar */
600+
| LPAR ELEM offset active_elemref_list RPAR /* Sugar */
587601
{ let at = at () in
588602
fun c -> ignore (anon_elem c);
589603
fun () ->
@@ -606,7 +620,7 @@ table_fields :
606620
| inline_export table_fields /* Sugar */
607621
{ fun c x at -> let tabs, elems, ims, exs = $2 c x at in
608622
tabs, elems, ims, $1 (TableExport x) c :: exs }
609-
| elem_type LPAR ELEM var_list RPAR /* Sugar */
623+
| elem_type LPAR ELEM active_elemref_list RPAR /* Sugar */
610624
{ fun c x at ->
611625
let offset = [i32_const (0l @@ at) @@ at] @@ at in
612626
let init = $4 c func in let size = Int32.of_int (List.length init) in

interpreter/valid/valid.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,19 @@ let check_memory (c : context) (mem : memory) =
424424
let {mtype} = mem.it in
425425
check_memory_type mtype mem.at
426426

427+
let check_elemref (c : context) (el : elem) =
428+
match el.it with
429+
| Null -> ()
430+
| Func x -> ignore (func c x)
431+
427432
let check_elem (c : context) (seg : table_segment) =
428433
match seg.it with
429434
| Active {index; offset; init} ->
430435
ignore (table c index);
431436
check_const c offset I32Type;
432-
ignore (List.map (func c) init)
437+
List.iter (check_elemref c) init
433438
| Passive init ->
434-
ignore (List.map (func c) init)
439+
List.iter (check_elemref c) init
435440

436441
let check_data (c : context) (seg : memory_segment) =
437442
match seg.it with

test/core/bulk.wast

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
;; Passive segment syntax
2+
(module
3+
(memory 1)
4+
(data passive "foo"))
5+
6+
(module
7+
(table 3 funcref)
8+
(elem passive (ref.func 0) (ref.null) (ref.func 1))
9+
(func)
10+
(func))
11+
112
;; memory.fill
213
(module
314
(memory 1)
@@ -171,7 +182,8 @@
171182
;; table.init
172183
(module
173184
(table 3 funcref)
174-
(elem passive $zero $one $zero $one)
185+
(elem passive
186+
(ref.func $zero) (ref.func $one) (ref.func $zero) (ref.func $one))
175187

176188
(func $zero (result i32) (i32.const 0))
177189
(func $one (result i32) (i32.const 1))
@@ -215,7 +227,7 @@
215227
(module
216228
(table 1 funcref)
217229
(func $f)
218-
(elem $p passive $f)
230+
(elem $p passive (ref.func $f))
219231
(elem $a 0 (i32.const 0) $f)
220232

221233
(func (export "drop_passive") (elem.drop $p))

0 commit comments

Comments
 (0)