1;;! bulk_memory = true
2
3(module $foreign
4  (memory (export "mem") 1 1)
5  (data 0 (i32.const 1000) "hello")
6  (data 0 (i32.const 2000) "olleh"))
7
8(register "foreign" $foreign)
9
10(module
11  (memory (import "foreign" "mem") 1 1)
12
13  (func $is_char (param i32 i32) (result i32)
14    local.get 0
15    i32.load8_u
16    local.get 1
17    i32.eq)
18
19  (func (export "is hello?") (param i32) (result i32)
20    local.get 0
21    i32.const 104 ;; 'h'
22    call $is_char
23
24    local.get 0
25    i32.const 1
26    i32.add
27    i32.const 101 ;; 'e'
28    call $is_char
29
30    local.get 0
31    i32.const 2
32    i32.add
33    i32.const 108 ;; 'l'
34    call $is_char
35
36    local.get 0
37    i32.const 3
38    i32.add
39    i32.const 108 ;; 'l'
40    call $is_char
41
42    local.get 0
43    i32.const 4
44    i32.add
45    i32.const 111 ;; 'o'
46    call $is_char
47
48    i32.and
49    i32.and
50    i32.and
51    i32.and
52  )
53
54  (func (export "is olleh?") (param i32) (result i32)
55    local.get 0
56    i32.const 111 ;; 'o'
57    call $is_char
58
59    local.get 0
60    i32.const 1
61    i32.add
62    i32.const 108 ;; 'l'
63    call $is_char
64
65    local.get 0
66    i32.const 2
67    i32.add
68    i32.const 108 ;; 'l'
69    call $is_char
70
71    local.get 0
72    i32.const 3
73    i32.add
74    i32.const 101 ;; 'e'
75    call $is_char
76
77    local.get 0
78    i32.const 4
79    i32.add
80    i32.const 104 ;; 'h'
81    call $is_char
82
83    i32.and
84    i32.and
85    i32.and
86    i32.and
87  )
88
89  (func (export "memory.copy") (param i32 i32 i32)
90    local.get 0
91    local.get 1
92    local.get 2
93    memory.copy))
94
95;; Our memory has our initial data in the right places.
96(assert_return
97  (invoke "is hello?" (i32.const 1000))
98  (i32.const 1))
99(assert_return
100  (invoke "is olleh?" (i32.const 2000))
101  (i32.const 1))
102
103;; Non-overlapping memory copy with dst < src.
104(invoke "memory.copy" (i32.const 500) (i32.const 1000) (i32.const 5))
105(assert_return
106  (invoke "is hello?" (i32.const 500))
107  (i32.const 1))
108
109;; Non-overlapping memory copy with dst > src.
110(invoke "memory.copy" (i32.const 1500) (i32.const 1000) (i32.const 5))
111(assert_return
112  (invoke "is hello?" (i32.const 1500))
113  (i32.const 1))
114
115;; Overlapping memory copy with dst < src.
116(invoke "memory.copy" (i32.const 1998) (i32.const 2000) (i32.const 5))
117(assert_return
118  (invoke "is olleh?" (i32.const 1998))
119  (i32.const 1))
120
121;; Overlapping memory copy with dst > src.
122(invoke "memory.copy" (i32.const 2000) (i32.const 1998) (i32.const 5))
123(assert_return
124  (invoke "is olleh?" (i32.const 2000))
125  (i32.const 1))
126
127;; Overlapping memory copy with dst = src.
128(invoke "memory.copy" (i32.const 2000) (i32.const 2000) (i32.const 5))
129(assert_return
130  (invoke "is olleh?" (i32.const 2000))
131  (i32.const 1))
132