validation.js (9372B)
1 // |jit-test| skip-if: !wasmSimdEnabled() 2 3 function testValid(code) { 4 assertEq(WebAssembly.validate(wasmTextToBinary(code)), true); 5 } 6 7 function testInvalid(code) { 8 assertEq(WebAssembly.validate(wasmTextToBinary(code)), false); 9 } 10 11 // v128 -> v128 12 13 for (let op of [ 14 'i8x16.neg', 15 'i8x16.abs', 16 'i16x8.neg', 17 'i16x8.abs', 18 'i16x8.extend_low_i8x16_s', 19 'i16x8.extend_high_i8x16_s', 20 'i16x8.extend_low_i8x16_u', 21 'i16x8.extend_high_i8x16_u', 22 'i32x4.neg', 23 'i32x4.abs', 24 'i32x4.extend_low_i16x8_s', 25 'i32x4.extend_high_i16x8_s', 26 'i32x4.extend_low_i16x8_u', 27 'i32x4.extend_high_i16x8_u', 28 'i32x4.trunc_sat_f32x4_s', 29 'i32x4.trunc_sat_f32x4_u', 30 'i64x2.neg', 31 'f32x4.abs', 32 'f32x4.neg', 33 'f32x4.sqrt', 34 'f32x4.convert_i32x4_s', 35 'f32x4.convert_i32x4_s', 36 'f64x2.abs', 37 'f64x2.neg', 38 'f64x2.sqrt', 39 'v128.not']) 40 { 41 testValid(`(module 42 (func (param v128) (result v128) 43 (${op} (local.get 0))))`); 44 } 45 46 for (let [prefix, result, suffix] of [['i8x16', 'i32', '_s'], 47 ['i8x16', 'i32', '_u'], 48 ['i16x8', 'i32', '_s'], 49 ['i16x8', 'i32', '_u'], 50 ['i32x4', 'i32', ''], 51 ['i64x2', 'i64', ''], 52 ['f32x4', 'f32', ''], 53 ['f64x2', 'f64', '']]) 54 { 55 testValid(`(module 56 (func (param v128) (result ${result}) 57 (${prefix}.extract_lane${suffix} 1 (local.get 0))))`); 58 } 59 60 // The wat parser accepts small out-of-range lane indices, but they must be 61 // caught in validation. 62 63 testInvalid( 64 `(module 65 (func (param v128) (result i32) 66 (i8x16.extract_lane_u 16 (local.get 0))))`); 67 68 // (v128, v128) -> v128 69 70 for (let op of [ 71 'i8x16.eq', 72 'i8x16.ne', 73 'i8x16.lt_s', 74 'i8x16.lt_u', 75 'i8x16.gt_s', 76 'i8x16.gt_u', 77 'i8x16.le_s', 78 'i8x16.le_u', 79 'i8x16.ge_s', 80 'i8x16.ge_u', 81 'i16x8.eq', 82 'i16x8.ne', 83 'i16x8.lt_s', 84 'i16x8.lt_u', 85 'i16x8.gt_s', 86 'i16x8.gt_u', 87 'i16x8.le_s', 88 'i16x8.le_u', 89 'i16x8.ge_s', 90 'i16x8.ge_u', 91 'i32x4.eq', 92 'i32x4.ne', 93 'i32x4.lt_s', 94 'i32x4.lt_u', 95 'i32x4.gt_s', 96 'i32x4.gt_u', 97 'i32x4.le_s', 98 'i32x4.le_u', 99 'i32x4.ge_s', 100 'i32x4.ge_u', 101 'f32x4.eq', 102 'f32x4.ne', 103 'f32x4.lt', 104 'f32x4.gt', 105 'f32x4.le', 106 'f32x4.ge', 107 'f64x2.eq', 108 'f64x2.ne', 109 'f64x2.lt', 110 'f64x2.gt', 111 'f64x2.le', 112 'f64x2.ge', 113 'v128.and', 114 'v128.or', 115 'v128.xor', 116 'v128.andnot', 117 'i8x16.avgr_u', 118 'i16x8.avgr_u', 119 'i8x16.add', 120 'i8x16.add_sat_s', 121 'i8x16.add_sat_u', 122 'i8x16.sub', 123 'i8x16.sub_sat_s', 124 'i8x16.sub_sat_u', 125 'i8x16.min_s', 126 'i8x16.max_s', 127 'i8x16.min_u', 128 'i8x16.max_u', 129 'i16x8.add', 130 'i16x8.add_sat_s', 131 'i16x8.add_sat_u', 132 'i16x8.sub', 133 'i16x8.sub_sat_s', 134 'i16x8.sub_sat_u', 135 'i16x8.mul', 136 'i16x8.min_s', 137 'i16x8.max_s', 138 'i16x8.min_u', 139 'i16x8.max_u', 140 'i32x4.add', 141 'i32x4.sub', 142 'i32x4.mul', 143 'i32x4.min_s', 144 'i32x4.max_s', 145 'i32x4.min_u', 146 'i32x4.max_u', 147 'i64x2.add', 148 'i64x2.sub', 149 'i64x2.mul', 150 'f32x4.add', 151 'f32x4.sub', 152 'f32x4.mul', 153 'f32x4.div', 154 'f32x4.min', 155 'f32x4.max', 156 'f64x2.add', 157 'f64x2.sub', 158 'f64x2.mul', 159 'f64x2.div', 160 'f64x2.min', 161 'f64x2.max', 162 'i8x16.narrow_i16x8_s', 163 'i8x16.narrow_i16x8_u', 164 'i16x8.narrow_i32x4_s', 165 'i16x8.narrow_i32x4_u', 166 'i8x16.swizzle']) 167 { 168 testValid(`(module 169 (func (param v128) (param v128) (result v128) 170 (${op} (local.get 0) (local.get 1))))`); 171 } 172 173 testValid(`(module 174 (func (param v128) (param v128) (result v128) 175 (i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 (local.get 0) (local.get 1))))`); 176 177 assertErrorMessage(() => testValid( 178 `(module 179 (func (param v128) (param v128) (result v128) 180 (i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 (local.get 0) (local.get 1))))`), 181 SyntaxError, 182 /expected a u8/); 183 184 // (v128, i32) -> v128 185 186 for (let op of [ 187 'i8x16.shl', 188 'i8x16.shr_s', 189 'i8x16.shr_u', 190 'i16x8.shl', 191 'i16x8.shr_s', 192 'i16x8.shr_u', 193 'i32x4.shl', 194 'i32x4.shr_s', 195 'i32x4.shr_u', 196 'i64x2.shl', 197 'i64x2.shr_s', 198 'i64x2.shr_u']) 199 { 200 testValid(`(module 201 (func (param v128) (param i32) (result v128) 202 (${op} (local.get 0) (local.get 1))))`); 203 } 204 205 // v128 -> i32 206 207 for (let op of [ 208 'v128.any_true', 209 'i8x16.all_true', 210 'i16x8.all_true', 211 'i32x4.all_true', 212 'i8x16.bitmask', 213 'i16x8.bitmask', 214 'i32x4.bitmask']) 215 { 216 testValid(`(module 217 (func (param v128) (result i32) 218 (${op} (local.get 0))))`); 219 } 220 221 // T -> V128 222 223 for (let [op, input] of [ 224 ['i8x16.splat', 'i32'], 225 ['i16x8.splat', 'i32'], 226 ['i32x4.splat', 'i32'], 227 ['i64x2.splat', 'i64'], 228 ['f32x4.splat', 'f32'], 229 ['f64x2.splat', 'f64']]) 230 { 231 testValid(`(module 232 (func (param ${input}) (result v128) 233 (${op} (local.get 0))))`); 234 } 235 236 // i32 -> v128 237 238 for (let op of [ 239 'v128.load', 240 'v128.load8_splat', 241 'v128.load16_splat', 242 'v128.load32_splat', 243 'v128.load64_splat', 244 'v128.load8x8_s', 245 'v128.load8x8_u', 246 'v128.load16x4_s', 247 'v128.load16x4_u', 248 'v128.load32x2_s', 249 'v128.load32x2_u']) 250 { 251 testValid(`(module 252 (memory 1 1) 253 (func (param i32) (result v128) 254 (${op} (local.get 0))))`); 255 } 256 257 testValid(`(module 258 (func (result v128) 259 (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)) 260 (func (result v128) 261 (v128.const i16x8 0 1 2 3 4 5 6 7)) 262 (func (result v128) 263 (v128.const i32x4 0 1 2 3)) 264 (func (result v128) 265 (v128.const i64x2 0 1)) 266 (func (result v128) 267 (v128.const f32x4 0 1 2 3)) 268 (func (result v128) 269 (v128.const f32x4 0.5 1.5 2.5 3.5)) 270 (func (result v128) 271 (v128.const f64x2 0 1)) 272 (func (result v128) 273 (v128.const f64x2 0.5 1.5)))`); 274 275 assertErrorMessage(() => testValid( 276 `(module 277 (func (result v128) 278 (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)))`), 279 SyntaxError, 280 /expected a i8/); 281 282 assertErrorMessage(() => testValid( 283 `(module 284 (func (result v128) 285 (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 256 15)))`), 286 SyntaxError, 287 /invalid i8 number/); 288 289 assertErrorMessage(() => testValid( 290 `(module 291 (func (result v128) 292 (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 3.14 15)))`), 293 SyntaxError, 294 /expected a i8/); 295 296 assertErrorMessage(() => testValid( 297 `(module 298 (func (result v128) 299 (v128.const f32x4 0.5 1.5 2.5))`), 300 SyntaxError, 301 /expected a float/); 302 303 assertErrorMessage(() => testValid( 304 `(module 305 (func (result v128) 306 (v128.const i8x8 0 1 2 3 4 5 6 7)))`), 307 SyntaxError, 308 /expected one of/); 309 310 // v128 -> () 311 312 testValid(`(module 313 (memory 1 1) 314 (func (param i32) (param v128) 315 (v128.store (local.get 0) (local.get 1))))`); 316 317 // (v128, v128, v128) -> v128 318 319 testValid(`(module 320 (func (param v128) (param v128) (param v128) (result v128) 321 (v128.bitselect (local.get 0) (local.get 1) (local.get 2))))`); 322 323 // (v128, t) -> v128 324 325 for (let [prefix, input] of [['i8x16', 'i32'], 326 ['i16x8', 'i32'], 327 ['i32x4', 'i32'], 328 ['i64x2', 'i64'], 329 ['f32x4', 'f32'], 330 ['f64x2', 'f64']]) 331 { 332 testValid(`(module 333 (func (param v128) (param ${input}) (result v128) 334 (${prefix}.replace_lane 1 (local.get 0) (local.get 1))))`); 335 } 336 337 testInvalid( 338 `(module 339 (func (param v128) (param i32) (result v128) 340 (i8x16.replace_lane 16 (local.get 0) (local.get 1))))`); 341 342 // Global variables 343 344 testValid(`(module 345 (global $g (mut v128) (v128.const f32x4 1 2 3 4)))`); 346 347 testValid(`(module 348 (global $g (import "m" "g") v128) 349 (global $h (mut v128) (global.get $g)))`); 350 351 testValid(`(module 352 (global $g (export "g") v128 (v128.const f32x4 1 2 3 4)))`); 353 354 testValid(`(module 355 (global $g (export "g") (mut v128) (v128.const f32x4 1 2 3 4)))`); 356 357 // Imports, exports, calls 358 359 testValid(`(module 360 (import "m" "g" (func (param v128) (result v128))) 361 (func (export "f") (param v128) (result v128) 362 (f64x2.add (local.get 0) (v128.const f64x2 1 2))))`); 363 364 testValid(`(module 365 (func $f (param v128) (result v128) 366 (i8x16.neg (local.get 0))) 367 (func $g (export "g") (param v128) (result v128) 368 (call $f (local.get 0))))`);