Skip to content

Commit 2f610a4

Browse files
authored
[interpreter] Refactor parser to handle select & call_indirect correctly (WebAssembly#1567)
1 parent 2eeea88 commit 2f610a4

File tree

1 file changed

+30
-70
lines changed

1 file changed

+30
-70
lines changed

text/parser.mly

Lines changed: 30 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -366,12 +366,16 @@ align_opt :
366366

367367
/* Instructions & Expressions */
368368

369-
instr :
369+
instr_list :
370+
| /* empty */ { fun c -> [] }
371+
| instr1 instr_list { fun c -> $1 c @ $2 c }
372+
| select_instr_instr_list { $1 }
373+
| call_instr_instr_list { $1 }
374+
375+
instr1 :
370376
| plain_instr { let at = at () in fun c -> [$1 c @@ at] }
371-
| select_instr_instr { fun c -> let e, es = $1 c in e :: es }
372-
| call_instr_instr { fun c -> let e, es = $1 c in e :: es }
373377
| block_instr { let at = at () in fun c -> [$1 c @@ at] }
374-
| expr { $1 } /* Sugar */
378+
| expr { $1 } /* Sugar */
375379

376380
plain_instr :
377381
| UNREACHABLE { fun c -> unreachable }
@@ -442,89 +446,51 @@ plain_instr :
442446
| VEC_REPLACE NAT { let at = at () in fun c -> $1 (vec_lane_index $2 at) }
443447

444448

445-
select_instr :
446-
| SELECT select_instr_results
447-
{ let at = at () in fun c -> let b, ts = $2 in
448-
select (if b then (Some ts) else None) @@ at }
449-
450-
select_instr_results :
451-
| LPAR RESULT value_type_list RPAR select_instr_results
452-
{ let _, ts = $5 in true, $3 @ ts }
453-
| /* empty */
454-
{ false, [] }
455-
456-
select_instr_instr :
457-
| SELECT select_instr_results_instr
449+
select_instr_instr_list :
450+
| SELECT select_instr_results_instr_list
458451
{ let at1 = ati 1 in
459452
fun c -> let b, ts, es = $2 c in
460-
select (if b then (Some ts) else None) @@ at1, es }
453+
(select (if b then (Some ts) else None) @@ at1) :: es }
461454

462-
select_instr_results_instr :
463-
| LPAR RESULT value_type_list RPAR select_instr_results_instr
455+
select_instr_results_instr_list :
456+
| LPAR RESULT value_type_list RPAR select_instr_results_instr_list
464457
{ fun c -> let _, ts, es = $5 c in true, $3 @ ts, es }
465-
| instr
458+
| instr_list
466459
{ fun c -> false, [], $1 c }
467460

468461

469-
call_instr :
470-
| CALL_INDIRECT var call_instr_type
471-
{ let at = at () in fun c -> call_indirect ($2 c table) ($3 c) @@ at }
472-
| CALL_INDIRECT call_instr_type /* Sugar */
473-
{ let at = at () in fun c -> call_indirect (0l @@ at) ($2 c) @@ at }
474-
475-
call_instr_type :
476-
| type_use call_instr_params
477-
{ let at1 = ati 1 in
478-
fun c ->
479-
match $2 c with
480-
| FuncType ([], []) -> $1 c type_
481-
| ft -> inline_type_explicit c ($1 c type_) ft at1 }
482-
| call_instr_params
483-
{ let at = at () in fun c -> inline_type c ($1 c) at }
484-
485-
call_instr_params :
486-
| LPAR PARAM value_type_list RPAR call_instr_params
487-
{ fun c -> let FuncType (ts1, ts2) = $5 c in FuncType ($3 @ ts1, ts2) }
488-
| call_instr_results
489-
{ fun c -> FuncType ([], $1 c) }
490-
491-
call_instr_results :
492-
| LPAR RESULT value_type_list RPAR call_instr_results
493-
{ fun c -> $3 @ $5 c }
494-
| /* empty */
495-
{ fun c -> [] }
496-
497-
498-
call_instr_instr :
499-
| CALL_INDIRECT var call_instr_type_instr
462+
call_instr_instr_list :
463+
| CALL_INDIRECT var call_instr_type_instr_list
500464
{ let at1 = ati 1 in
501-
fun c -> let x, es = $3 c in call_indirect ($2 c table) x @@ at1, es }
502-
| CALL_INDIRECT call_instr_type_instr /* Sugar */
465+
fun c -> let x, es = $3 c in
466+
(call_indirect ($2 c table) x @@ at1) :: es }
467+
| CALL_INDIRECT call_instr_type_instr_list /* Sugar */
503468
{ let at1 = ati 1 in
504-
fun c -> let x, es = $2 c in call_indirect (0l @@ at1) x @@ at1, es }
469+
fun c -> let x, es = $2 c in
470+
(call_indirect (0l @@ at1) x @@ at1) :: es }
505471

506-
call_instr_type_instr :
507-
| type_use call_instr_params_instr
472+
call_instr_type_instr_list :
473+
| type_use call_instr_params_instr_list
508474
{ let at1 = ati 1 in
509475
fun c ->
510476
match $2 c with
511477
| FuncType ([], []), es -> $1 c type_, es
512478
| ft, es -> inline_type_explicit c ($1 c type_) ft at1, es }
513-
| call_instr_params_instr
479+
| call_instr_params_instr_list
514480
{ let at = at () in
515481
fun c -> let ft, es = $1 c in inline_type c ft at, es }
516482

517-
call_instr_params_instr :
518-
| LPAR PARAM value_type_list RPAR call_instr_params_instr
483+
call_instr_params_instr_list :
484+
| LPAR PARAM value_type_list RPAR call_instr_params_instr_list
519485
{ fun c ->
520486
let FuncType (ts1, ts2), es = $5 c in FuncType ($3 @ ts1, ts2), es }
521-
| call_instr_results_instr
487+
| call_instr_results_instr_list
522488
{ fun c -> let ts, es = $1 c in FuncType ([], ts), es }
523489

524-
call_instr_results_instr :
525-
| LPAR RESULT value_type_list RPAR call_instr_results_instr
490+
call_instr_results_instr_list :
491+
| LPAR RESULT value_type_list RPAR call_instr_results_instr_list
526492
{ fun c -> let ts, es = $5 c in $3 @ ts, es }
527-
| instr
493+
| instr_list
528494
{ fun c -> [], $1 c }
529495

530496

@@ -657,12 +623,6 @@ if_ :
657623
| LPAR THEN instr_list RPAR /* Sugar */
658624
{ fun c c' -> [], $3 c', [] }
659625

660-
instr_list :
661-
| /* empty */ { fun c -> [] }
662-
| select_instr { fun c -> [$1 c] }
663-
| call_instr { fun c -> [$1 c] }
664-
| instr instr_list { fun c -> $1 c @ $2 c }
665-
666626
expr_list :
667627
| /* empty */ { fun c -> [] }
668628
| expr expr_list { fun c -> $1 c @ $2 c }

0 commit comments

Comments
 (0)