summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-s-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r--src/wasm/wasm-s-parser.cpp56
1 files changed, 29 insertions, 27 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 7fd4679b1..1067264f7 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -641,6 +641,16 @@ Type SExpressionWasmBuilder::stringToType(const char* str, bool allowError, bool
throw ParseException("invalid wasm type");
}
+Type SExpressionWasmBuilder::stringToLaneType(const char* str) {
+ if (strcmp(str, "i8x16") == 0) return i32;
+ if (strcmp(str, "i16x8") == 0) return i32;
+ if (strcmp(str, "i32x4") == 0) return i32;
+ if (strcmp(str, "i64x2") == 0) return i64;
+ if (strcmp(str, "f32x4") == 0) return f32;
+ if (strcmp(str, "f64x2") == 0) return f64;
+ return none;
+}
+
Function::DebugLocation SExpressionWasmBuilder::getDebugLocation(const SourceLocation& loc) {
IString file = loc.filename;
auto& debugInfoFileNames = wasm.debugInfoFileNames;
@@ -864,6 +874,20 @@ Expression* SExpressionWasmBuilder::makeThenOrElse(Element& s) {
return ret;
}
+template<int Lanes>
+static Literal makeLanes(Element& s, MixedArena& allocator, Type lane_t) {
+ std::array<Literal, Lanes> lanes;
+ for (size_t i = 0; i < Lanes; ++i) {
+ Expression* lane = parseConst(s[i+2]->str(), lane_t, allocator);
+ if (lane) {
+ lanes[i] = lane->cast<Const>()->value;
+ } else {
+ throw ParseException("Could not parse v128 lane");
+ }
+ }
+ return Literal(lanes);
+}
+
Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) {
if (type != v128) {
auto ret = parseConst(s[1]->str(), type, allocator);
@@ -872,57 +896,35 @@ Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) {
}
auto ret = allocator.alloc<Const>();
- auto getLiteral = [](Expression* expr) {
- if (expr == nullptr) {
- throw ParseException("Could not parse v128 lane");
- }
- return expr->cast<Const>()->value;
- };
- Type lane_t = stringToType(s[1]->str());
+ Type lane_t = stringToLaneType(s[1]->str().str);
size_t lanes = s.size() - 2;
switch (lanes) {
case 2: {
if (lane_t != i64 && lane_t != f64) {
throw ParseException("Unexpected v128 literal lane type");
}
- std::array<Literal, 2> lanes;
- for (size_t i = 0; i < 2; ++i) {
- lanes[i] = getLiteral(parseConst(s[i+2]->str(), lane_t, allocator));
- }
- ret->value = Literal(lanes);
+ ret->value = makeLanes<2>(s, allocator, lane_t);
break;
}
case 4: {
if (lane_t != i32 && lane_t != f32) {
throw ParseException("Unexpected v128 literal lane type");
}
- std::array<Literal, 4> lanes;
- for (size_t i = 0; i < 4; ++i) {
- lanes[i] = getLiteral(parseConst(s[i+2]->str(), lane_t, allocator));
- }
- ret->value = Literal(lanes);
+ ret->value = makeLanes<4>(s, allocator, lane_t);
break;
}
case 8: {
if (lane_t != i32) {
throw ParseException("Unexpected v128 literal lane type");
}
- std::array<Literal, 8> lanes;
- for (size_t i = 0; i < 8; ++i) {
- lanes[i] = getLiteral(parseConst(s[i+2]->str(), lane_t, allocator));
- }
- ret->value = Literal(lanes);
+ ret->value = makeLanes<8>(s, allocator, lane_t);
break;
}
case 16: {
if (lane_t != i32) {
throw ParseException("Unexpected v128 literal lane type");
}
- std::array<Literal, 16> lanes;
- for (size_t i = 0; i < 16; ++i) {
- lanes[i] = getLiteral(parseConst(s[i+2]->str(), lane_t, allocator));
- }
- ret->value = Literal(lanes);
+ ret->value = makeLanes<16>(s, allocator, lane_t);
break;
}
default: throw ParseException("Unexpected number of lanes in v128 literal");