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