From 8ce9244de865167ea08a9fa571bdde940552a5c0 Mon Sep 17 00:00:00 2001 From: Andrew Scheidecker Date: Sat, 21 Nov 2015 17:42:15 -0500 Subject: [PATCH] Wrap the tableswitch default target in a (default ...) node so that something like (default (case x)) stands out from its (case ...) siblings that define targets rather than references to targets. --- ml-proto/host/lexer.mll | 1 + ml-proto/host/parser.mly | 8 ++++---- ml-proto/test/labels.wast | 6 ++++-- ml-proto/test/switch.wast | 28 ++++++++++++++++++---------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/ml-proto/host/lexer.mll b/ml-proto/host/lexer.mll index ec83a6e25e..379a9d15ab 100644 --- a/ml-proto/host/lexer.mll +++ b/ml-proto/host/lexer.mll @@ -148,6 +148,7 @@ rule token = parse | "if_else" { IF_ELSE } | "tableswitch" { TABLESWITCH } | "case" { CASE } + | "default" { DEFAULT } | "call" { CALL } | "call_import" { CALL_IMPORT } | "call_indirect" { CALL_INDIRECT } diff --git a/ml-proto/host/parser.mly b/ml-proto/host/parser.mly index 9d92550205..f6fd222781 100644 --- a/ml-proto/host/parser.mly +++ b/ml-proto/host/parser.mly @@ -131,7 +131,7 @@ let implicit_decl c t at = %} %token INT FLOAT TEXT VAR VALUE_TYPE LPAR RPAR -%token NOP BLOCK IF IF_ELSE LOOP BR BR_IF TABLESWITCH CASE +%token NOP BLOCK IF IF_ELSE LOOP BR BR_IF TABLESWITCH CASE DEFAULT %token CALL CALL_IMPORT CALL_INDIRECT RETURN %token GET_LOCAL SET_LOCAL LOAD STORE OFFSET ALIGN %token CONST UNARY BINARY COMPARE CONVERT @@ -239,10 +239,10 @@ expr1 : fun c -> Return (label c ("return" @@ at1) @@ at1, $2 c) } | IF expr expr { fun c -> If ($2 c, $3 c) } | IF_ELSE expr expr expr { fun c -> If_else ($2 c, $3 c, $4 c) } - | TABLESWITCH labeling expr LPAR TABLE target_list RPAR target case_list + | TABLESWITCH labeling expr LPAR TABLE target_list RPAR LPAR DEFAULT target RPAR case_list { fun c -> let c' = $2 c in let e = $3 c' in - let c'' = enter_switch c' in let es = $9 c'' in - Tableswitch (e, $6 c'', $8 c'', es) } + let c'' = enter_switch c' in let es = $12 c'' in + Tableswitch (e, $6 c'', $10 c'', es) } | CALL var expr_list { fun c -> Call ($2 c func, $3 c) } | CALL_IMPORT var expr_list { fun c -> Call_import ($2 c import, $3 c) } | CALL_INDIRECT var expr expr_list diff --git a/ml-proto/test/labels.wast b/ml-proto/test/labels.wast index f9287ae5b1..3549b35e7d 100644 --- a/ml-proto/test/labels.wast +++ b/ml-proto/test/labels.wast @@ -62,7 +62,8 @@ (block $ret (i32.mul (i32.const 10) (tableswitch $exit (get_local 0) - (table (case $0) (case $1) (case $2) (case $3)) (case $default) + (table (case $0) (case $1) (case $2) (case $3)) + (default (case $default)) (case $1 (i32.const 1)) (case $2 (br $exit (i32.const 2))) (case $3 (br $ret (i32.const 3))) @@ -75,7 +76,8 @@ (func $return (param i32) (result i32) (tableswitch (get_local 0) - (table (case $0) (case $1)) (case $default) + (table (case $0) (case $1)) + (default (case $default)) (case $0 (return (i32.const 0))) (case $1 (i32.const 1)) (case $default (i32.const 2)) diff --git a/ml-proto/test/switch.wast b/ml-proto/test/switch.wast index 0a9db9a06b..5a0899e13e 100644 --- a/ml-proto/test/switch.wast +++ b/ml-proto/test/switch.wast @@ -6,7 +6,8 @@ (block (tableswitch (get_local $i) (table (case $0) (case $1) (case $2) (case $3) (case $4) - (case $5) (case $6) (case $7)) (case $default) + (case $5) (case $6) (case $7)) + (default (case $default)) (case $0 (return (get_local $i))) (case $1 (nop)) ;; fallthrough (case $2) ;; fallthrough @@ -29,7 +30,8 @@ (block $l (tableswitch (i32.wrap/i64 (get_local $i)) (table (case $0) (case $1) (case $2) (case $3) (case $4) - (case $5) (case $6) (case $7)) (case $default) + (case $5) (case $6) (case $7)) + (default (case $default)) (case $0 (return (get_local $i))) (case $1 (nop)) ;; fallthrough (case $2) ;; fallthrough @@ -48,15 +50,18 @@ (func $corner (result i32) (local $x i32) (tableswitch (i32.const 0) - (table) (case $default) + (table) + (default (case $default)) (case $default) ) (tableswitch (i32.const 0) - (table) (case $default) + (table) + (default (case $default)) (case $default (set_local $x (i32.add (get_local $x) (i32.const 1)))) ) (tableswitch (i32.const 1) - (table (case $0)) (case $default) + (table (case $0)) + (default (case $default)) (case $default (set_local $x (i32.add (get_local $x) (i32.const 2)))) (case $0 (set_local $x (i32.add (get_local $x) (i32.const 4)))) ) @@ -67,14 +72,17 @@ (func $break (result i32) (local $x i32) (tableswitch $l (i32.const 0) - (table) (br $l) + (table) + (default (br $l)) ) (tableswitch $l (i32.const 0) - (table (br $l)) (case $default) + (table (br $l)) + (default (case $default)) (case $default (set_local $x (i32.add (get_local $x) (i32.const 1)))) ) (tableswitch $l (i32.const 1) - (table (case $0)) (br $l) + (table (case $0)) + (default (br $l)) (case $0 (set_local $x (i32.add (get_local $x) (i32.const 2)))) ) (get_local $x) @@ -107,5 +115,5 @@ (assert_return (invoke "corner") (i32.const 7)) (assert_return (invoke "break") (i32.const 0)) -(assert_invalid (module (func (tableswitch (i32.const 0) (table) (case 0)))) "invalid target") -(assert_invalid (module (func (tableswitch (i32.const 0) (table) (case 1) (case)))) "invalid target") +(assert_invalid (module (func (tableswitch (i32.const 0) (table) (default (case 0))))) "invalid target") +(assert_invalid (module (func (tableswitch (i32.const 0) (table) (default (case 1)) (case)))) "invalid target")