diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-18 11:39:22 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-18 14:24:40 -0700 |
commit | cf224aa34a3660aa5154091759d396936e946b28 (patch) | |
tree | 17e6ab9a9e2537ca37ba1a727d633b6d7e585708 | |
parent | 9700fca02229f4c3e15425a2396740384f7736cb (diff) | |
download | binaryen-cf224aa34a3660aa5154091759d396936e946b28.tar.gz binaryen-cf224aa34a3660aa5154091759d396936e946b28.tar.bz2 binaryen-cf224aa34a3660aa5154091759d396936e946b28.zip |
spec test updates, and many validation fixes
-rwxr-xr-x | check.py | 2 | ||||
-rw-r--r-- | src/s2wasm.h | 2 | ||||
-rw-r--r-- | src/wasm-binary.h | 2 | ||||
-rw-r--r-- | src/wasm-builder.h | 39 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 77 | ||||
-rw-r--r-- | src/wasm-validator.h | 77 | ||||
-rw-r--r-- | src/wasm.cpp | 67 | ||||
-rw-r--r-- | src/wasm.h | 41 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 26 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 662 | ||||
-rw-r--r-- | test/llvm_autogenerated/memory-addr64.s | 23 | ||||
-rw-r--r-- | test/llvm_autogenerated/memory-addr64.wast | 20 | ||||
m--------- | test/spec | 0 |
13 files changed, 554 insertions, 484 deletions
@@ -170,7 +170,7 @@ def split_wast(wast): ret = [] def to_end(j): depth = 1 - while depth > 0: + while depth > 0 and j < len(wast): if wast[j] == '"': j = wast.find('"', j + 1) elif wast[j] == '(': diff --git a/src/s2wasm.h b/src/s2wasm.h index 54d36011f..bef31486a 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -635,7 +635,7 @@ class S2WasmBuilder { auto curr = allocator->alloc<Unary>(); curr->op = op; curr->value = getInput(); - curr->type = type; + curr->finalize(); setOutput(curr, assign); }; auto makeHost = [&](HostOp op) { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 795e89d98..9674d12c1 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1015,7 +1015,7 @@ public: case Ctz: o << int8_t(curr->type == i32 ? BinaryConsts::I32Ctz : BinaryConsts::I64Ctz); break; case Popcnt: o << int8_t(curr->type == i32 ? BinaryConsts::I32Popcnt : BinaryConsts::I64Popcnt); break; case EqZ: o << int8_t(curr->type == i32 ? BinaryConsts::I32EqZ : BinaryConsts::I64EqZ); break; - case Neg: o << int8_t(curr->type == f32 ? BinaryConsts::F32Neg : BinaryConsts::F64Neg); break; + case Neg: o << int8_t(curr->type == f64 ? BinaryConsts::F64Neg : BinaryConsts::F32Neg); break; // TODO: wasm.h needs separate opcodes for all these case Abs: o << int8_t(curr->type == f32 ? BinaryConsts::F32Abs : BinaryConsts::F64Abs); break; case Ceil: o << int8_t(curr->type == f32 ? BinaryConsts::F32Ceil : BinaryConsts::F64Ceil); break; case Floor: o << int8_t(curr->type == f32 ? BinaryConsts::F32Floor : BinaryConsts::F64Floor); break; diff --git a/src/wasm-builder.h b/src/wasm-builder.h index c20c25f06..4dc195d5c 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -136,44 +136,7 @@ public: Unary* makeUnary(UnaryOp op, Expression *value) { auto* ret = allocator.alloc<Unary>(); ret->op = op; ret->value = value; - switch (op) { - case Clz: - case Ctz: - case Popcnt: - case Neg: - case Abs: - case Ceil: - case Floor: - case Trunc: - case Nearest: - case Sqrt: ret->type = value->type; break; - case EqZ: ret->type = i32; break; - case ExtendSInt32: case ExtendUInt32: ret->type = i64; break; - case WrapInt64: ret->type = i32; break; - case PromoteFloat32: ret->type = f64; break; - case DemoteFloat64: ret->type = f32; break; - case TruncSFloat32ToInt32: - case TruncUFloat32ToInt32: - case TruncSFloat64ToInt32: - case TruncUFloat64ToInt32: - case ReinterpretFloat32: ret->type = i32; break; - case TruncSFloat32ToInt64: - case TruncUFloat32ToInt64: - case TruncSFloat64ToInt64: - case TruncUFloat64ToInt64: - case ReinterpretFloat64: ret->type = i64; break; - case ReinterpretInt32: - case ConvertSInt32ToFloat32: - case ConvertUInt32ToFloat32: - case ConvertSInt64ToFloat32: - case ConvertUInt64ToFloat32: ret->type = f32; break; - case ReinterpretInt64: - case ConvertSInt32ToFloat64: - case ConvertUInt32ToFloat64: - case ConvertSInt64ToFloat64: - case ConvertUInt64ToFloat64: ret->type = f64; break; - default: abort(); - } + ret->finalize(); return ret; } Binary* makeBinary(BinaryOp op, Expression *left, Expression *right) { diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 4dfba25f8..74c2200a9 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -60,8 +60,6 @@ class Element { IString str_; bool dollared_; - size_t line, col; - public: Element(MixedArena& allocator) : isList_(true), list_(allocator), line(-1), col(-1) {} @@ -69,6 +67,8 @@ public: bool isStr() { return !isList_; } bool dollared() { return dollared_; } + size_t line, col; + // list methods List& list() { @@ -300,11 +300,9 @@ private: if (id == TYPE) return parseType(s); if (id != FUNC) return; size_t i = 1; - Name name; - if (s[i]->isStr()) { - name = s[i]->str(); - i++; - } else { + Name name, exportName; + i = parseFunctionNames(s, name, exportName); + if (!name.is()) { // unnamed, use an index name = Name::fromInt(functionCounter); } @@ -371,21 +369,26 @@ private: wasm.addStart(getFunctionName(*s[1])); } - void parseFunction(Element& s) { + // returns the next index in s + size_t parseFunctionNames(Element& s, Name& name, Name& exportName) { size_t i = 1; - Name name, exportName; - if (s[i]->isStr()) { + while (i < s.size() && s[i]->isStr()) { if (!s[i]->dollared()) { // an export name exportName = s[i]->str(); i++; - } - if (s[i]->isStr()) { - assert(s[i]->dollared()); + } else { name = s[i]->str(); i++; } } + return i; + } + + void parseFunction(Element& s) { + size_t i = 1; + Name name, exportName; + i = parseFunctionNames(s, name, exportName); if (!name.is()) { // unnamed, use an index name = Name::fromInt(functionCounter); @@ -558,7 +561,7 @@ public: case 'e': { if (op[1] == 'q') { if (op[2] == 0) return makeBinary(s, BinaryOp::Eq, type); - if (op[2] == 'z') return makeUnary(s, UnaryOp::EqZ, i32); + if (op[2] == 'z') return makeUnary(s, UnaryOp::EqZ, type); } if (op[1] == 'x') return makeUnary(s, op[7] == 'u' ? UnaryOp::ExtendUInt32 : UnaryOp::ExtendSInt32, type); abort_on(op); @@ -736,7 +739,50 @@ private: auto ret = allocator.alloc<Unary>(); ret->op = op; ret->value = parseExpression(s[1]); - ret->type = type; + ret->finalize(); + // type is the reported type, e.g. i64.ctz reports i64 (but has a return type of i32, in this case) + // verify the reported type is correct + switch (op) { + case EqZ: + case Neg: + case Abs: + case Ceil: + case Floor: + case Trunc: + case Nearest: + case Sqrt: + case Clz: + case Ctz: + case Popcnt: { + if (ret->value->type != unreachable && type != ret->value->type) throw ParseException(std::string("bad type for ") + getExpressionName(ret) + ": " + printWasmType(type) + " vs value type " + printWasmType(ret->value->type), s.line, s.col); + break; + } + case ExtendSInt32: case ExtendUInt32: + case WrapInt64: + case PromoteFloat32: + case DemoteFloat64: + case TruncSFloat32ToInt32: + case TruncUFloat32ToInt32: + case TruncSFloat64ToInt32: + case TruncUFloat64ToInt32: + case ReinterpretFloat32: + case TruncSFloat32ToInt64: + case TruncUFloat32ToInt64: + case TruncSFloat64ToInt64: + case TruncUFloat64ToInt64: + case ReinterpretFloat64: + case ReinterpretInt32: + case ConvertSInt32ToFloat32: + case ConvertUInt32ToFloat32: + case ConvertSInt64ToFloat32: + case ConvertUInt64ToFloat32: + case ReinterpretInt64: + case ConvertSInt32ToFloat64: + case ConvertUInt32ToFloat64: + case ConvertSInt64ToFloat64: + case ConvertUInt64ToFloat64: break; + default: WASM_UNREACHABLE(); + } return ret; } @@ -1150,6 +1196,7 @@ private: size_t i = 2; if (s[i]->isStr()) { wasm.memory.max = atoi(s[i]->c_str()); + if (wasm.memory.max > Memory::kMaxSize) throw ParseException("total memory must be <= 4GB"); i++; } while (i < s.size()) { diff --git a/src/wasm-validator.h b/src/wasm-validator.h index f93e06524..3d8596ad2 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -30,6 +30,7 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>> bool valid; std::map<Name, WasmType> breakTypes; // breaks to a label must all have the same type, and the right type + WasmType returnType = unreachable; // type used in returns public: bool validate(Module& module) { @@ -51,7 +52,7 @@ public: } } void visitIf(If *curr) { - shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "if condition must be i32"); + shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32 || curr->condition->type == i64, curr, "if condition must be valid"); } void visitLoop(Loop *curr) { if (curr->in.is()) { @@ -96,29 +97,39 @@ public: } void visitCall(Call *curr) { auto* target = getModule()->getFunction(curr->target); + shouldBeTrue(curr->operands.size() == target->params.size(), curr, "call param number must match"); for (size_t i = 0; i < curr->operands.size(); i++) { - shouldBeTrue(curr->operands[i]->type == target->params[i], curr, "call param types must match"); + shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, target->params[i], curr, "call param types must match"); } } void visitCallImport(CallImport *curr) { auto* target = getModule()->getImport(curr->target)->type; + shouldBeTrue(curr->operands.size() == target->params.size(), curr, "call param number must match"); for (size_t i = 0; i < curr->operands.size(); i++) { - shouldBeTrue(curr->operands[i]->type == target->params[i], curr, "call param types must match"); + shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, target->params[i], curr, "call param types must match"); + } + } + void visitCallIndirect(CallIndirect *curr) { + auto* type = curr->fullType; + shouldBeEqualOrFirstIsUnreachable(curr->target->type, i32, curr, "indirect call target must be an i32"); + shouldBeTrue(curr->operands.size() == type->params.size(), curr, "call param number must match"); + for (size_t i = 0; i < curr->operands.size(); i++) { + shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, type->params[i], curr, "call param types must match"); } } void visitSetLocal(SetLocal *curr) { if (curr->value->type != unreachable) { - shouldBeEqual(curr->type, curr->value->type, curr, "set_local type must be correct"); + shouldBeEqualOrFirstIsUnreachable(curr->value->type, curr->type, curr, "set_local type must be correct"); } } void visitLoad(Load *curr) { validateAlignment(curr->align); - shouldBeEqual(curr->ptr->type, i32, curr, "load pointer type must be i32"); + shouldBeEqualOrFirstIsUnreachable(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"); + shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "store pointer type must be i32"); + shouldBeEqualOrFirstIsUnreachable(curr->value->type, curr->type, curr, "store value type must match"); } void visitBinary(Binary *curr) { if (curr->left->type != unreachable && curr->right->type != unreachable) { @@ -126,6 +137,15 @@ public: } } void visitUnary(Unary *curr) { + shouldBeUnequal(curr->value->type, none, curr, "unaries must not receive a none as their input"); + switch (curr->op) { + case EqZ: { + shouldBeEqual(curr->type, i32, curr, "eqz must return i32"); + break; + } + default: {} + } + if (curr->value->type == unreachable) return; switch (curr->op) { case Clz: case Ctz: @@ -143,7 +163,7 @@ public: break; } case EqZ: { - shouldBeEqual(curr->type, i32, curr, "relational unaries must return i32"); + shouldBeTrue(curr->value->type == i32 || curr->value->type == i64, curr, "eqz input must be i32 or i64"); break; } case ExtendSInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; @@ -175,15 +195,42 @@ public: } } + void visitReturn(Return* curr) { + if (curr->value) { + returnType = curr->value->type; + } + } + + void visitHost(Host* curr) { + switch (curr->op) { + case GrowMemory: { + shouldBeEqual(curr->operands.size(), size_t(1), curr, "grow_memory must have 1 operand"); + shouldBeEqualOrFirstIsUnreachable(curr->operands[0]->type, i32, curr, "grow_memory must have i32 operand"); + break; + } + case PageSize: + case CurrentMemory: + case HasFeature: break; + default: WASM_UNREACHABLE(); + } + } + void visitFunction(Function *curr) { // if function has no result, it is ignored // if body is unreachable, it might be e.g. a return - if (curr->result != none && curr->body->type != unreachable) { - shouldBeEqual(curr->result, curr->body->type, curr->body, "function result must match, if function returns"); + if (curr->result != none) { + if (curr->body->type != unreachable) { + shouldBeEqual(curr->result, curr->body->type, curr->body, "function body type must match, if function returns"); + } + if (returnType != unreachable) { + shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function returns"); + } } + returnType = unreachable; } void visitMemory(Memory *curr) { shouldBeFalse(curr->initial > curr->max, "memory", "memory max >= initial"); + shouldBeTrue(curr->max <= Memory::kMaxSize, "memory", "total memory must be <= 4GB"); size_t top = 0; for (auto& segment : curr->segments) { shouldBeFalse(segment.offset < top, "memory", "segment offset is small enough"); @@ -296,6 +343,16 @@ private: } template<typename T, typename S> + bool shouldBeEqualOrFirstIsUnreachable(S left, S right, T curr, const char* text) { + if (left != unreachable && left != right) { + fail() << "" << left << " != " << right << ": " << text << ", on \n" << curr << std::endl; + valid = false; + return false; + } + return true; + } + + template<typename T, typename S> bool shouldBeUnequal(S left, S right, T curr, const char* text) { if (left == right) { fail() << "" << left << " == " << right << ": " << text << ", on \n" << curr << std::endl; diff --git a/src/wasm.cpp b/src/wasm.cpp index 98268310a..09d9c3c16 100644 --- a/src/wasm.cpp +++ b/src/wasm.cpp @@ -22,66 +22,65 @@ namespace wasm { struct BlockTypeSeeker : public PostWalker<BlockTypeSeeker, Visitor<BlockTypeSeeker>> { Block* target; // look for this one - WasmType type = unreachable; + std::vector<WasmType> types; BlockTypeSeeker(Block* target) : target(target) {} - void noteType(WasmType other) { - // once none, stop. it then indicates a poison value, that must not be consumed - // and ignore unreachable - if (type != none) { - if (other == none) { - type = none; - } else if (other != unreachable) { - if (type == unreachable) { - type = other; - } else if (type != other) { - type = none; // poison value, we saw multiple types; this should not be consumed - } - } - } - } - void visitBreak(Break *curr) { if (curr->name == target->name) { - noteType(curr->value ? curr->value->type : none); + types.push_back(curr->value ? curr->value->type : none); } } void visitSwitch(Switch *curr) { for (auto name : curr->targets) { - if (name == target->name) noteType(curr->value ? curr->value->type : none); + if (name == target->name) types.push_back(curr->value ? curr->value->type : none); } } void visitBlock(Block *curr) { if (curr == target) { - if (curr->list.size() > 0) noteType(curr->list.back()->type); - } else { - type = unreachable; // ignore all breaks til now, they were captured by someone with the same name + if (curr->list.size() > 0) { + types.push_back(curr->list.back()->type); + } else { + types.push_back(none); + } + } else if (curr->name == target->name) { + types.clear(); // ignore all breaks til now, they were captured by someone with the same name } } }; void Block::finalize() { - if (list.size() > 0) { - auto last = list.back()->type; - if (last != unreachable) { - // well that was easy - type = last; - return; - } - } if (!name.is()) { - // that was rather silly - type = unreachable; + // nothing branches here, so this is easy + if (list.size() > 0) { + type = list.back()->type; + } else { + type = unreachable; + } return; } - // oh no this is hard + BlockTypeSeeker seeker(this); Expression* temp = this; seeker.walk(temp); - type = seeker.type; + type = unreachable; + for (auto other : seeker.types) { + // once none, stop. it then indicates a poison value, that must not be consumed + // and ignore unreachable + if (type != none) { + if (other == none) { + type = none; + } else if (other != unreachable) { + if (type == unreachable) { + type = other; + } else if (type != other) { + type = none; // poison value, we saw multiple types; this should not be consumed + } + } + } + } } } // namespace wasm diff --git a/src/wasm.h b/src/wasm.h index f68459401..68c388df8 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1118,7 +1118,46 @@ public: bool isRelational() { return op == EqZ; } - // no finalize since some opcodes have more than one type, so user must set it anyhow + void finalize() { + switch (op) { + case Clz: + case Ctz: + case Popcnt: + case Neg: + case Abs: + case Ceil: + case Floor: + case Trunc: + case Nearest: + case Sqrt: type = value->type; break; + case EqZ: type = i32; break; + case ExtendSInt32: case ExtendUInt32: type = i64; break; + case WrapInt64: type = i32; break; + case PromoteFloat32: type = f64; break; + case DemoteFloat64: type = f32; break; + case TruncSFloat32ToInt32: + case TruncUFloat32ToInt32: + case TruncSFloat64ToInt32: + case TruncUFloat64ToInt32: + case ReinterpretFloat32: type = i32; break; + case TruncSFloat32ToInt64: + case TruncUFloat32ToInt64: + case TruncSFloat64ToInt64: + case TruncUFloat64ToInt64: + case ReinterpretFloat64: type = i64; break; + case ReinterpretInt32: + case ConvertSInt32ToFloat32: + case ConvertUInt32ToFloat32: + case ConvertSInt64ToFloat32: + case ConvertUInt64ToFloat32: type = f32; break; + case ReinterpretInt64: + case ConvertSInt32ToFloat64: + case ConvertUInt32ToFloat64: + case ConvertSInt64ToFloat64: + case ConvertUInt64ToFloat64: type = f64; break; + default: WASM_UNREACHABLE(); + } + } }; class Binary : public SpecificExpression<Expression::BinaryId> { diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 6ccd642ae..728215893 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -73,7 +73,7 @@ void test_core() { constF64Bits = BinaryenConst(module, BinaryenLiteralFloat64Bits(0xffff12345678abcdLL)); const char* switchValueNames[] = { "the-value" }; - const char* switchBodyNames[] = { "the-body" }; + const char* switchBodyNames[] = { "the-nothing" }; BinaryenExpressionRef callOperands2[] = { makeInt32(module, 13), makeFloat64(module, 3.7) }; BinaryenExpressionRef callOperands4[] = { makeInt32(module, 13), makeInt64(module, 37), makeFloat32(module, 1.3f), makeFloat64(module, 3.7) }; @@ -81,7 +81,7 @@ void test_core() { BinaryenType params[4] = { BinaryenInt32(), BinaryenInt64(), BinaryenFloat32(), BinaryenFloat64() }; BinaryenFunctionTypeRef iiIfF = BinaryenAddFunctionType(module, "iiIfF", BinaryenInt32(), params, 4); - BinaryenExpressionRef bodyList[] = { + BinaryenExpressionRef valueList[] = { // Unary makeUnary(module, BinaryenClz(), 1), makeUnary(module, BinaryenCtz(), 2), @@ -160,16 +160,19 @@ void test_core() { BinaryenLoop(module, NULL, "in2", makeInt32(module, 0)), BinaryenLoop(module, NULL, NULL, makeInt32(module, 0)), BinaryenBreak(module, "the-value", makeInt32(module, 0), makeInt32(module, 1)), - BinaryenBreak(module, "the-body", makeInt32(module, 2), NULL), + BinaryenBreak(module, "the-nothing", makeInt32(module, 2), NULL), BinaryenBreak(module, "the-value", NULL, makeInt32(module, 3)), - BinaryenBreak(module, "the-body", NULL, NULL), + BinaryenBreak(module, "the-nothing", NULL, NULL), BinaryenSwitch(module, switchValueNames, 1, "the-value", makeInt32(module, 0), makeInt32(module, 1)), - BinaryenSwitch(module, switchBodyNames, 1, "the-body", makeInt32(module, 2), NULL), + BinaryenSwitch(module, switchBodyNames, 1, "the-nothing", makeInt32(module, 2), NULL), BinaryenUnary(module, BinaryenEqZ(), // check the output type of the call node BinaryenCall(module, "kitchen-sinker", callOperands4, 4, BinaryenInt32()) ), BinaryenUnary(module, BinaryenEqZ(), // check the output type of the call node - BinaryenCallImport(module, "an-imported", callOperands2, 2, BinaryenFloat32()) + BinaryenUnary(module, + BinaryenTruncSFloat32ToInt32(), + BinaryenCallImport(module, "an-imported", callOperands2, 2, BinaryenFloat32()) + ) ), BinaryenUnary(module, BinaryenEqZ(), // check the output type of the call node BinaryenCallIndirect(module, makeInt32(module, 2449), callOperands4, 4, iiIfF) @@ -183,16 +186,17 @@ void test_core() { BinaryenStore(module, 4, 0, 0, makeInt32(module, 10), makeInt32(module, 11)), BinaryenStore(module, 8, 2, 4, makeInt32(module, 110), makeInt64(module, 111)), BinaryenSelect(module, makeInt32(module, 1), makeInt32(module, 3), makeInt32(module, 5)), - BinaryenReturn(module, NULL), - BinaryenReturn(module, makeFloat32(module, 1)), + BinaryenReturn(module, makeInt32(module, 1337)), // TODO: Host BinaryenNop(module), BinaryenUnreachable(module), }; - // Make the main body of the function. one block with a return value, one without - BinaryenExpressionRef value = BinaryenBlock(module, "the-value", bodyList, sizeof(bodyList) / sizeof(BinaryenExpressionRef)); - BinaryenExpressionRef body = BinaryenBlock(module, "the-body", &value, 1); + // Make the main body of the function. and one block with a return value, one without + BinaryenExpressionRef value = BinaryenBlock(module, "the-value", valueList, sizeof(valueList) / sizeof(BinaryenExpressionRef)); + BinaryenExpressionRef nothing = BinaryenBlock(module, "the-nothing", &value, 1); + BinaryenExpressionRef bodyList[] = { nothing, makeInt32(module, 42) }; + BinaryenExpressionRef body = BinaryenBlock(module, "the-body", bodyList, 2); // Create the function BinaryenType localTypes[] = { BinaryenInt32() }; diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index e36e9ba14..c4fb6a4af 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -19,340 +19,344 @@ BinaryenFloat64: 4 (func $kitchen-sinker (type $iiIfF) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) (local $4 i32) (block $the-body - (block $the-value - (i32.clz - (i32.const -10) - ) - (i64.ctz - (i64.const -22) - ) - (i32.popcnt - (i32.const -10) - ) - (f32.neg - (f32.const -33.61199951171875) - ) - (f64.abs - (f64.const -9005.841) - ) - (f32.ceil - (f32.const -33.61199951171875) - ) - (f64.floor - (f64.const -9005.841) - ) - (f32.trunc - (f32.const -33.61199951171875) - ) - (f32.nearest - (f32.const -33.61199951171875) - ) - (f64.sqrt - (f64.const -9005.841) - ) - (i32.eqz - (i32.const -10) - ) - (i64.extend_s/i32 - (i32.const -10) - ) - (i64.extend_u/i32 - (i32.const -10) - ) - (i32.wrap/i64 - (i64.const -22) - ) - (i32.trunc_s/f32 - (f32.const -33.61199951171875) - ) - (i64.trunc_s/f32 - (f32.const -33.61199951171875) - ) - (i32.trunc_u/f32 - (f32.const -33.61199951171875) - ) - (i64.trunc_u/f32 - (f32.const -33.61199951171875) - ) - (i32.trunc_s/f64 - (f64.const -9005.841) - ) - (i64.trunc_s/f64 - (f64.const -9005.841) - ) - (i32.trunc_u/f64 - (f64.const -9005.841) - ) - (i64.trunc_u/f64 - (f64.const -9005.841) - ) - (i32.reinterpret/f32 - (f32.const -33.61199951171875) - ) - (i64.reinterpret/f64 - (f64.const -9005.841) - ) - (f32.convert_s/i32 - (i32.const -10) - ) - (f64.convert_s/i32 - (i32.const -10) - ) - (f32.convert_u/i32 - (i32.const -10) - ) - (f64.convert_u/i32 - (i32.const -10) - ) - (f32.convert_s/i64 - (i64.const -22) - ) - (f64.convert_s/i64 - (i64.const -22) - ) - (f32.convert_u/i64 - (i64.const -22) - ) - (f64.convert_u/i64 - (i64.const -22) - ) - (f64.promote/f32 - (f32.const -33.61199951171875) - ) - (f32.demote/f64 - (f64.const -9005.841) - ) - (f32.reinterpret/i32 - (i32.const -10) - ) - (f64.reinterpret/i64 - (i64.const -22) - ) - (i32.add - (i32.const -10) - (i32.const -11) - ) - (f64.sub - (f64.const -9005.841) - (f64.const -9007.333) - ) - (i32.div_s - (i32.const -10) - (i32.const -11) - ) - (i64.div_u - (i64.const -22) - (i64.const -23) - ) - (i64.rem_s - (i64.const -22) - (i64.const -23) - ) - (i32.rem_u - (i32.const -10) - (i32.const -11) - ) - (i32.and - (i32.const -10) - (i32.const -11) - ) - (i64.or - (i64.const -22) - (i64.const -23) - ) - (i32.xor - (i32.const -10) - (i32.const -11) - ) - (i64.shl - (i64.const -22) - (i64.const -23) - ) - (i64.shr_u - (i64.const -22) - (i64.const -23) - ) - (i32.shr_s - (i32.const -10) - (i32.const -11) - ) - (i32.rotl - (i32.const -10) - (i32.const -11) - ) - (i64.rotr - (i64.const -22) - (i64.const -23) - ) - (f32.div - (f32.const -33.61199951171875) - (f32.const -62.5) - ) - (f64.copysign - (f64.const -9005.841) - (f64.const -9007.333) - ) - (f32.min - (f32.const -33.61199951171875) - (f32.const -62.5) - ) - (f64.max - (f64.const -9005.841) - (f64.const -9007.333) - ) - (i32.eq - (i32.const -10) - (i32.const -11) - ) - (f32.ne - (f32.const -33.61199951171875) - (f32.const -62.5) - ) - (i32.lt_s - (i32.const -10) - (i32.const -11) - ) - (i64.lt_u - (i64.const -22) - (i64.const -23) - ) - (i64.le_s - (i64.const -22) - (i64.const -23) - ) - (i32.le_u - (i32.const -10) - (i32.const -11) - ) - (i64.gt_s - (i64.const -22) - (i64.const -23) - ) - (i32.gt_u - (i32.const -10) - (i32.const -11) - ) - (i32.ge_s - (i32.const -10) - (i32.const -11) - ) - (i64.ge_u - (i64.const -22) - (i64.const -23) - ) - (f32.lt - (f32.const -33.61199951171875) - (f32.const -62.5) - ) - (f64.le - (f64.const -9005.841) - (f64.const -9007.333) - ) - (f64.gt - (f64.const -9005.841) - (f64.const -9007.333) - ) - (f32.ge - (f32.const -33.61199951171875) - (f32.const -62.5) - ) - (block - ) - (if - (i32.const 1) - (i32.const 2) - (i32.const 3) - ) - (if - (i32.const 4) - (i32.const 5) - ) - (loop $out $in - (i32.const 0) - ) - (loop $in2 - (i32.const 0) - ) - (loop - (i32.const 0) - ) - (br_if $the-value - (i32.const 1) - (i32.const 0) - ) - (br_if $the-body - (i32.const 2) - ) - (br $the-value - (i32.const 3) - ) - (br $the-body) - (br_table $the-value $the-value - (i32.const 1) - (i32.const 0) - ) - (br_table $the-body $the-body - (i32.const 2) - ) - (i32.eqz - (call $kitchen-sinker - (i32.const 13) - (i64.const 37) - (f32.const 1.2999999523162842) - (f64.const 3.7) + (block $the-nothing + (block $the-value + (i32.clz + (i32.const -10) ) - ) - (f32.eqz - (call_import $an-imported - (i32.const 13) - (f64.const 3.7) + (i64.ctz + (i64.const -22) ) - ) - (i32.eqz - (call_indirect $iiIfF - (i32.const 2449) - (i32.const 13) - (i64.const 37) - (f32.const 1.2999999523162842) - (f64.const 3.7) + (i32.popcnt + (i32.const -10) ) + (f32.neg + (f32.const -33.61199951171875) + ) + (f64.abs + (f64.const -9005.841) + ) + (f32.ceil + (f32.const -33.61199951171875) + ) + (f64.floor + (f64.const -9005.841) + ) + (f32.trunc + (f32.const -33.61199951171875) + ) + (f32.nearest + (f32.const -33.61199951171875) + ) + (f64.sqrt + (f64.const -9005.841) + ) + (i32.eqz + (i32.const -10) + ) + (i64.extend_s/i32 + (i32.const -10) + ) + (i64.extend_u/i32 + (i32.const -10) + ) + (i32.wrap/i64 + (i64.const -22) + ) + (i32.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_s/f64 + (f64.const -9005.841) + ) + (i64.trunc_s/f64 + (f64.const -9005.841) + ) + (i32.trunc_u/f64 + (f64.const -9005.841) + ) + (i64.trunc_u/f64 + (f64.const -9005.841) + ) + (i32.reinterpret/f32 + (f32.const -33.61199951171875) + ) + (i64.reinterpret/f64 + (f64.const -9005.841) + ) + (f32.convert_s/i32 + (i32.const -10) + ) + (f64.convert_s/i32 + (i32.const -10) + ) + (f32.convert_u/i32 + (i32.const -10) + ) + (f64.convert_u/i32 + (i32.const -10) + ) + (f32.convert_s/i64 + (i64.const -22) + ) + (f64.convert_s/i64 + (i64.const -22) + ) + (f32.convert_u/i64 + (i64.const -22) + ) + (f64.convert_u/i64 + (i64.const -22) + ) + (f64.promote/f32 + (f32.const -33.61199951171875) + ) + (f32.demote/f64 + (f64.const -9005.841) + ) + (f32.reinterpret/i32 + (i32.const -10) + ) + (f64.reinterpret/i64 + (i64.const -22) + ) + (i32.add + (i32.const -10) + (i32.const -11) + ) + (f64.sub + (f64.const -9005.841) + (f64.const -9007.333) + ) + (i32.div_s + (i32.const -10) + (i32.const -11) + ) + (i64.div_u + (i64.const -22) + (i64.const -23) + ) + (i64.rem_s + (i64.const -22) + (i64.const -23) + ) + (i32.rem_u + (i32.const -10) + (i32.const -11) + ) + (i32.and + (i32.const -10) + (i32.const -11) + ) + (i64.or + (i64.const -22) + (i64.const -23) + ) + (i32.xor + (i32.const -10) + (i32.const -11) + ) + (i64.shl + (i64.const -22) + (i64.const -23) + ) + (i64.shr_u + (i64.const -22) + (i64.const -23) + ) + (i32.shr_s + (i32.const -10) + (i32.const -11) + ) + (i32.rotl + (i32.const -10) + (i32.const -11) + ) + (i64.rotr + (i64.const -22) + (i64.const -23) + ) + (f32.div + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.copysign + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f32.min + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.max + (f64.const -9005.841) + (f64.const -9007.333) + ) + (i32.eq + (i32.const -10) + (i32.const -11) + ) + (f32.ne + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (i32.lt_s + (i32.const -10) + (i32.const -11) + ) + (i64.lt_u + (i64.const -22) + (i64.const -23) + ) + (i64.le_s + (i64.const -22) + (i64.const -23) + ) + (i32.le_u + (i32.const -10) + (i32.const -11) + ) + (i64.gt_s + (i64.const -22) + (i64.const -23) + ) + (i32.gt_u + (i32.const -10) + (i32.const -11) + ) + (i32.ge_s + (i32.const -10) + (i32.const -11) + ) + (i64.ge_u + (i64.const -22) + (i64.const -23) + ) + (f32.lt + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.le + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f64.gt + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f32.ge + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (block + ) + (if + (i32.const 1) + (i32.const 2) + (i32.const 3) + ) + (if + (i32.const 4) + (i32.const 5) + ) + (loop $out $in + (i32.const 0) + ) + (loop $in2 + (i32.const 0) + ) + (loop + (i32.const 0) + ) + (br_if $the-value + (i32.const 1) + (i32.const 0) + ) + (br_if $the-nothing + (i32.const 2) + ) + (br $the-value + (i32.const 3) + ) + (br $the-nothing) + (br_table $the-value $the-value + (i32.const 1) + (i32.const 0) + ) + (br_table $the-nothing $the-nothing + (i32.const 2) + ) + (i32.eqz + (call $kitchen-sinker + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (i32.eqz + (i32.trunc_s/f32 + (call_import $an-imported + (i32.const 13) + (f64.const 3.7) + ) + ) + ) + (i32.eqz + (call_indirect $iiIfF + (i32.const 2449) + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (get_local $0) + (set_local $0 + (i32.const 101) + ) + (i32.load + (i32.const 1) + ) + (i64.load8_s offset=2 align=4 + (i32.const 8) + ) + (f32.load + (i32.const 2) + ) + (f64.load offset=2 + (i32.const 9) + ) + (i32.store + (i32.const 10) + (i32.const 11) + ) + (i64.store offset=2 align=4 + (i32.const 110) + (i64.const 111) + ) + (select + (i32.const 3) + (i32.const 5) + (i32.const 1) + ) + (return + (i32.const 1337) + ) + (nop) + (unreachable) ) - (get_local $0) - (set_local $0 - (i32.const 101) - ) - (i32.load - (i32.const 1) - ) - (i64.load8_s offset=2 align=4 - (i32.const 8) - ) - (f32.load - (i32.const 2) - ) - (f64.load offset=2 - (i32.const 9) - ) - (i32.store - (i32.const 10) - (i32.const 11) - ) - (i64.store offset=2 align=4 - (i32.const 110) - (i64.const 111) - ) - (select - (i32.const 3) - (i32.const 5) - (i32.const 1) - ) - (return) - (return - (f32.const 1) - ) - (nop) - (unreachable) ) + (i32.const 42) ) ) (func $starter (type $v) diff --git a/test/llvm_autogenerated/memory-addr64.s b/test/llvm_autogenerated/memory-addr64.s deleted file mode 100644 index 7a8ca3e8e..000000000 --- a/test/llvm_autogenerated/memory-addr64.s +++ /dev/null @@ -1,23 +0,0 @@ - .text - .file "/s/llvm/llvm/test/CodeGen/WebAssembly/memory-addr64.ll" - .globl memory_size - .type memory_size,@function -memory_size: - .result i64 - memory_size $push0= - return $pop0 - .endfunc -.Lfunc_end0: - .size memory_size, .Lfunc_end0-memory_size - - .globl grow_memory - .type grow_memory,@function -grow_memory: - .param i64 - grow_memory $0 - return - .endfunc -.Lfunc_end1: - .size grow_memory, .Lfunc_end1-grow_memory - - diff --git a/test/llvm_autogenerated/memory-addr64.wast b/test/llvm_autogenerated/memory-addr64.wast deleted file mode 100644 index b9b52d85f..000000000 --- a/test/llvm_autogenerated/memory-addr64.wast +++ /dev/null @@ -1,20 +0,0 @@ -(module - (memory 1 - (segment 4 "\10\04\00\00") - ) - (export "memory" memory) - (export "memory_size" $memory_size) - (export "grow_memory" $grow_memory) - (func $memory_size (result i64) - (return - (current_memory) - ) - ) - (func $grow_memory (param $$0 i64) - (grow_memory - (get_local $$0) - ) - (return) - ) -) -;; METADATA: { "asmConsts": {},"staticBump": 1040, "initializers": [] } diff --git a/test/spec b/test/spec -Subproject 3b4a2a969b104915cbc6695c83810f72769ff1b +Subproject 613dd58acfcc97c500dd6a77d88c716225db6e8 |