xref: /llvm-project/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h (revision 69577b2454fcfe35d562ede90c15150f7265376a)
1 //==- WebAssemblyAsmTypeCheck.h - Assembler for WebAssembly -*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file is part of the WebAssembly Assembler.
11 ///
12 /// It contains code to translate a parsed .s file into MCInsts.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_ASMPARSER_TYPECHECK_H
17 #define LLVM_LIB_TARGET_WEBASSEMBLY_ASMPARSER_TYPECHECK_H
18 
19 #include "llvm/BinaryFormat/Wasm.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCParser/MCAsmParser.h"
22 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include <variant>
25 
26 namespace llvm {
27 
28 class WebAssemblyAsmTypeCheck final {
29   MCAsmParser &Parser;
30   const MCInstrInfo &MII;
31 
32   struct Ref : public std::monostate {};
33   struct Any : public std::monostate {};
34   struct Polymorphic : public std::monostate {};
35   using StackType = std::variant<wasm::ValType, Ref, Any, Polymorphic>;
36   SmallVector<StackType, 16> Stack;
37   struct BlockInfo {
38     wasm::WasmSignature Sig;
39     size_t StackStartPos;
40     bool IsLoop;
41   };
42   SmallVector<BlockInfo, 8> BlockInfoStack;
43   SmallVector<wasm::ValType, 16> LocalTypes;
44   wasm::WasmSignature LastSig;
45   bool Is64;
46 
47   // checkTypes checks 'Types' against the value stack. popTypes checks 'Types'
48   // against the value stack and also pops them.
49   //
50   // If ExactMatch is true, 'Types' will be compared against not only the top of
51   // the value stack but the whole remaining value stack
52   // (TODO: This should be the whole remaining value stack "at the the current
53   // block level", which has not been implemented yet)
54   bool checkTypes(SMLoc ErrorLoc, ArrayRef<wasm::ValType> Types,
55                   bool ExactMatch = false);
56   bool checkTypes(SMLoc ErrorLoc, ArrayRef<StackType> Types,
57                   bool ExactMatch = false);
58   bool popTypes(SMLoc ErrorLoc, ArrayRef<wasm::ValType> Types,
59                 bool ExactMatch = false);
60   bool popTypes(SMLoc ErrorLoc, ArrayRef<StackType> Types,
61                 bool ExactMatch = false);
62   bool popType(SMLoc ErrorLoc, StackType Type);
63   bool popRefType(SMLoc ErrorLoc);
64   bool popAnyType(SMLoc ErrorLoc);
65   void pushTypes(ArrayRef<wasm::ValType> Types);
66   void pushType(StackType Type) { Stack.push_back(Type); }
67   bool match(StackType TypeA, StackType TypeB);
68   std::string getTypesString(ArrayRef<wasm::ValType> Types,
69                              size_t StartPos = 0);
70   std::string getTypesString(ArrayRef<StackType> Types, size_t StartPos = 0);
71   SmallVector<StackType, 4>
72   valTypesToStackTypes(ArrayRef<wasm::ValType> ValTypes);
73 
74   void dumpTypeStack(Twine Msg);
75   bool typeError(SMLoc ErrorLoc, const Twine &Msg);
76   bool getLocal(SMLoc ErrorLoc, const MCOperand &LocalOp, wasm::ValType &Type);
77   bool checkSig(SMLoc ErrorLoc, const wasm::WasmSignature &Sig);
78   bool getSymRef(SMLoc ErrorLoc, const MCOperand &SymOp,
79                  const MCSymbolRefExpr *&SymRef);
80   bool getGlobal(SMLoc ErrorLoc, const MCOperand &GlobalOp,
81                  wasm::ValType &Type);
82   bool getTable(SMLoc ErrorLoc, const MCOperand &TableOp, wasm::ValType &Type);
83   bool getSignature(SMLoc ErrorLoc, const MCOperand &SigOp,
84                     wasm::WasmSymbolType Type, const wasm::WasmSignature *&Sig);
85   bool checkTryTable(SMLoc ErrorLoc, const MCInst &Inst);
86 
87 public:
88   WebAssemblyAsmTypeCheck(MCAsmParser &Parser, const MCInstrInfo &MII,
89                           bool Is64);
90 
91   void funcDecl(const wasm::WasmSignature &Sig);
92   void localDecl(const SmallVectorImpl<wasm::ValType> &Locals);
93   void setLastSig(const wasm::WasmSignature &Sig) { LastSig = Sig; }
94   bool endOfFunction(SMLoc ErrorLoc, bool ExactMatch);
95   bool typeCheck(SMLoc ErrorLoc, const MCInst &Inst, OperandVector &Operands);
96 
97   void clear() {
98     Stack.clear();
99     BlockInfoStack.clear();
100     LocalTypes.clear();
101   }
102 };
103 
104 } // end namespace llvm
105 
106 #endif // LLVM_LIB_TARGET_WEBASSEMBLY_ASMPARSER_TYPECHECK_H
107