From 7429876b5621bc328990b1976b03b2561b849e97 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Nov 2015 14:01:49 -0800 Subject: [PATCH 1/4] Change nan literal syntax to avoid including parens. Change from `nan(0x...)` to `nan:0x...`, since parens are reserved characters in the s-expression syntax. --- ml-proto/host/lexer.mll | 2 +- ml-proto/spec/float.ml | 8 +++---- ml-proto/test/float_literals.wast | 24 ++++++++++----------- ml-proto/test/float_memory.wast | 8 +++---- ml-proto/test/float_misc.wast | 36 +++++++++++++++---------------- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/ml-proto/host/lexer.mll b/ml-proto/host/lexer.mll index 357678418a..729f5dce68 100644 --- a/ml-proto/host/lexer.mll +++ b/ml-proto/host/lexer.mll @@ -101,7 +101,7 @@ let float = | sign "0x" hexdigit+ '.'? hexdigit* 'p' sign digit+ | sign "infinity" | sign "nan" - | sign "nan(0x" hexdigit+ ")" + | sign "nan:0x" hexdigit+ let text = '"' character* '"' let name = '$' (letter | digit | '_' | tick | symbol)+ diff --git a/ml-proto/spec/float.ml b/ml-proto/spec/float.ml index 1e326fdcb0..aa2a2f85b2 100644 --- a/ml-proto/spec/float.ml +++ b/ml-proto/spec/float.ml @@ -143,9 +143,9 @@ struct let of_signless_string x len = if x <> "nan" && - (len > 7) && - (String.sub x 0 6) = "nan(0x" && (String.get x (len - 1)) = ')' then - (let s = Rep.of_string (String.sub x 4 ((len - 5))) in + (len > 6) && + (String.sub x 0 6) = "nan:0x" then + (let s = Rep.of_string (String.sub x 4 ((len - 4))) in if s = Rep.zero then raise (Failure "nan payload must not be zero") else if Rep.logand s bare_nan <> Rep.zero then @@ -172,7 +172,7 @@ struct let a = abs x in let af = arith_of_bits a in if af <> af then - ("nan(0x" ^ Rep.print_nan_significand_digits a ^ ")") + ("nan:0x" ^ Rep.print_nan_significand_digits a) else (* TODO: OCaml's string_of_float is insufficient *) string_of_float (to_float a) diff --git a/ml-proto/test/float_literals.wast b/ml-proto/test/float_literals.wast index 27ed205ee7..ca71a77eb0 100644 --- a/ml-proto/test/float_literals.wast +++ b/ml-proto/test/float_literals.wast @@ -2,12 +2,12 @@ (func $f32.nan (result i32) (i32.reinterpret/f32 (f32.const nan))) (func $f32.positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan))) (func $f32.negative_nan (result i32) (i32.reinterpret/f32 (f32.const -nan))) - (func $f32.plain_nan (result i32) (i32.reinterpret/f32 (f32.const nan(0x400000)))) - (func $f32.informally_known_as_plain_snan (result i32) (i32.reinterpret/f32 (f32.const nan(0x200000)))) - (func $f32.allones_nan (result i32) (i32.reinterpret/f32 (f32.const -nan(0x7fffff)))) - (func $f32.misc_nan (result i32) (i32.reinterpret/f32 (f32.const nan(0x012345)))) - (func $f32.misc_positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan(0x304050)))) - (func $f32.misc_negative_nan (result i32) (i32.reinterpret/f32 (f32.const -nan(0x2abcde)))) + (func $f32.plain_nan (result i32) (i32.reinterpret/f32 (f32.const nan:0x400000))) + (func $f32.informally_known_as_plain_snan (result i32) (i32.reinterpret/f32 (f32.const nan:0x200000))) + (func $f32.allones_nan (result i32) (i32.reinterpret/f32 (f32.const -nan:0x7fffff))) + (func $f32.misc_nan (result i32) (i32.reinterpret/f32 (f32.const nan:0x012345))) + (func $f32.misc_positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan:0x304050))) + (func $f32.misc_negative_nan (result i32) (i32.reinterpret/f32 (f32.const -nan:0x2abcde))) (func $f32.infinity (result i32) (i32.reinterpret/f32 (f32.const infinity))) (func $f32.positive_infinity (result i32) (i32.reinterpret/f32 (f32.const +infinity))) (func $f32.negative_infinity (result i32) (i32.reinterpret/f32 (f32.const -infinity))) @@ -24,12 +24,12 @@ (func $f64.nan (result i64) (i64.reinterpret/f64 (f64.const nan))) (func $f64.positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan))) (func $f64.negative_nan (result i64) (i64.reinterpret/f64 (f64.const -nan))) - (func $f64.plain_nan (result i64) (i64.reinterpret/f64 (f64.const nan(0x8000000000000)))) - (func $f64.informally_known_as_plain_snan (result i64) (i64.reinterpret/f64 (f64.const nan(0x4000000000000)))) - (func $f64.allones_nan (result i64) (i64.reinterpret/f64 (f64.const -nan(0xfffffffffffff)))) - (func $f64.misc_nan (result i64) (i64.reinterpret/f64 (f64.const nan(0x0123456789abc)))) - (func $f64.misc_positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan(0x3040506070809)))) - (func $f64.misc_negative_nan (result i64) (i64.reinterpret/f64 (f64.const -nan(0x2abcdef012345)))) + (func $f64.plain_nan (result i64) (i64.reinterpret/f64 (f64.const nan:0x8000000000000))) + (func $f64.informally_known_as_plain_snan (result i64) (i64.reinterpret/f64 (f64.const nan:0x4000000000000))) + (func $f64.allones_nan (result i64) (i64.reinterpret/f64 (f64.const -nan:0xfffffffffffff))) + (func $f64.misc_nan (result i64) (i64.reinterpret/f64 (f64.const nan:0x0123456789abc))) + (func $f64.misc_positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan:0x3040506070809))) + (func $f64.misc_negative_nan (result i64) (i64.reinterpret/f64 (f64.const -nan:0x2abcdef012345))) (func $f64.infinity (result i64) (i64.reinterpret/f64 (f64.const infinity))) (func $f64.positive_infinity (result i64) (i64.reinterpret/f64 (f64.const +infinity))) (func $f64.negative_infinity (result i64) (i64.reinterpret/f64 (f64.const -infinity))) diff --git a/ml-proto/test/float_memory.wast b/ml-proto/test/float_memory.wast index 03490f7a16..b9418a5159 100644 --- a/ml-proto/test/float_memory.wast +++ b/ml-proto/test/float_memory.wast @@ -23,11 +23,11 @@ ) (assert_return (invoke "store_i32" (i32.const 0x7f800001)) (i32.const 0x7f800001)) -(assert_return (invoke "load_f32") (f32.const nan(0x000001))) +(assert_return (invoke "load_f32") (f32.const nan:0x000001)) (assert_return (invoke "store_i32" (i32.const 0x80000000)) (i32.const 0x80000000)) (assert_return (invoke "load_f32") (f32.const -0.0)) -(assert_return (invoke "store_f32" (f32.const nan(0x000001))) (f32.const nan(0x000001))) +(assert_return (invoke "store_f32" (f32.const nan:0x000001)) (f32.const nan:0x000001)) (assert_return (invoke "load_i32") (i32.const 0x7f800001)) (assert_return (invoke "store_f32" (f32.const -0.0)) (f32.const -0.0)) (assert_return (invoke "load_i32") (i32.const 0x80000000)) @@ -54,11 +54,11 @@ ) (assert_return (invoke "store_i64" (i64.const 0x7ff0000000000001)) (i64.const 0x7ff0000000000001)) -(assert_return (invoke "load_f64") (f64.const nan(0x0000000000001))) +(assert_return (invoke "load_f64") (f64.const nan:0x0000000000001)) (assert_return (invoke "store_i64" (i64.const 0x8000000000000000)) (i64.const 0x8000000000000000)) (assert_return (invoke "load_f64") (f64.const -0.0)) -(assert_return (invoke "store_f64" (f64.const nan(0x0000000000001))) (f64.const nan(0x0000000000001))) +(assert_return (invoke "store_f64" (f64.const nan:0x0000000000001)) (f64.const nan:0x0000000000001)) (assert_return (invoke "load_i64") (i64.const 0x7ff0000000000001)) (assert_return (invoke "store_f64" (f64.const -0.0)) (f64.const -0.0)) (assert_return (invoke "load_i64") (i64.const 0x8000000000000000)) diff --git a/ml-proto/test/float_misc.wast b/ml-proto/test/float_misc.wast index 12a8f2da20..c447d621df 100644 --- a/ml-proto/test/float_misc.wast +++ b/ml-proto/test/float_misc.wast @@ -64,7 +64,7 @@ (assert_return (invoke "f32.add" (f32.const 0x1.000002p+23) (f32.const 0x1p-1)) (f32.const 0x1.000004p+23)) ;; Test that what some systems call signalling NaN behaves as a quiet NaN. -(assert_return_nan (invoke "f32.add" (f32.const nan(0x200000)) (f32.const 1.0))) +(assert_return_nan (invoke "f32.add" (f32.const nan:0x200000) (f32.const 1.0))) (assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0)) @@ -136,7 +136,7 @@ (assert_return (invoke "f64.add" (f64.const -0x0.3f3d1a052fa2bp-1022) (f64.const -0x1.4b78292c7d2adp-1021)) (f64.const -0x1.6b16b62f14fc2p-1021)) ;; Test that what some systems call signalling NaN behaves as a quiet NaN. -(assert_return_nan (invoke "f64.add" (f64.const nan(0x4000000000000)) (f64.const 1.0))) +(assert_return_nan (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0))) ;; Test for a historic spreadsheet bug. ;; https://blogs.office.com/2007/09/25/calculation-issue-update/ @@ -260,41 +260,41 @@ (assert_return (invoke "f32.abs" (f32.const nan)) (f32.const nan)) (assert_return (invoke "f32.abs" (f32.const -nan)) (f32.const nan)) -(assert_return (invoke "f32.abs" (f32.const nan(0x0f1e2))) (f32.const nan(0x0f1e2))) -(assert_return (invoke "f32.abs" (f32.const -nan(0x0f1e2))) (f32.const nan(0x0f1e2))) +(assert_return (invoke "f32.abs" (f32.const nan:0x0f1e2)) (f32.const nan:0x0f1e2)) +(assert_return (invoke "f32.abs" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f64.abs" (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.abs" (f64.const -nan)) (f64.const nan)) -(assert_return (invoke "f64.abs" (f64.const nan(0x0f1e27a6b))) (f64.const nan(0x0f1e27a6b))) -(assert_return (invoke "f64.abs" (f64.const -nan(0x0f1e27a6b))) (f64.const nan(0x0f1e27a6b))) +(assert_return (invoke "f64.abs" (f64.const nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b)) +(assert_return (invoke "f64.abs" (f64.const -nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b)) (assert_return (invoke "f32.neg" (f32.const nan)) (f32.const -nan)) (assert_return (invoke "f32.neg" (f32.const -nan)) (f32.const nan)) -(assert_return (invoke "f32.neg" (f32.const nan(0x0f1e2))) (f32.const -nan(0x0f1e2))) -(assert_return (invoke "f32.neg" (f32.const -nan(0x0f1e2))) (f32.const nan(0x0f1e2))) +(assert_return (invoke "f32.neg" (f32.const nan:0x0f1e2)) (f32.const -nan:0x0f1e2)) +(assert_return (invoke "f32.neg" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f64.neg" (f64.const nan)) (f64.const -nan)) (assert_return (invoke "f64.neg" (f64.const -nan)) (f64.const nan)) -(assert_return (invoke "f64.neg" (f64.const nan(0x0f1e27a6b))) (f64.const -nan(0x0f1e27a6b))) -(assert_return (invoke "f64.neg" (f64.const -nan(0x0f1e27a6b))) (f64.const nan(0x0f1e27a6b))) +(assert_return (invoke "f64.neg" (f64.const nan:0x0f1e27a6b)) (f64.const -nan:0x0f1e27a6b)) +(assert_return (invoke "f64.neg" (f64.const -nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b)) (assert_return (invoke "f32.copysign" (f32.const nan) (f32.const nan)) (f32.const nan)) (assert_return (invoke "f32.copysign" (f32.const nan) (f32.const -nan)) (f32.const -nan)) (assert_return (invoke "f32.copysign" (f32.const -nan) (f32.const nan)) (f32.const nan)) (assert_return (invoke "f32.copysign" (f32.const -nan) (f32.const -nan)) (f32.const -nan)) -(assert_return (invoke "f32.copysign" (f32.const nan(0x0f1e2)) (f32.const nan)) (f32.const nan(0x0f1e2))) -(assert_return (invoke "f32.copysign" (f32.const nan(0x0f1e2)) (f32.const -nan)) (f32.const -nan(0x0f1e2))) -(assert_return (invoke "f32.copysign" (f32.const -nan(0x0f1e2)) (f32.const nan)) (f32.const nan(0x0f1e2))) -(assert_return (invoke "f32.copysign" (f32.const -nan(0x0f1e2)) (f32.const -nan)) (f32.const -nan(0x0f1e2))) +(assert_return (invoke "f32.copysign" (f32.const nan:0x0f1e2) (f32.const nan)) (f32.const nan:0x0f1e2)) +(assert_return (invoke "f32.copysign" (f32.const nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) +(assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const nan)) (f32.const nan:0x0f1e2)) +(assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const -nan)) (f64.const -nan)) (assert_return (invoke "f64.copysign" (f64.const -nan) (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.copysign" (f64.const -nan) (f64.const -nan)) (f64.const -nan)) -(assert_return (invoke "f64.copysign" (f64.const nan(0x0f1e27a6b)) (f64.const nan)) (f64.const nan(0x0f1e27a6b))) -(assert_return (invoke "f64.copysign" (f64.const nan(0x0f1e27a6b)) (f64.const -nan)) (f64.const -nan(0x0f1e27a6b))) -(assert_return (invoke "f64.copysign" (f64.const -nan(0x0f1e27a6b)) (f64.const nan)) (f64.const nan(0x0f1e27a6b))) -(assert_return (invoke "f64.copysign" (f64.const -nan(0x0f1e27a6b)) (f64.const -nan)) (f64.const -nan(0x0f1e27a6b))) +(assert_return (invoke "f64.copysign" (f64.const nan:0x0f1e27a6b) (f64.const nan)) (f64.const nan:0x0f1e27a6b)) +(assert_return (invoke "f64.copysign" (f64.const nan:0x0f1e27a6b) (f64.const -nan)) (f64.const -nan:0x0f1e27a6b)) +(assert_return (invoke "f64.copysign" (f64.const -nan:0x0f1e27a6b) (f64.const nan)) (f64.const nan:0x0f1e27a6b)) +(assert_return (invoke "f64.copysign" (f64.const -nan:0x0f1e27a6b) (f64.const -nan)) (f64.const -nan:0x0f1e27a6b)) ;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest. (assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep-1)) (f32.const 1.0)) From be0c38e3afdb2481f4f20926a53e49aa161b53a6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 6 Nov 2015 11:39:04 -0800 Subject: [PATCH 2/4] Remove redundant parens. --- ml-proto/spec/float.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ml-proto/spec/float.ml b/ml-proto/spec/float.ml index aa2a2f85b2..d57805600f 100644 --- a/ml-proto/spec/float.ml +++ b/ml-proto/spec/float.ml @@ -145,7 +145,7 @@ struct if x <> "nan" && (len > 6) && (String.sub x 0 6) = "nan:0x" then - (let s = Rep.of_string (String.sub x 4 ((len - 4))) in + (let s = Rep.of_string (String.sub x 4 (len - 4)) in if s = Rep.zero then raise (Failure "nan payload must not be zero") else if Rep.logand s bare_nan <> Rep.zero then From fe6c87be88e5dffa0420486016daafb7ecd44956 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Fri, 6 Nov 2015 13:48:56 -0800 Subject: [PATCH 3/4] Add unconditional unreachable expression Add an expression which typechecks in any context, and always traps when executed. --- ml-proto/host/lexer.mll | 1 + ml-proto/host/parser.mly | 3 ++- ml-proto/spec/ast.ml | 1 + ml-proto/spec/check.ml | 3 +++ ml-proto/spec/eval.ml | 3 +++ ml-proto/spec/sugar.ml | 3 +++ ml-proto/spec/sugar.mli | 1 + ml-proto/test/select.wast | 12 ++++++------ ml-proto/test/unreachable.wast | 35 ++++++++++++++++++++++++++++++++++ 9 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 ml-proto/test/unreachable.wast diff --git a/ml-proto/host/lexer.mll b/ml-proto/host/lexer.mll index 357678418a..6f738200b1 100644 --- a/ml-proto/host/lexer.mll +++ b/ml-proto/host/lexer.mll @@ -241,6 +241,7 @@ rule token = parse | (ixx as t)".select" { SELECT ( intop t Int32Op.Select Int64Op.Select) } | (fxx as t)".select" { SELECT ( floatop t Float32Op.Select Float64Op.Select) } + | "unreachable" { UNREACHABLE } | "page_size" { PAGE_SIZE } | "memory_size" { MEMORY_SIZE } | "grow_memory" { GROW_MEMORY } diff --git a/ml-proto/host/parser.mly b/ml-proto/host/parser.mly index 8f097b94bb..a5bdd9fc91 100644 --- a/ml-proto/host/parser.mly +++ b/ml-proto/host/parser.mly @@ -159,7 +159,7 @@ let implicit_decl c t at = %token CONST UNARY BINARY COMPARE CONVERT %token FUNC TYPE PARAM RESULT LOCAL %token MODULE MEMORY SEGMENT IMPORT EXPORT TABLE -%token PAGE_SIZE MEMORY_SIZE GROW_MEMORY HAS_FEATURE +%token UNREACHABLE PAGE_SIZE MEMORY_SIZE GROW_MEMORY HAS_FEATURE %token ASSERT_INVALID ASSERT_RETURN ASSERT_RETURN_NAN ASSERT_TRAP INVOKE %token EOF @@ -283,6 +283,7 @@ expr1 : | COMPARE expr expr { fun c -> compare ($1, $2 c, $3 c) } | CONVERT expr { fun c -> convert ($1, $2 c) } | SELECT expr expr expr { fun c -> select ($1, $2 c, $3 c, $4 c) } + | UNREACHABLE { fun c -> unreachable } | PAGE_SIZE { fun c -> host (PageSize, []) } | MEMORY_SIZE { fun c -> host (MemorySize, []) } | GROW_MEMORY expr { fun c -> host (GrowMemory, [$2 c]) } diff --git a/ml-proto/spec/ast.ml b/ml-proto/spec/ast.ml index f153a25c13..155e577930 100644 --- a/ml-proto/spec/ast.ml +++ b/ml-proto/spec/ast.ml @@ -104,6 +104,7 @@ and expr' = | Compare of relop * expr * expr (* arithmetic comparison *) | Convert of cvt * expr (* conversion *) | Select of selectop * expr * expr * expr (* branchless conditional *) + | Unreachable (* trap *) | Host of hostop * expr list (* host interaction *) and case = case' Source.phrase diff --git a/ml-proto/spec/check.ml b/ml-proto/spec/check.ml index 574e877eba..edc31850b8 100644 --- a/ml-proto/spec/check.ml +++ b/ml-proto/spec/check.ml @@ -218,6 +218,9 @@ let rec check_expr c et e = check_expr c (Some t) e2; check_expr c (Some t) e3 + | Unreachable -> + check_type None None e.at + | Host (hostop, es) -> let ({ins; out}, hasmem) = type_hostop hostop in if hasmem then diff --git a/ml-proto/spec/eval.ml b/ml-proto/spec/eval.ml index efe9e7caf8..c079e61659 100644 --- a/ml-proto/spec/eval.ml +++ b/ml-proto/spec/eval.ml @@ -250,6 +250,9 @@ let rec eval_expr (c : config) (e : expr) = let v2 = some (eval_expr c e3) e3.at in Some (if cond <> Int32.zero then v1 else v2) + | Unreachable -> + Trap.error e.at "unreachable executed" + | Host (hostop, es) -> let vs = List.map (eval_expr c) es in eval_hostop c hostop vs e.at diff --git a/ml-proto/spec/sugar.ml b/ml-proto/spec/sugar.ml index 7e0ad43c55..ff0cef20bb 100644 --- a/ml-proto/spec/sugar.ml +++ b/ml-proto/spec/sugar.ml @@ -88,6 +88,9 @@ let convert (cvt, e) = let select (selectop, cond, e1, e2) = Select (selectop, cond, e1, e2) +let unreachable = + Unreachable + let host (hostop, es) = Host (hostop, es) diff --git a/ml-proto/spec/sugar.mli b/ml-proto/spec/sugar.mli index c3bc82a0a8..721790e781 100644 --- a/ml-proto/spec/sugar.mli +++ b/ml-proto/spec/sugar.mli @@ -26,6 +26,7 @@ val binary : binop * expr * expr -> expr' val compare : relop * expr * expr -> expr' val convert : cvt * expr -> expr' val select : selectop * expr * expr * expr -> expr' +val unreachable : expr' val host : hostop * expr list -> expr' val case : literal * (expr list * bool) option -> case' diff --git a/ml-proto/test/select.wast b/ml-proto/test/select.wast index d242cbd870..d5b0994864 100644 --- a/ml-proto/test/select.wast +++ b/ml-proto/test/select.wast @@ -13,9 +13,9 @@ ;; Check that both sides of the select are evaluated (func $select_trap_l (param $cond i32) (result i32) - (i32.select (get_local $cond) (i32.div_s (i32.const 1)(i32.const 0)) (i32.const 0))) + (i32.select (get_local $cond) (unreachable) (i32.const 0))) (func $select_trap_r (param $cond i32) (result i32) - (i32.select (get_local $cond) (i32.const 0) (i32.div_s (i32.const 1)(i32.const 0)))) + (i32.select (get_local $cond) (i32.const 0) (unreachable))) (export "select_i32" $select_i32) (export "select_i64" $select_i64) @@ -41,7 +41,7 @@ (assert_return_nan (invoke "select_f64" (i32.const 1) (f64.const nan) (f64.const 1))) (assert_return_nan (invoke "select_f64" (i32.const 0) (f64.const 2) (f64.const nan))) -(assert_trap (invoke "select_trap_l" (i32.const 1)) "integer divide by zero") -(assert_trap (invoke "select_trap_l" (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "select_trap_r" (i32.const 1)) "integer divide by zero") -(assert_trap (invoke "select_trap_r" (i32.const 0)) "integer divide by zero") \ No newline at end of file +(assert_trap (invoke "select_trap_l" (i32.const 1)) "unreachable executed") +(assert_trap (invoke "select_trap_l" (i32.const 0)) "unreachable executed") +(assert_trap (invoke "select_trap_r" (i32.const 1)) "unreachable executed") +(assert_trap (invoke "select_trap_r" (i32.const 0)) "unreachable executed") diff --git a/ml-proto/test/unreachable.wast b/ml-proto/test/unreachable.wast new file mode 100644 index 0000000000..a895aec37a --- /dev/null +++ b/ml-proto/test/unreachable.wast @@ -0,0 +1,35 @@ +(module + (func $return_i32 (result i32) + (unreachable)) + (func $return_f64 (result f64) + (unreachable)) + + (func $if (param i32) (result f32) + (if (get_local 0) (unreachable) (f32.const 0))) + + (func $block + (block (i32.const 1) (unreachable) (i32.const 2))) + + (func $return_i64 (result i64) + (return (i64.const 1)) + (unreachable)) + + (func $call (result f64) + (call $return_i32) + (unreachable)) + + (export "return_i32" $return_i32) + (export "return_f64" $return_f64) + (export "if" $if) + (export "block" $block) + (export "return_i64" $return_i64) + (export "call" $call) +) + +(assert_trap (invoke "return_i32") "unreachable executed") +(assert_trap (invoke "return_f64") "unreachable executed") +(assert_trap (invoke "if" (i32.const 1)) "unreachable executed") +(assert_return (invoke "if" (i32.const 0)) (f32.const 0)) +(assert_trap (invoke "block") "unreachable executed") +(assert_return (invoke "return_i64") (i64.const 1)) +(assert_trap (invoke "call") "unreachable executed") From f0a05827d55062d109dc10dbe8b9863286fed040 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Mon, 9 Nov 2015 09:47:13 -0800 Subject: [PATCH 4/4] Do nothing more simply for Unreachable type check --- ml-proto/spec/check.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ml-proto/spec/check.ml b/ml-proto/spec/check.ml index edc31850b8..a82c92717f 100644 --- a/ml-proto/spec/check.ml +++ b/ml-proto/spec/check.ml @@ -219,7 +219,7 @@ let rec check_expr c et e = check_expr c (Some t) e3 | Unreachable -> - check_type None None e.at + () | Host (hostop, es) -> let ({ins; out}, hasmem) = type_hostop hostop in