Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Commit 1671a38

Browse files
authored
[Interpreter] Handle 0-byte copies properly. (#61)
Similar to the MVP, a 0-byte access at the end of the region is legal.
1 parent 63986ff commit 1671a38

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

interpreter/runtime/memory.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,16 @@ let store_packed sz mem a o v =
145145
| _ -> raise Type
146146
in storen mem a o n x
147147

148-
let check_bounds mem a = if I64.ge_u a (bound mem) then raise Bounds
148+
let check_bounds mem a = if I64.gt_u a (bound mem) then raise Bounds
149149

150150
let fill mem a v n =
151151
let rec loop a n =
152152
if n > 0l then begin
153153
store_byte mem a v;
154154
loop (Int64.add a 1L) (Int32.sub n 1l)
155155
end
156-
in check_bounds mem a; loop a n
156+
in loop a n;
157+
check_bounds mem Int64.(add a (of_int32 n))
157158

158159
let copy mem d s n =
159160
let n' = Int64.of_int32 n in
@@ -163,10 +164,9 @@ let copy mem d s n =
163164
store_byte mem d (load_byte mem s);
164165
loop (Int64.add d dx) (Int64.add s dx) (Int32.sub n 1l) dx
165166
end
166-
in
167-
check_bounds mem d;
168-
check_bounds mem s;
169-
if overlap && s < d then
167+
in (if overlap && s < d then
170168
loop Int64.(add d (sub n' 1L)) Int64.(add s (sub n' 1L)) n (-1L)
171169
else
172-
loop d s n 1L
170+
loop d s n 1L);
171+
check_bounds mem (Int64.add d n');
172+
check_bounds mem (Int64.add s n')

test/core/bulk.wast

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
(assert_return (invoke "load8_u" (i32.const 0xff00)) (i32.const 1))
3434
(assert_return (invoke "load8_u" (i32.const 0xffff)) (i32.const 1))
3535

36-
;; Fail on out-of-bounds even if filling 0 bytes.
37-
(assert_trap (invoke "fill" (i32.const 0x10000) (i32.const 0) (i32.const 0))
36+
;; Succeed when writing 0 bytes at the end of the region.
37+
(invoke "fill" (i32.const 0x10000) (i32.const 0) (i32.const 0))
38+
39+
;; Fail on out-of-bounds when writing 0 bytes outside of memory.
40+
(assert_trap (invoke "fill" (i32.const 0x10001) (i32.const 0) (i32.const 0))
3841
"out of bounds memory access")
3942

4043

@@ -90,8 +93,12 @@
9093
(assert_return (invoke "load8_u" (i32.const 0xfffe)) (i32.const 0xaa))
9194
(assert_return (invoke "load8_u" (i32.const 0xffff)) (i32.const 0xbb))
9295

93-
;; Fail on out-of-bounds even if copying 0 bytes.
94-
(assert_trap (invoke "copy" (i32.const 0x10000) (i32.const 0) (i32.const 0))
96+
;; Succeed when copying 0 bytes at the end of the region.
97+
(invoke "copy" (i32.const 0x10000) (i32.const 0) (i32.const 0))
98+
(invoke "copy" (i32.const 0) (i32.const 0x10000) (i32.const 0))
99+
100+
;; Fail on out-of-bounds when copying 0 bytes outside of memory.
101+
(assert_trap (invoke "copy" (i32.const 0x10001) (i32.const 0) (i32.const 0))
95102
"out of bounds memory access")
96-
(assert_trap (invoke "copy" (i32.const 0) (i32.const 0x10000) (i32.const 0))
103+
(assert_trap (invoke "copy" (i32.const 0) (i32.const 0x10001) (i32.const 0))
97104
"out of bounds memory access")

0 commit comments

Comments
 (0)