diff options
-rwxr-xr-x | auto_update_tests.py | 10 | ||||
-rw-r--r-- | src/passes/Print.cpp | 8 | ||||
-rw-r--r-- | src/wasm-binary.h | 4 | ||||
-rw-r--r-- | src/wasm-validator.h | 87 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 2 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 2 | ||||
-rw-r--r-- | test/reg_switch.wast | 4 | ||||
-rw-r--r-- | test/reg_switch.wast.fromBinary | 4 |
8 files changed, 65 insertions, 56 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 5fa106747..378f511cc 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -17,13 +17,6 @@ for asm in sorted(os.listdir('test')): actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() open(os.path.join('test', wasm), 'w').write(actual) -for wasm in sorted(os.listdir('test')): - if wasm.endswith('.wast') and os.path.basename(wasm) not in ['kitchen_sink.wast']: # i64s in kitchen_sink - print '..', wasm - asm = wasm.replace('.wast', '.2asm.js') - actual, err = subprocess.Popen([os.path.join('bin', 'wasm2asm'), os.path.join('test', wasm)], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() - open(os.path.join('test', asm), 'w').write(actual) - for dot_s_dir in ['dot_s', 'llvm_autogenerated']: for s in sorted(os.listdir(os.path.join('test', dot_s_dir))): if not s.endswith('.s'): continue @@ -111,7 +104,7 @@ for t in sorted(os.listdir(os.path.join('test', 'example'))): print ' '.join(extra) subprocess.check_call(extra) # Link against the binaryen C library DSO, using an executable-relative rpath - cmd = ['example.o', '-lbinaryen-c'] + cmd + ['-Wl,-rpath=$ORIGIN/../lib'] + cmd = ['example.o', '-lbinaryen'] + cmd + ['-Wl,-rpath=$ORIGIN/../lib'] else: continue if os.environ.get('COMPILER_FLAGS'): @@ -126,5 +119,4 @@ for t in sorted(os.listdir(os.path.join('test', 'example'))): finally: os.remove(output_file) - print '\n[ success! ]' diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index aa0657727..121287846 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -307,8 +307,8 @@ struct PrintSExpression : public Visitor<PrintSExpression> { case TruncSFloat64ToInt64: o << "trunc_s/f64"; break; case TruncUFloat64ToInt32: case TruncUFloat64ToInt64: o << "trunc_u/f64"; break; - case ReinterpretFloat32: - case ReinterpretFloat64: o << "reinterpret/" << (curr->type == i64 ? "f64" : "f32"); break; + case ReinterpretFloat32: o << "reinterpret/f32"; break; + case ReinterpretFloat64: o << "reinterpret/f64"; break; case ConvertUInt32ToFloat32: case ConvertUInt32ToFloat64: o << "convert_u/i32"; break; case ConvertSInt32ToFloat32: @@ -319,8 +319,8 @@ struct PrintSExpression : public Visitor<PrintSExpression> { case ConvertSInt64ToFloat64: o << "convert_s/i64"; break; case PromoteFloat32: o << "promote/f32"; break; case DemoteFloat64: o << "demote/f64"; break; - case ReinterpretInt32: - case ReinterpretInt64: o << "reinterpret/" << (curr->type == f64 ? "i64" : "i32"); break; + case ReinterpretInt32: o << "reinterpret/i32"; break; + case ReinterpretInt64: o << "reinterpret/i64"; break; default: abort(); } incIndent(); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 1fe3ef26a..ad6abf5af 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1946,8 +1946,8 @@ public: case BinaryConsts::F64ConvertF32: curr = allocator.alloc<Unary>(); curr->op = PromoteFloat32; curr->type = f64; break; case BinaryConsts::I32ReinterpretF32: curr = allocator.alloc<Unary>(); curr->op = ReinterpretFloat32; curr->type = i32; break; case BinaryConsts::I64ReinterpretF64: curr = allocator.alloc<Unary>(); curr->op = ReinterpretFloat64; curr->type = i64; break; - case BinaryConsts::F64ReinterpretI64: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt32; curr->type = f64; break; - case BinaryConsts::F32ReinterpretI32: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt64; curr->type = f32; break; + case BinaryConsts::F32ReinterpretI32: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt32; curr->type = f32; break; + case BinaryConsts::F64ReinterpretI64: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt64; curr->type = f64; break; default: return false; } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 7315ba4e5..f93e06524 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -50,6 +50,9 @@ public: breakTypes.erase(curr->name); } } + void visitIf(If *curr) { + shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "if condition must be i32"); + } void visitLoop(Loop *curr) { if (curr->in.is()) { LoopChildChecker childChecker(curr->in); @@ -80,12 +83,28 @@ public: } void visitBreak(Break *curr) { noteBreak(curr->name, curr->value); + if (curr->condition) { + shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "break condition must be i32"); + } } void visitSwitch(Switch *curr) { for (auto& target : curr->targets) { noteBreak(target, curr->value); } noteBreak(curr->default_, curr->value); + shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "br_table condition must be i32"); + } + void visitCall(Call *curr) { + auto* target = getModule()->getFunction(curr->target); + for (size_t i = 0; i < curr->operands.size(); i++) { + shouldBeTrue(curr->operands[i]->type == target->params[i], curr, "call param types must match"); + } + } + void visitCallImport(CallImport *curr) { + auto* target = getModule()->getImport(curr->target)->type; + for (size_t i = 0; i < curr->operands.size(); i++) { + shouldBeTrue(curr->operands[i]->type == target->params[i], curr, "call param types must match"); + } } void visitSetLocal(SetLocal *curr) { if (curr->value->type != unreachable) { @@ -94,9 +113,12 @@ public: } void visitLoad(Load *curr) { validateAlignment(curr->align); + shouldBeEqual(curr->ptr->type, i32, curr, "load pointer type must be i32"); } void visitStore(Store *curr) { validateAlignment(curr->align); + shouldBeEqual(curr->ptr->type, i32, curr, "store pointer type must be i32"); + shouldBeEqual(curr->value->type, curr->type, curr, "store value type must match"); } void visitBinary(Binary *curr) { if (curr->left->type != unreachable && curr->right->type != unreachable) { @@ -124,36 +146,31 @@ public: shouldBeEqual(curr->type, i32, curr, "relational unaries must return i32"); break; } - case ExtendSInt32: - case ExtendUInt32: - case WrapInt64: - case TruncSFloat32ToInt32: - case TruncSFloat32ToInt64: - case TruncUFloat32ToInt32: - case TruncUFloat32ToInt64: - case TruncSFloat64ToInt32: - case TruncSFloat64ToInt64: - case TruncUFloat64ToInt32: - case TruncUFloat64ToInt64: - case ReinterpretFloat32: - case ReinterpretFloat64: - case ConvertUInt32ToFloat32: - case ConvertUInt32ToFloat64: - case ConvertSInt32ToFloat32: - case ConvertSInt32ToFloat64: - case ConvertUInt64ToFloat32: - case ConvertUInt64ToFloat64: - case ConvertSInt64ToFloat32: - case ConvertSInt64ToFloat64: - case PromoteFloat32: - case DemoteFloat64: - case ReinterpretInt32: - case ReinterpretInt64: { - //if (curr->value->type != unreachable) { - shouldBeUnequal(curr->value->type, curr->type, curr, "conversion unaries must not return the same type"); - //} - break; - } + case ExtendSInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; + case ExtendUInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; + case WrapInt64: shouldBeEqual(curr->value->type, i64, curr, "wrap type must be correct"); break; + case TruncSFloat32ToInt32: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; + case TruncSFloat32ToInt64: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; + case TruncUFloat32ToInt32: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; + case TruncUFloat32ToInt64: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; + case TruncSFloat64ToInt32: shouldBeEqual(curr->value->type, f64, curr, "trunc type must be correct"); break; + case TruncSFloat64ToInt64: shouldBeEqual(curr->value->type, f64, curr, "trunc type must be correct"); break; + case TruncUFloat64ToInt32: shouldBeEqual(curr->value->type, f64, curr, "trunc type must be correct"); break; + case TruncUFloat64ToInt64: shouldBeEqual(curr->value->type, f64, curr, "trunc type must be correct"); break; + case ReinterpretFloat32: shouldBeEqual(curr->value->type, f32, curr, "reinterpret/f32 type must be correct"); break; + case ReinterpretFloat64: shouldBeEqual(curr->value->type, f64, curr, "reinterpret/f64 type must be correct"); break; + case ConvertUInt32ToFloat32: shouldBeEqual(curr->value->type, i32, curr, "convert type must be correct"); break; + case ConvertUInt32ToFloat64: shouldBeEqual(curr->value->type, i32, curr, "convert type must be correct"); break; + case ConvertSInt32ToFloat32: shouldBeEqual(curr->value->type, i32, curr, "convert type must be correct"); break; + case ConvertSInt32ToFloat64: shouldBeEqual(curr->value->type, i32, curr, "convert type must be correct"); break; + case ConvertUInt64ToFloat32: shouldBeEqual(curr->value->type, i64, curr, "convert type must be correct"); break; + case ConvertUInt64ToFloat64: shouldBeEqual(curr->value->type, i64, curr, "convert type must be correct"); break; + case ConvertSInt64ToFloat32: shouldBeEqual(curr->value->type, i64, curr, "convert type must be correct"); break; + case ConvertSInt64ToFloat64: shouldBeEqual(curr->value->type, i64, curr, "convert type must be correct"); break; + case PromoteFloat32: shouldBeEqual(curr->value->type, f32, curr, "promote type must be correct"); break; + case DemoteFloat64: shouldBeEqual(curr->value->type, f64, curr, "demote type must be correct"); break; + case ReinterpretInt32: shouldBeEqual(curr->value->type, i32, curr, "reinterpret/i32 type must be correct"); break; + case ReinterpretInt64: shouldBeEqual(curr->value->type, i64, curr, "reinterpret/i64 type must be correct"); break; default: abort(); } } @@ -243,7 +260,7 @@ private: template<typename T> bool shouldBeTrue(bool result, T curr, const char* text) { if (!result) { - fail() << "unexpected false: " << text << ", on " << curr << std::endl; + fail() << "unexpected false: " << text << ", on \n" << curr << std::endl; valid = false; return false; } @@ -252,7 +269,7 @@ private: template<typename T> bool shouldBeFalse(bool result, T curr, const char* text) { if (result) { - fail() << "unexpected true: " << text << ", on " << curr << std::endl; + fail() << "unexpected true: " << text << ", on \n" << curr << std::endl; valid = false; return false; } @@ -262,7 +279,7 @@ private: template<typename T, typename S> bool shouldBeEqual(S left, S right, T curr, const char* text) { if (left != right) { - fail() << "" << left << " != " << right << ": " << text << ", on " << curr << std::endl; + fail() << "" << left << " != " << right << ": " << text << ", on \n" << curr << std::endl; valid = false; return false; } @@ -271,7 +288,7 @@ private: template<typename T, typename S, typename U> bool shouldBeEqual(S left, S right, T curr, U other, const char* text) { if (left != right) { - fail() << "" << left << " != " << right << ": " << text << ", on " << curr << " / " << other << std::endl; + fail() << "" << left << " != " << right << ": " << text << ", on \n" << curr << " / " << other << std::endl; valid = false; return false; } @@ -281,7 +298,7 @@ private: template<typename T, typename S> bool shouldBeUnequal(S left, S right, T curr, const char* text) { if (left == right) { - fail() << "" << left << " == " << right << ": " << text << ", on " << curr << std::endl; + fail() << "" << left << " == " << right << ": " << text << ", on \n" << curr << std::endl; valid = false; return false; } diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 13caa8c89..8de127340 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -118,7 +118,7 @@ void test_core() { makeUnary(module, BinaryenPromoteFloat32(), 3), makeUnary(module, BinaryenDemoteFloat64(), 4), makeUnary(module, BinaryenReinterpretInt32(), 1), - makeUnary(module, BinaryenReinterpretInt64(), 1), + makeUnary(module, BinaryenReinterpretInt64(), 2), // Binary makeBinary(module, BinaryenAdd(), 1), makeBinary(module, BinaryenSub(), 4), diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 7a1366888..e878984a3 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -125,7 +125,7 @@ BinaryenFloat64: 4 (i32.const -10) ) (f64.reinterpret/i64 - (i32.const -10) + (i64.const -22) ) (i32.add (i32.const -10) diff --git a/test/reg_switch.wast b/test/reg_switch.wast index b53d45f54..60a294af0 100644 --- a/test/reg_switch.wast +++ b/test/reg_switch.wast @@ -2,10 +2,10 @@ (memory 0) (func $0 (if - (nop) + (i32.const 0) (block $A (br_table $A - (nop) + (i32.const 0) ) ) ) diff --git a/test/reg_switch.wast.fromBinary b/test/reg_switch.wast.fromBinary index 89a2fe061..7ea792099 100644 --- a/test/reg_switch.wast.fromBinary +++ b/test/reg_switch.wast.fromBinary @@ -3,11 +3,11 @@ (type $0 (func)) (func $0 (type $0) (if - (nop) + (i32.const 0) (block $label$0 (block $label$1 (br_table $label$1 - (nop) + (i32.const 0) ) ) ) |