diff options
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r-- | src/wast-parser.cc | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 353eed36..f2fcf73e 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -583,8 +583,8 @@ TokenTypePair WastParser::PeekPair() { return TokenTypePair{{Peek(), Peek(1)}}; } -bool WastParser::PeekMatch(TokenType type) { - return Peek() == type; +bool WastParser::PeekMatch(TokenType type, size_t n) { + return Peek(n) == type; } bool WastParser::PeekMatchLpar(TokenType type) { @@ -1945,6 +1945,26 @@ Result WastParser::ParseSIMDLoadStoreInstr(Location loc, std::unique_ptr<Expr>* out_expr) { ErrorUnlessOpcodeEnabled(token); + Var memidx(0, loc); + + if (options_->features.multi_memory_enabled()) { + // We have to be a little careful when reading the memeory index. + // If there is just a single integer folloing the instruction that + // represents the lane index, so we check for either a pair of intergers + // or an integers followed by offset= or align=. + bool try_read_mem_index = true; + if (PeekMatch(TokenType::Nat)) { + // The next token could be a memory index or a lane index + if (!PeekMatch(TokenType::OffsetEqNat, 1) && + !PeekMatch(TokenType::AlignEqNat, 1) && + !PeekMatch(TokenType::Nat, 1)) { + try_read_mem_index = false; + } + } + if (try_read_mem_index) { + CHECK_RESULT(ParseMemidx(loc, &memidx)); + } + } Address offset; Address align; ParseOffsetOpt(&offset); @@ -1957,7 +1977,7 @@ Result WastParser::ParseSIMDLoadStoreInstr(Location loc, return Result::Error; } - out_expr->reset(new T(token.opcode(), align, offset, lane_idx, loc)); + out_expr->reset(new T(token.opcode(), memidx, align, offset, lane_idx, loc)); return Result::Ok; } |