Skip to content

Commit 1888885

Browse files
committed
Merge pull request #74 from WebAssembly/add-assert-fault
Add assert_fault script command
2 parents 823b4c1 + 8fef105 commit 1888885

File tree

7 files changed

+49
-13
lines changed

7 files changed

+49
-13
lines changed

ml-proto/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,11 @@ In order to be able to check and run modules for testing purposes, the S-express
226226
script: <cmd>*
227227
228228
cmd:
229-
<module> ;; define, validate, and initialize module
230-
( invoke <name> <expr>* ) ;; invoke export and print result
231-
( assert_eq (invoke <name> <expr>* ) <expr> ) ;; assert expected results of invocation
232-
( assert_invalid <module> <failure> ) ;; assert invalid module with given failure string
229+
<module> ;; define, validate, and initialize module
230+
( invoke <name> <expr>* ) ;; invoke export and print result
231+
( assert_eq (invoke <name> <expr>* ) <expr> ) ;; assert expected results of invocation
232+
( assert_fault (invoke <name> <expr>* ) <failure> ) ;; assert invocation faults with given failure string
233+
( assert_invalid <module> <failure> ) ;; assert invalid module with given failure string
233234
```
234235

235236
Invocation is only possible after a module has been defined.

ml-proto/src/host/lexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ rule token = parse
249249

250250
| "assert_invalid" { ASSERTINVALID }
251251
| "assert_eq" { ASSERTEQ }
252+
| "assert_fault" { ASSERTFAULT }
252253
| "invoke" { INVOKE }
253254

254255
| name as s { VAR s }

ml-proto/src/host/parser.mly

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ let anon_label c = {c with labels = VarMap.map ((+) 1) c.labels}
103103
%token GETLOCAL SETLOCAL LOADGLOBAL STOREGLOBAL LOAD STORE
104104
%token CONST UNARY BINARY COMPARE CONVERT
105105
%token FUNC PARAM RESULT LOCAL MODULE MEMORY SEGMENT GLOBAL IMPORT EXPORT TABLE
106-
%token ASSERTINVALID ASSERTEQ INVOKE
106+
%token ASSERTINVALID ASSERTEQ ASSERTFAULT INVOKE
107107
%token EOF
108108

109109
%token<string> INT
@@ -348,6 +348,8 @@ cmd :
348348
{ Invoke ($3, $4 (c0 ())) @@ at() }
349349
| LPAR ASSERTEQ LPAR INVOKE TEXT expr_list RPAR expr RPAR
350350
{ AssertEq ($5, $6 (c0 ()), $8 (c0 ())) @@ at() }
351+
| LPAR ASSERTFAULT LPAR INVOKE TEXT expr_list RPAR TEXT RPAR
352+
{ AssertFault ($5, $6 (c0 ()), $8) @@ at() }
351353
;
352354
cmd_list :
353355
| /* empty */ { [] }

ml-proto/src/host/print.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ let print_value vo =
7373
(Values.string_of_value v) (Types.string_of_value_type t);
7474
flush_all ()
7575
| None ->
76-
printf "()";
76+
printf "()\n";
7777
flush_all ()
7878

ml-proto/src/host/script.ml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and command' =
1212
| AssertInvalid of Ast.modul * string
1313
| Invoke of string * Ast.expr list
1414
| AssertEq of string * Ast.expr list * Ast.expr
15+
| AssertFault of string * Ast.expr list * string
1516

1617
type script = command list
1718

@@ -29,6 +30,14 @@ let eval_args es at =
2930
| None -> Error.error at "unexpected () value" in
3031
List.map reject_none evs
3132

33+
let assert_error f err re at =
34+
match f () with
35+
| exception Error.Error (_, s) ->
36+
if not (Str.string_match (Str.regexp re) s 0) then
37+
Error.error at ("failure \"" ^ s ^ "\" does not match: \"" ^ re ^ "\"")
38+
| _ ->
39+
Error.error at ("expected " ^ err)
40+
3241
let run_command cmd =
3342
match cmd.it with
3443
| Define m ->
@@ -44,13 +53,7 @@ let run_command cmd =
4453

4554
| AssertInvalid (m, re) ->
4655
trace "Checking invalid...";
47-
(match try Check.check_module m; None with Error.Error (_, s) -> Some s with
48-
| None ->
49-
Error.error cmd.at "expected invalid module"
50-
| Some s ->
51-
if not (Str.string_match (Str.regexp re) s 0) then
52-
Error.error cmd.at
53-
("validation failure \"" ^ s ^ "\" does not match: \"" ^ re ^ "\""))
56+
assert_error (fun () -> Check.check_module m) "invalid module" re cmd.at
5457

5558
| Invoke (name, es) ->
5659
trace "Invoking...";
@@ -79,6 +82,15 @@ let run_command cmd =
7982
Error.error cmd.at "assertion failed"
8083
end
8184

85+
| AssertFault (name, es, re) ->
86+
trace "Assert fault invoking...";
87+
let m = match !current_module with
88+
| Some m -> m
89+
| None -> Error.error cmd.at "no module defined to invoke"
90+
in
91+
let vs = eval_args es cmd.at in
92+
assert_error (fun () -> Eval.invoke m name vs) "fault" re cmd.at
93+
8294
let dry_command cmd =
8395
match cmd.it with
8496
| Define m ->
@@ -87,6 +99,7 @@ let dry_command cmd =
8799
| AssertInvalid _ -> ()
88100
| Invoke _ -> ()
89101
| AssertEq _ -> ()
102+
| AssertFault _ -> ()
90103

91104
let run script =
92105
List.iter (if !Flags.dry then dry_command else run_command) script

ml-proto/src/host/script.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and command' =
88
| AssertInvalid of Ast.modul * string
99
| Invoke of string * Ast.expr list
1010
| AssertEq of string * Ast.expr list * Ast.expr
11+
| AssertFault of string * Ast.expr list * string
1112

1213
type script = command list
1314

ml-proto/test/memory_fault.wasm

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
(module
2+
(memory 100)
3+
4+
(export "store" $store)
5+
(func $store (param $i i32) (param $v i32) (i32.store (get_local $i) (get_local $v)))
6+
7+
(export "load" $load)
8+
(func $load (param $i i32) (result i32) (i32.load (get_local $i)))
9+
)
10+
11+
(invoke "store" (i32.const 96) (i32.const 42))
12+
(assert_eq (invoke "load" (i32.const 96)) (i32.const 42))
13+
(assert_fault (invoke "store" (i32.const 97) (i32.const 13)) "runtime: out of bounds memory access")
14+
(assert_fault (invoke "load" (i32.const 97)) "runtime: out of bounds memory access")
15+
(assert_fault (invoke "store" (i32.const 98) (i32.const 13)) "runtime: out of bounds memory access")
16+
(assert_fault (invoke "load" (i32.const 98)) "runtime: out of bounds memory access")
17+
(assert_fault (invoke "store" (i32.const 99) (i32.const 13)) "runtime: out of bounds memory access")
18+
(assert_fault (invoke "load" (i32.const 99)) "runtime: out of bounds memory access")

0 commit comments

Comments
 (0)