summaryrefslogtreecommitdiff
path: root/test/lit/exec/fuzzing-api.wast
blob: eae95fc0a87a169883f5c7151c03b2cf9d9e8b8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.

;; RUN: wasm-opt %s -all --fuzz-exec -o /dev/null 2>&1 | filecheck %s

;; Test the fuzzing-support module imports.

(module
 (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
 (import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))

 (import "fuzzing-support" "throw" (func $throw))

 (import "fuzzing-support" "table-set" (func $table.set (param i32 funcref)))
 (import "fuzzing-support" "table-get" (func $table.get (param i32) (result funcref)))

 (import "fuzzing-support" "call-export" (func $call.export (param i32)))
 (import "fuzzing-support" "call-export-catch" (func $call.export.catch (param i32) (result i32)))

 (import "fuzzing-support" "call-ref" (func $call.ref (param funcref)))
 (import "fuzzing-support" "call-ref-catch" (func $call.ref.catch (param funcref) (result i32)))

 (table $table 10 20 funcref)

 ;; Note that the exported table appears first here, but in the binary and in
 ;; the IR it is actually last, as we always add function exports first.
 (export "table" (table $table))

 ;; CHECK:      [fuzz-exec] calling logging
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 (func $logging (export "logging")
  (call $log-i32
   (i32.const 42)
  )
  (call $log-f64
   (f64.const 3.14159)
  )
 )

 ;; CHECK:      [fuzz-exec] calling throwing
 ;; CHECK-NEXT: [exception thrown: __private ()]
 (func $throwing (export "throwing")
  (call $throw)
 )

 ;; CHECK:      [fuzz-exec] calling table.setting
 ;; CHECK-NEXT: [exception thrown: __private ()]
 (func $table.setting (export "table.setting")
  (call $table.set
   (i32.const 5)
   (ref.func $table.setting)
  )
  ;; Out of bounds sets will throw.
  (call $table.set
   (i32.const 9999)
   (ref.func $table.setting)
  )
 )

 ;; CHECK:      [fuzz-exec] calling table.getting
 ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 ;; CHECK-NEXT: [exception thrown: __private ()]
 (func $table.getting (export "table.getting")
  ;; There is a non-null value at 5, and a null at 6.
  (call $log-i32
   (ref.is_null
    (call $table.get
     (i32.const 5)
    )
   )
  )
  (call $log-i32
   (ref.is_null
    (call $table.get
     (i32.const 6)
    )
   )
  )
  ;; Out of bounds gets will throw.
  (drop
   (call $table.get
    (i32.const 9999)
   )
  )
 )

 ;; CHECK:      [fuzz-exec] calling export.calling
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 ;; CHECK-NEXT: [exception thrown: __private ()]
 (func $export.calling (export "export.calling")
  ;; At index 0 in the exports we have $logging, so we will do those loggings.
  (call $call.export
   (i32.const 0)
  )
  ;; At index 999 we have nothing, so we'll error.
  (call $call.export
   (i32.const 999)
  )
 )

 ;; CHECK:      [fuzz-exec] calling export.calling.catching
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 (func $export.calling.catching (export "export.calling.catching")
  ;; At index 0 in the exports we have $logging, so we will do those loggings,
  ;; then log a 0 as no exception happens.
  (call $log-i32
   (call $call.export.catch
    (i32.const 0)
   )
  )
  ;; At index 999 we have nothing, so we'll error, catch it, and log 1.
  (call $log-i32
   (call $call.export.catch
    (i32.const 999)
   )
  )
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 ;; CHECK-NEXT: [exception thrown: __private ()]
 (func $ref.calling (export "ref.calling")
  ;; This will emit some logging.
  (call $call.ref
   (ref.func $logging)
  )
  ;; This will throw.
  (call $call.ref
   (ref.null func)
  )
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.catching
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 (func $ref.calling.catching (export "ref.calling.catching")
  ;; This will emit some logging, then log 0 as we do not error.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $logging)
   )
  )
  ;; The exception here is caught, and we'll log 1.
  (call $log-i32
   (call $call.ref.catch
    (ref.null func)
   )
  )
 )

 (func $legal (param $x i32) (result i32)
  ;; Helper for the function below. All types here are legal for JS.
  (call $log-i32
   (i32.const 12)
  )
  ;; Also log the param to show it is 0, which is what $call.ref does for all
  ;; params.
  (call $log-i32
   (local.get $x)
  )
  (i32.const 34)
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.legal
 ;; CHECK-NEXT: [LoggingExternalInterface logging 12]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
 (func $ref.calling.legal (export "ref.calling.legal")
  ;; It is fine to call-ref a function with params and results. The params get
  ;; default values, and the results are ignored. All we will see here is the
  ;; logging from the function, "12".
  (call $call.ref
   (ref.func $legal)
  )
 )

 (func $illegal (param $x i64)
  ;; Helper for the function below. The param, an i64, causes a problem: when we
  ;; call from JS we provide 0, but 0 throws when it tries to convert to BigInt.
  (call $log-i32
   (i32.const 56)
  )
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.illegal
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 (func $ref.calling.illegal (export "ref.calling.illegal")
  ;; The i64 param causes an error here, so we will only log 1 because we catch an exception.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $illegal)
   )
  )
 )

 (func $illegal-v128 (param $x v128)
  ;; Helper for the function below.
  (call $log-i32
   (i32.const 56)
  )
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.illegal-v128
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 (func $ref.calling.illegal-v128 (export "ref.calling.illegal-v128")
  ;; As above, we throw on the v128 param, and log 1.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $illegal-v128)
   )
  )
 )

 (func $illegal-result (result v128)
  ;; Helper for the function below. The result is illegal for JS.
  (call $log-i32
   (i32.const 910)
  )
  (v128.const i32x4 1 2 3 4)
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.illegal-result
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 (func $ref.calling.illegal-result (export "ref.calling.illegal-result")
  ;; The v128 result causes an error here, so we will log 1 as an exception. The JS
  ;; semantics determine that we do that check *before* the call, so the logging
  ;; of 910 does not go through.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $illegal-result)
   )
  )
 )

 (func $legal-result (result i64)
  ;; Helper for the function below.
  (call $log-i32
   (i32.const 910)
  )
  (i64.const 90)
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.legal-result
 ;; CHECK-NEXT: [LoggingExternalInterface logging 910]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
 (func $ref.calling.legal-result (export "ref.calling.legal-result")
  ;; Unlike v128, i64 is legal in a result. The JS VM just returns a BigInt.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $legal-result)
   )
  )
 )

 (func $trap
  ;; Helper for the function below.
  (unreachable)
 )

 ;; CHECK:      [fuzz-exec] calling ref.calling.trap
 ;; CHECK-NEXT: [trap unreachable]
 ;; CHECK-NEXT: warning: no passes specified, not doing any work
 (func $ref.calling.trap (export "ref.calling.trap")
  ;; We try to catch an exception here, but the target function traps, which is
  ;; not something we can catch. We will trap here, and not log at all.
  (call $log-i32
   (call $call.ref.catch
    (ref.func $trap)
   )
  )
 )
)
;; CHECK:      [fuzz-exec] calling logging
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]

;; CHECK:      [fuzz-exec] calling throwing
;; CHECK-NEXT: [exception thrown: __private ()]

;; CHECK:      [fuzz-exec] calling table.setting
;; CHECK-NEXT: [exception thrown: __private ()]

;; CHECK:      [fuzz-exec] calling table.getting
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK-NEXT: [exception thrown: __private ()]

;; CHECK:      [fuzz-exec] calling export.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]

;; CHECK:      [fuzz-exec] calling export.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]

;; CHECK:      [fuzz-exec] calling ref.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]

;; CHECK:      [fuzz-exec] calling ref.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]

;; CHECK:      [fuzz-exec] calling ref.calling.legal
;; CHECK-NEXT: [LoggingExternalInterface logging 12]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]

;; CHECK:      [fuzz-exec] calling ref.calling.illegal
;; CHECK-NEXT: [LoggingExternalInterface logging 1]

;; CHECK:      [fuzz-exec] calling ref.calling.illegal-v128
;; CHECK-NEXT: [LoggingExternalInterface logging 1]

;; CHECK:      [fuzz-exec] calling ref.calling.illegal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 1]

;; CHECK:      [fuzz-exec] calling ref.calling.legal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 910]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]

;; CHECK:      [fuzz-exec] calling ref.calling.trap
;; CHECK-NEXT: [trap unreachable]
;; CHECK-NEXT: [fuzz-exec] comparing export.calling
;; CHECK-NEXT: [fuzz-exec] comparing export.calling.catching
;; CHECK-NEXT: [fuzz-exec] comparing logging
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.catching
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-result
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-v128
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal-result
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.trap
;; CHECK-NEXT: [fuzz-exec] comparing table.getting
;; CHECK-NEXT: [fuzz-exec] comparing table.setting
;; CHECK-NEXT: [fuzz-exec] comparing throwing