Skip to content

Commit

Permalink
Merge pull request #103 from WebAssembly/runaway-recursion
Browse files Browse the repository at this point in the history
Handle interpreter stack overflow, and test runaway recursion.
  • Loading branch information
sunfishcode committed Oct 8, 2015
2 parents 9a7fc7b + 45673f5 commit a39ea85
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ml-proto/TestingTodo.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ welcome.
Misc semantics:
- test that linear memory is little-endian for all integers and floats
- test that unaligned and misaligned accesses work, even if slow
- test that runaway recursion traps
- ~~test that runaway recursion traps~~
- test that too-big linear memory resize fails appropriately
- test that too-big linear memory initial allocation fails
- test that function addresses are monotonic indices, and not actual addresses.
Expand Down
11 changes: 8 additions & 3 deletions ml-proto/spec/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ let mem_size v at =
let i64 = Int64.of_int32 i32 in
Int64.shift_right_logical (Int64.shift_left i64 32) 32

let callstack_exhaustion at =
error at ("runtime: callstack exhausted")


(* Evaluation *)

Expand Down Expand Up @@ -296,9 +299,11 @@ let init m imports host =
{funcs; imports; exports; tables; memory = memory'; host}

let invoke m name vs =
let f = export m (name @@ no_region) in
assert (List.length vs = List.length f.it.params);
eval_func m f vs
try
let f = export m (name @@ no_region) in
assert (List.length vs = List.length f.it.params);
eval_func m f vs
with Stack_overflow -> callstack_exhaustion no_region

(* This function is not part of the spec. *)
let host_eval e =
Expand Down
1 change: 1 addition & 0 deletions ml-proto/test/fac.wast
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@
(assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776))
(assert_trap (invoke "fac-rec" (i64.const 1073741824)) "runtime: callstack exhausted")
17 changes: 17 additions & 0 deletions ml-proto/test/runaway-recursion.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(module
;; Implementations are required to have every call consume some abstract
;; resource towards exhausting some abstract finite limit, such that
;; infinitely recursive testcases reliably trap in finite time. This is
;; because otherwise applications could come to depend on it on those
;; implementations and be incompatible with implementations that don't do
;; it (or don't do it under the same circumstances).
(func (call 0))
(export "runaway" 0)

(func $a (call $b))
(func $b (call $a))
(export "mutual_runaway" $a)
)

(assert_trap (invoke "runaway") "runtime: callstack exhausted")
(assert_trap (invoke "mutual_runaway") "runtime: callstack exhausted")

0 comments on commit a39ea85

Please sign in to comment.