diff options
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 56 |
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"); |