// |jit-test| skip-if: !wasmSimdEnabled()
function testValid(code) {
assertEq(WebAssembly.validate(wasmTextToBinary(code)), true );
}
function testInvalid(code) {
assertEq(WebAssembly.validate(wasmTextToBinary(code)), false );
}
// v128 -> v128
for (let op of [
'i8x16.neg' ,
'i8x16.abs' ,
'i16x8.neg' ,
'i16x8.abs' ,
'i16x8.extend_low_i8x16_s' ,
'i16x8.extend_high_i8x16_s' ,
'i16x8.extend_low_i8x16_u' ,
'i16x8.extend_high_i8x16_u' ,
'i32x4.neg' ,
'i32x4.abs' ,
'i32x4.extend_low_i16x8_s' ,
'i32x4.extend_high_i16x8_s' ,
'i32x4.extend_low_i16x8_u' ,
'i32x4.extend_high_i16x8_u' ,
'i32x4.trunc_sat_f32x4_s' ,
'i32x4.trunc_sat_f32x4_u' ,
'i64x2.neg' ,
'f32x4.abs' ,
'f32x4.neg' ,
'f32x4.sqrt' ,
'f32x4.convert_i32x4_s' ,
'f32x4.convert_i32x4_s' ,
'f64x2.abs' ,
'f64x2.neg' ,
'f64x2.sqrt' ,
'v128.not' ])
{
testValid(`(module
(func (param v128) (result v128)
(${op} (local.get 0))))`);
}
for (let [prefix, result, suffix] of [['i8x16' , 'i32' , '_s' ],
['i8x16' , 'i32' , '_u' ],
['i16x8' , 'i32' , '_s' ],
['i16x8' , 'i32' , '_u' ],
['i32x4' , 'i32' , '' ],
['i64x2' , 'i64' , '' ],
['f32x4' , 'f32' , '' ],
['f64x2' , 'f64' , '' ]])
{
testValid(`(module
(func (param v128) (result ${result})
(${prefix}.extract_lane${suffix} 1 (local.get 0))))`);
}
// The wat parser accepts small out-of-range lane indices, but they must be
// caught in validation.
testInvalid(
`(module
(func (param v128) (result i32)
(i8x16.extract_lane_u 16 (local.get 0))))`);
// (v128, v128) -> v128
for (let op of [
'i8x16.eq' ,
'i8x16.ne' ,
'i8x16.lt_s' ,
'i8x16.lt_u' ,
'i8x16.gt_s' ,
'i8x16.gt_u' ,
'i8x16.le_s' ,
'i8x16.le_u' ,
'i8x16.ge_s' ,
'i8x16.ge_u' ,
'i16x8.eq' ,
'i16x8.ne' ,
'i16x8.lt_s' ,
'i16x8.lt_u' ,
'i16x8.gt_s' ,
'i16x8.gt_u' ,
'i16x8.le_s' ,
'i16x8.le_u' ,
'i16x8.ge_s' ,
'i16x8.ge_u' ,
'i32x4.eq' ,
'i32x4.ne' ,
'i32x4.lt_s' ,
'i32x4.lt_u' ,
'i32x4.gt_s' ,
'i32x4.gt_u' ,
'i32x4.le_s' ,
'i32x4.le_u' ,
'i32x4.ge_s' ,
'i32x4.ge_u' ,
'f32x4.eq' ,
'f32x4.ne' ,
'f32x4.lt' ,
'f32x4.gt' ,
'f32x4.le' ,
'f32x4.ge' ,
'f64x2.eq' ,
'f64x2.ne' ,
'f64x2.lt' ,
'f64x2.gt' ,
'f64x2.le' ,
'f64x2.ge' ,
'v128.and' ,
'v128.or' ,
'v128.xor' ,
'v128.andnot' ,
'i8x16.avgr_u' ,
'i16x8.avgr_u' ,
'i8x16.add' ,
'i8x16.add_sat_s' ,
'i8x16.add_sat_u' ,
'i8x16.sub' ,
'i8x16.sub_sat_s' ,
'i8x16.sub_sat_u' ,
'i8x16.min_s' ,
'i8x16.max_s' ,
'i8x16.min_u' ,
'i8x16.max_u' ,
'i16x8.add' ,
'i16x8.add_sat_s' ,
'i16x8.add_sat_u' ,
'i16x8.sub' ,
'i16x8.sub_sat_s' ,
'i16x8.sub_sat_u' ,
'i16x8.mul' ,
'i16x8.min_s' ,
'i16x8.max_s' ,
'i16x8.min_u' ,
'i16x8.max_u' ,
'i32x4.add' ,
'i32x4.sub' ,
'i32x4.mul' ,
'i32x4.min_s' ,
'i32x4.max_s' ,
'i32x4.min_u' ,
'i32x4.max_u' ,
'i64x2.add' ,
'i64x2.sub' ,
'i64x2.mul' ,
'f32x4.add' ,
'f32x4.sub' ,
'f32x4.mul' ,
'f32x4.div' ,
'f32x4.min' ,
'f32x4.max' ,
'f64x2.add' ,
'f64x2.sub' ,
'f64x2.mul' ,
'f64x2.div' ,
'f64x2.min' ,
'f64x2.max' ,
'i8x16.narrow_i16x8_s' ,
'i8x16.narrow_i16x8_u' ,
'i16x8.narrow_i32x4_s' ,
'i16x8.narrow_i32x4_u' ,
'i8x16.swizzle' ])
{
testValid(`(module
(func (param v128) (param v128) (result v128)
(${op} (local.get 0) (local.get 1))))`);
}
testValid(`(module
(func (param v128) (param v128) (result v128)
(i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 (local.get 0) (local.get 1))))`);
assertErrorMessage(() => testValid(
`(module
(func (param v128) (param v128) (result v128)
(i8x16.shuffle 0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 (local.get 0) (local.get 1))))`),
SyntaxError,
/expected a u8/);
// (v128, i32) -> v128
for (let op of [
'i8x16.shl' ,
'i8x16.shr_s' ,
'i8x16.shr_u' ,
'i16x8.shl' ,
'i16x8.shr_s' ,
'i16x8.shr_u' ,
'i32x4.shl' ,
'i32x4.shr_s' ,
'i32x4.shr_u' ,
'i64x2.shl' ,
'i64x2.shr_s' ,
'i64x2.shr_u' ])
{
testValid(`(module
(func (param v128) (param i32) (result v128)
(${op} (local.get 0) (local.get 1))))`);
}
// v128 -> i32
for (let op of [
'v128.any_true' ,
'i8x16.all_true' ,
'i16x8.all_true' ,
'i32x4.all_true' ,
'i8x16.bitmask' ,
'i16x8.bitmask' ,
'i32x4.bitmask' ])
{
testValid(`(module
(func (param v128) (result i32)
(${op} (local.get 0))))`);
}
// T -> V128
for (let [op, input] of [
['i8x16.splat' , 'i32' ],
['i16x8.splat' , 'i32' ],
['i32x4.splat' , 'i32' ],
['i64x2.splat' , 'i64' ],
['f32x4.splat' , 'f32' ],
['f64x2.splat' , 'f64' ]])
{
testValid(`(module
(func (param ${input}) (result v128)
(${op} (local.get 0))))`);
}
// i32 -> v128
for (let op of [
'v128.load' ,
'v128.load8_splat' ,
'v128.load16_splat' ,
'v128.load32_splat' ,
'v128.load64_splat' ,
'v128.load8x8_s' ,
'v128.load8x8_u' ,
'v128.load16x4_s' ,
'v128.load16x4_u' ,
'v128.load32x2_s' ,
'v128.load32x2_u' ])
{
testValid(`(module
(memory 1 1)
(func (param i32) (result v128)
(${op} (local.get 0))))`);
}
testValid(`(module
(func (result v128)
(v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
(func (result v128)
(v128.const i16x8 0 1 2 3 4 5 6 7))
(func (result v128)
(v128.const i32x4 0 1 2 3))
(func (result v128)
(v128.const i64x2 0 1))
(func (result v128)
(v128.const f32x4 0 1 2 3))
(func (result v128)
(v128.const f32x4 0.5 1.5 2.5 3.5))
(func (result v128)
(v128.const f64x2 0 1))
(func (result v128)
(v128.const f64x2 0.5 1.5)))`);
assertErrorMessage(() => testValid(
`(module
(func (result v128)
(v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)))`),
SyntaxError,
/expected a i8/);
assertErrorMessage(() => testValid(
`(module
(func (result v128)
(v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 256 15)))`),
SyntaxError,
/invalid i8 number/);
assertErrorMessage(() => testValid(
`(module
(func (result v128)
(v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 3.14 15)))`),
SyntaxError,
/expected a i8/);
assertErrorMessage(() => testValid(
`(module
(func (result v128)
(v128.const f32x4 0.5 1.5 2.5))`),
SyntaxError,
/expected a float /);
assertErrorMessage(() => testValid(
`(module
(func (result v128)
(v128.const i8x8 0 1 2 3 4 5 6 7)))`),
SyntaxError,
/expected one of/);
// v128 -> ()
testValid(`(module
(memory 1 1)
(func (param i32) (param v128)
(v128.store (local.get 0) (local.get 1))))`);
// (v128, v128, v128) -> v128
testValid(`(module
(func (param v128) (param v128) (param v128) (result v128)
(v128.bitselect (local.get 0) (local.get 1) (local.get 2))))`);
// (v128, t) -> v128
for (let [prefix, input] of [['i8x16' , 'i32' ],
['i16x8' , 'i32' ],
['i32x4' , 'i32' ],
['i64x2' , 'i64' ],
['f32x4' , 'f32' ],
['f64x2' , 'f64' ]])
{
testValid(`(module
(func (param v128) (param ${input}) (result v128)
(${prefix}.replace_lane 1 (local.get 0) (local.get 1))))`);
}
testInvalid(
`(module
(func (param v128) (param i32) (result v128)
(i8x16.replace_lane 16 (local.get 0) (local.get 1))))`);
// Global variables
testValid(`(module
(global $g (mut v128) (v128.const f32x4 1 2 3 4)))`);
testValid(`(module
(global $g (import "m" "g" ) v128)
(global $h (mut v128) (global.get $g)))`);
testValid(`(module
(global $g (export "g" ) v128 (v128.const f32x4 1 2 3 4)))`);
testValid(`(module
(global $g (export "g" ) (mut v128) (v128.const f32x4 1 2 3 4)))`);
// Imports, exports, calls
testValid(`(module
(import "m" "g" (func (param v128) (result v128)))
(func (export "f" ) (param v128) (result v128)
(f64x2.add (local.get 0) (v128.const f64x2 1 2))))`);
testValid(`(module
(func $f (param v128) (result v128)
(i8x16.neg (local.get 0)))
(func $g (export "g" ) (param v128) (result v128)
(call $f (local.get 0))))`);
Messung V0.5 C=93 H=76 G=84
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland