diff options
-rwxr-xr-x | check.py | 2 | ||||
-rw-r--r-- | src/wasm-binary.h | 79 | ||||
-rw-r--r-- | test/unit.wast.fromBinary | 397 |
3 files changed, 455 insertions, 23 deletions
@@ -370,7 +370,7 @@ if torture: print '\n[ checking binary format testcases... ]\n' for wast in tests: - if wast.endswith('.wast') and not wast in ['unit.wast']: # blacklist some known failures + if wast.endswith('.wast') and not wast in []: # blacklist some known failures cmd = [os.path.join('bin', 'wasm-as'), os.path.join('test', wast), '-o', 'a.wasm'] print ' '.join(cmd) if os.path.exists('a.wasm'): os.unlink('a.wasm') diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 235a0e772..34b8711f5 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -261,17 +261,31 @@ enum ASTNodes { F64Le = 0x9a, F64Gt = 0x9b, F64Ge = 0x9c, - I32SConvertF32 = 0x9d, - I32SConvertF64 = 0x9e, - I32UConvertF32 = 0x9f, - I32UConvertF64 = 0xa0, - I32ConvertI64 = 0xa1, - I64SConvertF32 = 0xa2, - I64SConvertF64 = 0xa3, - I64UConvertF32 = 0xa4, - I64UConvertF64 = 0xa5, - I64SConvertI32 = 0xa6, - I64UConvertI32 = 0xa7, + + I32SConvertF32 = 0x9d, + I32SConvertF64 = 0x9e, + I32UConvertF32 = 0x9f, + I32UConvertF64 = 0xa0, + I32ConvertI64 = 0xa1, + I64SConvertF32 = 0xa2, + I64SConvertF64 = 0xa3, + I64UConvertF32 = 0xa4, + I64UConvertF64 = 0xa5, + I64SConvertI32 = 0xa6, + I64UConvertI32 = 0xa7, + F32SConvertI32 = 0xa8, + F32UConvertI32 = 0xa9, + F32SConvertI64 = 0xaa, + F32UConvertI64 = 0xab, + F32ConvertF64 = 0xac, + F32ReinterpretI32 = 0xad, + F64SConvertI32 = 0xae, + F64UConvertI32 = 0xaf, + F64SConvertI64 = 0xb0, + F64UConvertI64 = 0xb1, + F64ConvertF32 = 0xb2, + F64ReinterpretI64 = 0xb3, + I64ReinterpretF64 = 0xb5, I32LoadMem8S = 0x20, I32LoadMem8U = 0x21, @@ -777,21 +791,21 @@ public: case Trunc: o << int8_t(curr->type == f32 ? BinaryConsts::F32Trunc : BinaryConsts::F64Trunc); break;; case Nearest: o << int8_t(curr->type == f32 ? BinaryConsts::F32NearestInt : BinaryConsts::F64NearestInt); break; case Sqrt: o << int8_t(curr->type == f32 ? BinaryConsts::F32Sqrt : BinaryConsts::F64Sqrt); break; - case ExtendSInt32: abort(); break; - case ExtendUInt32: abort(); break; - case WrapInt64: abort(); break; - case TruncSFloat32: abort(); // XXX no signe/dunsigned versions of trunc? - case TruncUFloat32: abort(); // XXX - case TruncSFloat64: abort(); // XXX - case TruncUFloat64: abort(); // XXX - case ReinterpretFloat: abort(); // XXX missing + case ExtendSInt32: o << int8_t(BinaryConsts::I64SConvertI32); break; + case ExtendUInt32: o << int8_t(BinaryConsts::I64UConvertI32); break; + case WrapInt64: o << int8_t(BinaryConsts::I32ConvertI64); break; + case TruncUFloat32: o << int8_t(curr->type == i32 ? BinaryConsts::I32UConvertF32 : BinaryConsts::I64UConvertF32); break; + case TruncSFloat32: o << int8_t(curr->type == i32 ? BinaryConsts::I32SConvertF32 : BinaryConsts::I64SConvertF32); break; + case TruncUFloat64: o << int8_t(curr->type == i32 ? BinaryConsts::I32UConvertF64 : BinaryConsts::I64UConvertF64); break; + case TruncSFloat64: o << int8_t(curr->type == i32 ? BinaryConsts::I32SConvertF64 : BinaryConsts::I64SConvertF64); break; case ConvertUInt32: o << int8_t(curr->type == f32 ? BinaryConsts::I32UConvertF32 : BinaryConsts::I32UConvertF64); break; case ConvertSInt32: o << int8_t(curr->type == f32 ? BinaryConsts::I32SConvertF32 : BinaryConsts::I32SConvertF64); break; case ConvertUInt64: o << int8_t(curr->type == f32 ? BinaryConsts::I64UConvertF32 : BinaryConsts::I64UConvertF64); break; case ConvertSInt64: o << int8_t(curr->type == f32 ? BinaryConsts::I64UConvertF32 : BinaryConsts::I64UConvertF64); break; - case PromoteFloat32: abort(); // XXX - case DemoteFloat64: abort(); // XXX - case ReinterpretInt: abort(); // XXX + case DemoteFloat64: o << int8_t(BinaryConsts::F32ConvertF64); break; + case PromoteFloat32: o << int8_t(BinaryConsts::F64ConvertF32); break; + case ReinterpretFloat: o << int8_t(curr->type == f32 ? BinaryConsts::F32ReinterpretI32 : BinaryConsts::F64ReinterpretI64); break; + case ReinterpretInt: assert(curr->type == f64); o << int8_t(BinaryConsts::I64ReinterpretF64); break; // XX what about f32? default: abort(); } recurse(curr->value); @@ -1454,6 +1468,27 @@ public: case BinaryConsts::I64UConvertF64: curr->op = ConvertUInt64; curr->type = f64; break; case BinaryConsts::I64SConvertF32: curr->op = ConvertSInt64; curr->type = f32; break; case BinaryConsts::I64SConvertF64: curr->op = ConvertSInt64; curr->type = f64; break; + + case BinaryConsts::I64SConvertI32: curr->op = ExtendSInt32; curr->type = i64; break; + case BinaryConsts::I64UConvertI32: curr->op = ExtendUInt32; curr->type = i64; break; + case BinaryConsts::I32ConvertI64: curr->op = WrapInt64; curr->type = i32; break; + + case BinaryConsts::F32UConvertI32: curr->op = TruncUFloat32; curr->type = i32; break; + case BinaryConsts::F64UConvertI32: curr->op = TruncUFloat32; curr->type = i64; break; + case BinaryConsts::F32SConvertI32: curr->op = TruncSFloat32; curr->type = i32; break; + case BinaryConsts::F64SConvertI32: curr->op = TruncSFloat32; curr->type = i64; break; + case BinaryConsts::F32UConvertI64: curr->op = TruncUFloat64; curr->type = i32; break; + case BinaryConsts::F64UConvertI64: curr->op = TruncUFloat64; curr->type = i64; break; + case BinaryConsts::F32SConvertI64: curr->op = TruncSFloat64; curr->type = i32; break; + case BinaryConsts::F64SConvertI64: curr->op = TruncSFloat64; curr->type = i64; break; + + case BinaryConsts::F32ConvertF64: curr->op = DemoteFloat64; curr->type = f32; break; + case BinaryConsts::F64ConvertF32: curr->op = PromoteFloat32; curr->type = f64; break; + case BinaryConsts::F32ReinterpretI32: curr->op = ReinterpretFloat; curr->type = i32; break; + case BinaryConsts::F64ReinterpretI64: curr->op = ReinterpretFloat; curr->type = i64; break; + case BinaryConsts::I64ReinterpretF64: curr->op = ReinterpretInt; curr->type = f64; break; + // XXX what about f32 reinterpret? + default: return false; } if (debug) std::cerr << "zz node: Unary" << std::endl; diff --git a/test/unit.wast.fromBinary b/test/unit.wast.fromBinary new file mode 100644 index 000000000..460c90834 --- /dev/null +++ b/test/unit.wast.fromBinary @@ -0,0 +1,397 @@ +(module + (memory 4096 4096) + (type $0 (func (param f32))) + (type $1 (func)) + (type $2 (func (param f64) (result i32))) + (type $3 (func (param f64 f64) (result f64))) + (type $4 (func (result f64))) + (type $5 (func (result i32))) + (type $6 (func (param i32) (result i32))) + (import $_emscripten_asm_const_vi "env" "_emscripten_asm_const_vi") + (import $f64-to-int "env" "f64-to-int" (param f64) (result i32)) + (import $f64-rem "env" "f64-rem" (param f64 f64) (result f64)) + (export "big_negative" $big_negative) + (table $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (func $big_negative + (local $var$0 f64) + (block $label$0 + (set_local $var$0 + (f64.const -2147483648) + ) + (set_local $var$0 + (f64.const -2147483648) + ) + (set_local $var$0 + (f64.const -21474836480) + ) + (set_local $var$0 + (f64.const 0.039625) + ) + (set_local $var$0 + (f64.const -0.039625) + ) + ) + ) + (func $importedDoubles + (local $var$0 f64) + (block $label$0 + (set_local $var$0 + (f64.add + (f64.add + (f64.add + (f64.load align=8 + (i32.const 8) + ) + (f64.load align=8 + (i32.const 16) + ) + ) + (f64.neg + (f64.load align=8 + (i32.const 16) + ) + ) + ) + (f64.neg + (f64.load align=8 + (i32.const 8) + ) + ) + ) + ) + (if + (i32.gt_s + (i32.load align=4 + (i32.const 24) + ) + (i32.const 0) + ) + (br $label$0 + (f64.const -3.4) + ) + ) + (if + (f64.gt + (f64.load align=8 + (i32.const 32) + ) + (f64.const 0) + ) + (br $label$0 + (f64.const 5.6) + ) + ) + (f64.const 1.2) + ) + ) + (func $doubleCompares (param $var$0 f64) (param $var$1 f64) + (local $var$2 i32) + (local $var$3 f64) + (local $var$4 f64) + (block $label$0 + (if + (f64.gt + (get_local $var$0) + (f64.const 0) + ) + (br $label$0 + (f64.const 1.2) + ) + ) + (if + (f64.gt + (get_local $var$4) + (f64.const 0) + ) + (br $label$0 + (f64.const -3.4) + ) + ) + (if + (i32.gt_s + (get_local $var$2) + (i32.const 0) + ) + (br $label$0 + (f64.const 5.6) + ) + ) + (if + (f64.lt + (get_local $var$0) + (get_local $var$1) + ) + (br $label$0 + (get_local $var$0) + ) + ) + (get_local $var$1) + ) + ) + (func $intOps + (local $var$0 i32) + (i32.eq + (get_local $var$0) + (i32.const 0) + ) + ) + (func $conversions + (local $var$0 i32) + (local $var$1 f64) + (block $label$0 + (set_local $var$0 + (call_import $f64-to-int + (get_local $var$1) + ) + ) + (set_local $var$1 + (f64.convert_s/i32 + (get_local $var$0) + ) + ) + (set_local $var$1 + (f64.convert_u/i32 + (i32.shr_u + (get_local $var$0) + (i32.const 0) + ) + ) + ) + ) + ) + (func $seq + (local $var$0 f64) + (set_local $var$0 + (f64.sub + (block $label$0 + (f64.const 0.1) + (f64.const 5.1) + ) + (block $label$1 + (f64.const 3.2) + (f64.const 4.2) + ) + ) + ) + ) + (func $switcher (param $var$0 i32) + (block $label$0 + (tableswitch $label$4 + (i32.sub + (get_local $var$0) + (i32.const 1) + ) + (table (case $label$1) (case $label$2)) (case $label$3) + (case $label$1 + (br $label$0 + (i32.const 1) + ) + ) + (case $label$2 + (br $label$0 + (i32.const 2) + ) + ) + (case $label$3 + (nop) + ) + ) + (tableswitch $label$8 + (i32.sub + (get_local $var$0) + (i32.const 5) + ) + (table (case $label$5) (case $label$6) (case $label$6) (case $label$6) (case $label$6) (case $label$6) (case $label$6) (case $label$7)) (case $label$6) + (case $label$7 + (br $label$0 + (i32.const 121) + ) + ) + (case $label$5 + (br $label$0 + (i32.const 51) + ) + ) + (case $label$6 + (nop) + ) + ) + (tableswitch $label$14 + (i32.sub + (get_local $var$0) + (i32.const 2) + ) + (table (case $label$9) (case $label$10) (case $label$10) (case $label$11) (case $label$10) (case $label$10) (case $label$10) (case $label$10) (case $label$12) (case $label$10) (case $label$13)) (case $label$10) + (case $label$13 + (br $label$14) + ) + (case $label$12 + (br $label$14) + ) + (case $label$11 + (block $label$15 + (loop $label$16 $label$17 + (block $label$18 + (br $label$16) + (br $label$17) + ) + ) + (br $label$14) + ) + ) + (case $label$9 + (block $label$19 + (loop $label$20 $label$21 + (block $label$22 + (br $label$14) + (br $label$21) + ) + ) + (br $label$14) + ) + ) + (case $label$10 + (nop) + ) + ) + (i32.const 0) + ) + ) + (func $blocker + (block $label$0 + (br $label$0) + ) + ) + (func $frem + (call_import $f64-rem + (f64.const 5.5) + (f64.const 1.2) + ) + ) + (func $big_uint_div_u + (local $var$0 i32) + (block $label$0 + (set_local $var$0 + (i32.and + (i32.div_u + (i32.const 255) + (i32.const 2) + ) + (i32.const 255) + ) + ) + (get_local $var$0) + ) + ) + (func $fr (param $var$0 f32) + (local $var$1 f32) + (local $var$2 f64) + (block $label$0 + (f32.demote/f64 + (get_local $var$2) + ) + (get_local $var$1) + (f32.const 5) + (f32.const 0) + (f32.const 5) + (f32.const 0) + ) + ) + (func $negZero + (f64.const -0) + ) + (func $abs + (local $var$0 i32) + (local $var$1 i32) + (local $var$2 f32) + (local $var$3 f64) + (block $label$0 + (set_local $var$0 + (block $label$1 + (set_local $var$1 + (i32.const 0) + ) + (i32.select + (i32.lt_s + (get_local $var$1) + (i32.const 0) + ) + (i32.sub + (i32.const 0) + (get_local $var$1) + ) + (get_local $var$1) + ) + ) + ) + (set_local $var$3 + (f64.abs + (f64.const 0) + ) + ) + (set_local $var$2 + (f32.abs + (f32.const 0) + ) + ) + ) + ) + (func $neg + (local $var$0 f32) + (block $label$0 + (set_local $var$0 + (f32.neg + (get_local $var$0) + ) + ) + (call_indirect $0 + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + (get_local $var$0) + ) + ) + ) + (func $cneg (param $var$0 f32) + (call_indirect $0 + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + (get_local $var$0) + ) + ) + (func $___syscall_ret + (local $var$0 i32) + (i32.gt_u + (i32.shr_u + (get_local $var$0) + (i32.const 0) + ) + (i32.const -4096) + ) + ) + (func $z + (nop) + ) + (func $w + (nop) + ) + (func $block_and_after + (block $label$0 + (block $label$1 + (i32.const 1) + (br $label$1) + ) + (i32.const 0) + ) + ) +) + |