[PATCH] D52442: [WebAssembly] Fixed AsmParser not allowing instructions with / and :

Wouter van Oortmerssen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 1 10:20:54 PDT 2018


aardappel updated this revision to Diff 167766.
aardappel added a comment.

Addressed review comments, now only fixing / in names.


Repository:
  rL LLVM

https://reviews.llvm.org/D52442

Files:
  lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
  test/MC/WebAssembly/basic-assembly.s


Index: test/MC/WebAssembly/basic-assembly.s
===================================================================
--- test/MC/WebAssembly/basic-assembly.s
+++ test/MC/WebAssembly/basic-assembly.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+sign_ext,+simd128 < %s | FileCheck %s
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+simd128,+nontrapping-fptoint < %s | FileCheck %s
 
     .text
     .type    test0, at function
@@ -42,6 +42,11 @@
     get_local   4
     get_local   5
     f32x4.add
+    # Test correct parsing of instructions with / and : in them:
+    # TODO: enable once instruction has been added.
+    #i32x4.trunc_s/f32x4:sat
+    i32.trunc_s/f32
+    #i32.trunc_s:sat/f32
     end_function
 
 
@@ -81,4 +86,5 @@
 # CHECK-NEXT:      get_local   4
 # CHECK-NEXT:      get_local   5
 # CHECK-NEXT:      f32x4.add
+# CHECK-NEXT:      i32.trunc_s/f32
 # CHECK-NEXT:      end_function
Index: lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
===================================================================
--- lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -227,15 +227,34 @@
 
   bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
                         SMLoc NameLoc, OperandVector &Operands) override {
+    // Note: Name does NOT point into the sourcecode, but to a local, so
+    // use NameLoc instead.
+    Name = StringRef(NameLoc.getPointer(), Name.size());
+    // WebAssembly has instructions with / in them, which AsmLexer parses
+    // as seperate tokens, so if we find such tokens immediately adjacent (no
+    // whitespace), expand the name to include them:
+    for (;;) {
+      auto &Sep = Lexer.getTok();
+      if (Sep.getLoc().getPointer() != Name.end() ||
+          Sep.getKind() != AsmToken::Slash) break;
+      // Extend name with /
+      Name = StringRef(Name.begin(), Name.size() + Sep.getString().size());
+      Parser.Lex();
+      // We must now find another identifier, or error.
+      auto &Id = Lexer.getTok();
+      if (Id.getKind() != AsmToken::Identifier ||
+          Id.getLoc().getPointer() != Name.end())
+        return Error("Incomplete instruction name: ", Id);
+      Name = StringRef(Name.begin(), Name.size() + Id.getString().size());
+      Parser.Lex();
+    }
+    // Now construct the name as first operand.
     Operands.push_back(make_unique<WebAssemblyOperand>(
-        WebAssemblyOperand::Token, NameLoc,
-        SMLoc::getFromPointer(NameLoc.getPointer() + Name.size()),
-        WebAssemblyOperand::TokOp{
-            StringRef(NameLoc.getPointer(), Name.size())}));
+        WebAssemblyOperand::Token, NameLoc, SMLoc::getFromPointer(Name.end()),
+        WebAssemblyOperand::TokOp{Name}));
     auto NamePair = Name.split('.');
     // If no '.', there is no type prefix.
-    if (NamePair.second.empty())
-      std::swap(NamePair.first, NamePair.second);
+    auto BaseName = NamePair.second.empty() ? NamePair.first : NamePair.second;
     while (Lexer.isNot(AsmToken::EndOfStatement)) {
       auto &Tok = Lexer.getTok();
       switch (Tok.getKind()) {
@@ -254,11 +273,11 @@
         Parser.Lex();
         if (Lexer.isNot(AsmToken::Integer))
           return Error("Expected integer instead got: ", Lexer.getTok());
-        if (ParseOperandStartingWithInteger(true, Operands, NamePair.second))
+        if (ParseOperandStartingWithInteger(true, Operands, BaseName))
           return true;
         break;
       case AsmToken::Integer:
-        if (ParseOperandStartingWithInteger(false, Operands, NamePair.second))
+        if (ParseOperandStartingWithInteger(false, Operands, BaseName))
           return true;
         break;
       case AsmToken::Real: {
@@ -284,7 +303,7 @@
     // assembly, so we add a dummy one explicitly (since we have no control
     // over signature tables here, we assume these will be regenerated when
     // the wasm module is generated).
-    if (NamePair.second == "block" || NamePair.second == "loop") {
+    if (BaseName == "block" || BaseName == "loop") {
       Operands.push_back(make_unique<WebAssemblyOperand>(
           WebAssemblyOperand::Integer, NameLoc, NameLoc,
           WebAssemblyOperand::IntOp{-1}));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52442.167766.patch
Type: text/x-patch
Size: 4281 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181001/830af4af/attachment-0001.bin>


More information about the llvm-commits mailing list