Try changing how vector assertions work
diff --git a/src/literal.h b/src/literal.h index 80e58a0..8aa5a4d 100644 --- a/src/literal.h +++ b/src/literal.h
@@ -477,6 +477,7 @@ std::array<Literal, 16> getLanesUI8x16() const; std::array<Literal, 8> getLanesSI16x8() const; std::array<Literal, 8> getLanesUI16x8() const; + std::array<Literal, 4> getLanesUI32x4() const; std::array<Literal, 4> getLanesI32x4() const; std::array<Literal, 2> getLanesI64x2() const; std::array<Literal, 8> getLanesF16x8() const;
diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 5044b36..d8e453e 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp
@@ -169,6 +169,72 @@ } Result<ExpectedResult> result(Lexer& in) { + if (in.takeSExprStart("v128.const"sv)) { + LaneResults lanes; + if (in.takeKeyword("i16x8"sv)) { + for (int i = 0; i < 8; i++) { + auto int_ = in.takeI16(); + if (!int_) { + return in.err("expected i16"); + } + // ??? + lanes.lanes.push_back(Literal(static_cast<int32_t>(*int_))); + } + } else if (in.takeKeyword("i32x4"sv)) { + for (int i = 0; i < 4; i++) { + auto int_ = in.takeI32(); + if (!int_) { + return in.err("expected i32"); + } + lanes.lanes.push_back(Literal(*int_)); + } + } else if (in.takeKeyword("i8x16"sv)) { + for (int i = 0; i < 16; i++) { + auto int_ = in.takeI8(); + if (!int_) { + return in.err("expected i8"); + } + lanes.lanes.push_back(Literal(*int_)); + } + } else if (in.takeKeyword("i64x2"sv)) { + for (int i = 0; i < 2; i++) { + auto int_ = in.takeI64(); + if (!int_) { + return in.err("expected i64"); + } + lanes.lanes.push_back(Literal(*int_)); + } + } else if (in.takeKeyword("f32x4"sv)) { + lanes.isFloat = true; + for (int i = 0; i < 4; ++i) { + if (auto f = in.takeF32()) { + lanes.lanes.push_back(Literal(*f)); + } else { + auto kind = nan(in); + CHECK_ERR(kind); + lanes.lanes.push_back(NaNResult{*kind, Type::f32}); + } + } + } else if (in.takeKeyword("f64x2"sv)) { + lanes.isFloat = true; + for (int i = 0; i < 2; ++i) { + if (auto f = in.takeF64()) { + lanes.lanes.push_back(Literal(*f)); + } else { + auto kind = nan(in); + CHECK_ERR(kind); + lanes.lanes.push_back(NaNResult{*kind, Type::f64}); + } + } + } else { + return in.err("unexpected vector shape"); + } + if (!in.takeRParen()) { + return in.err("expected end of v128.const"); + } + return lanes; + } + Lexer constLexer = in; auto c = const_(constLexer); // TODO: Generating and discarding errors like this can lead to quadratic @@ -198,37 +264,6 @@ return NaNResult{*kind, Type::f64}; } - if (in.takeSExprStart("v128.const"sv)) { - LaneResults lanes; - if (in.takeKeyword("f32x4"sv)) { - for (int i = 0; i < 4; ++i) { - if (auto f = in.takeF32()) { - lanes.push_back(Literal(*f)); - } else { - auto kind = nan(in); - CHECK_ERR(kind); - lanes.push_back(NaNResult{*kind, Type::f32}); - } - } - } else if (in.takeKeyword("f64x2"sv)) { - for (int i = 0; i < 2; ++i) { - if (auto f = in.takeF64()) { - lanes.push_back(Literal(*f)); - } else { - auto kind = nan(in); - CHECK_ERR(kind); - lanes.push_back(NaNResult{*kind, Type::f64}); - } - } - } else { - return in.err("unexpected vector shape"); - } - if (!in.takeRParen()) { - return in.err("expected end of v128.const"); - } - return lanes; - } - if (in.takeSExprStart("ref.null")) { if (!in.takeRParen()) { return in.err("expected end of ref.null");
diff --git a/src/parser/wat-parser.h b/src/parser/wat-parser.h index 380d0f0..54a63ab 100644 --- a/src/parser/wat-parser.h +++ b/src/parser/wat-parser.h
@@ -74,7 +74,11 @@ using LaneResult = std::variant<Literal, NaNResult>; -using LaneResults = std::vector<LaneResult>; +struct LaneResults { + std::vector<LaneResult> lanes; + bool isFloat = false; +}; +// using LaneResults = std::vector<LaneResult>; using ExpectedResult = std::variant<Literal, NullRefResult, RefResult, NaNResult, LaneResults>;
diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 849bc18..ea478de 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp
@@ -364,17 +364,6 @@ if (auto* v = std::get_if<Literal>(&expected)) { if (val != *v) { - if (val.type.isVector() && v->type.isVector() && isAlternative) { - auto valLanes = val.getLanesI32x4(); - auto expLanes = v->getLanesI32x4(); - for (int i = 0; i < 4; ++i) { - if (valLanes[i] != expLanes[i]) { - err << "0x" << std::setfill('0') << std::setw(8) << std::hex - << expLanes[i] << std::dec; - return AlternativeErr{err.str(), i}; - } - } - } err << *v; return AlternativeErr{err.str()}; } @@ -396,10 +385,34 @@ err << e->msg; return AlternativeErr{err.str()}; } - } else if (auto* lanes = std::get_if<LaneResults>(&expected)) { + } else if (auto* l = std::get_if<LaneResults>(&expected)) { + auto* lanes = &l->lanes; switch (lanes->size()) { + case 16: { + auto vals = val.getLanesUI8x16(); + for (int i = 0; i < 16; ++i) { + auto check = checkLane(vals[i], (*lanes)[i]); + if (auto* e = check.getErr()) { + err << e->msg; + return AlternativeErr{err.str(), i}; + } + } + break; + } + case 8: { + auto vals = val.getLanesUI16x8(); + for (int i = 0; i < 8; ++i) { + auto check = checkLane(vals[i], (*lanes)[i]); + if (auto* e = check.getErr()) { + err << e->msg; + return AlternativeErr{err.str(), i}; + } + } + break; + } case 4: { - auto vals = val.getLanesF32x4(); + auto vals = l->isFloat ? val.getLanesF32x4() : val.getLanesUI32x4(); + // auto vals = val.getLanesUI32x4(); for (int i = 0; i < 4; ++i) { auto check = checkLane(vals[i], (*lanes)[i]); if (auto* e = check.getErr()) { @@ -410,7 +423,7 @@ break; } case 2: { - auto vals = val.getLanesF64x2(); + auto vals = l->isFloat ? val.getLanesF64x2() : val.getLanesI64x2(); for (int i = 0; i < 2; ++i) { auto check = checkLane(vals[i], (*lanes)[i]); if (auto* e = check.getErr()) {
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 95a2949..d84986a 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp
@@ -1868,6 +1868,9 @@ LaneArray<8> Literal::getLanesUI16x8() const { return getLanes<uint16_t, 8>(*this); } +LaneArray<4> Literal::getLanesUI32x4() const { + return getLanes<uint32_t, 4>(*this); +} LaneArray<4> Literal::getLanesI32x4() const { return getLanes<int32_t, 4>(*this); }