summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcheck.py2
-rw-r--r--src/wasm-binary.h79
-rw-r--r--test/unit.wast.fromBinary397
3 files changed, 455 insertions, 23 deletions
diff --git a/check.py b/check.py
index 076c43b7a..7c963a7c7 100755
--- a/check.py
+++ b/check.py
@@ -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)
+ )
+ )
+)
+