| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 1 | //===-- ReaderInternals.h - Definitions internal to the reader ---*- C++ -*--=// | 
|  | 2 | // | 
|  | 3 | //  This header file defines various stuff that is used by the bytecode reader. | 
|  | 4 | // | 
|  | 5 | //===----------------------------------------------------------------------===// | 
|  | 6 |  | 
|  | 7 | #ifndef READER_INTERNALS_H | 
|  | 8 | #define READER_INTERNALS_H | 
|  | 9 |  | 
|  | 10 | #include "llvm/Bytecode/Primitives.h" | 
|  | 11 | #include "llvm/SymTabValue.h" | 
|  | 12 | #include "llvm/Method.h" | 
|  | 13 | #include "llvm/Instruction.h" | 
|  | 14 | #include <map> | 
|  | 15 | #include <utility> | 
|  | 16 |  | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 17 | // Enable to trace to figure out what the heck is going on when parsing fails | 
|  | 18 | #define TRACE_LEVEL 0 | 
|  | 19 |  | 
|  | 20 | #if TRACE_LEVEL    // ByteCodeReading_TRACEer | 
|  | 21 | #include "llvm/Assembly/Writer.h" | 
|  | 22 | #define BCR_TRACE(n, X) if (n < TRACE_LEVEL) cerr << string(n*2, ' ') << X | 
|  | 23 | #else | 
|  | 24 | #define BCR_TRACE(n, X) | 
|  | 25 | #endif | 
|  | 26 |  | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 27 | class BasicBlock; | 
|  | 28 | class Method; | 
|  | 29 | class Module; | 
|  | 30 | class Type; | 
|  | 31 |  | 
|  | 32 | typedef unsigned char uchar; | 
|  | 33 |  | 
|  | 34 | struct RawInst {       // The raw fields out of the bytecode stream... | 
|  | 35 | unsigned NumOperands; | 
|  | 36 | unsigned Opcode; | 
|  | 37 | const Type *Ty; | 
|  | 38 | unsigned Arg1, Arg2; | 
|  | 39 | union { | 
|  | 40 | unsigned Arg3; | 
|  | 41 | vector<unsigned> *VarArgs;   // Contains arg #3,4,5... if NumOperands > 3 | 
|  | 42 | }; | 
|  | 43 | }; | 
|  | 44 |  | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 45 | class BytecodeParser : public AbstractTypeUser { | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 46 | public: | 
|  | 47 | BytecodeParser() { | 
|  | 48 | // Define this in case we don't see a ModuleGlobalInfo block. | 
|  | 49 | FirstDerivedTyID = Type::FirstDerivedTyID; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | Module *ParseBytecode(const uchar *Buf, const uchar *EndBuf); | 
|  | 53 | private:          // All of this data is transient across calls to ParseBytecode | 
|  | 54 | typedef vector<Value *> ValueList; | 
|  | 55 | typedef vector<ValueList> ValueTable; | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 56 | ValueTable Values, LateResolveValues; | 
|  | 57 | ValueTable ModuleValues, LateResolveModuleValues; | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 58 |  | 
|  | 59 | // TypesLoaded - This vector mirrors the Values[TypeTyID] plane.  It is used | 
|  | 60 | // to deal with forward references to types. | 
|  | 61 | // | 
|  | 62 | typedef vector<PATypeHandle<Type> > TypeValuesListTy; | 
|  | 63 | TypeValuesListTy ModuleTypeValues; | 
|  | 64 | TypeValuesListTy MethodTypeValues; | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 65 |  | 
|  | 66 | // Information read from the ModuleGlobalInfo section of the file... | 
|  | 67 | unsigned FirstDerivedTyID; | 
|  | 68 |  | 
|  | 69 | // When the ModuleGlobalInfo section is read, we load the type of each method | 
|  | 70 | // and the 'ModuleValues' slot that it lands in.  We then load a placeholder | 
|  | 71 | // into its slot to reserve it.  When the method is loaded, this placeholder | 
|  | 72 | // is replaced. | 
|  | 73 | // | 
|  | 74 | list<pair<const MethodType *, unsigned> > MethodSignatureList; | 
|  | 75 |  | 
|  | 76 | private: | 
|  | 77 | bool ParseModule            (const uchar * Buf, const uchar *End, Module *&); | 
|  | 78 | bool ParseModuleGlobalInfo  (const uchar *&Buf, const uchar *End, Module *); | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 79 | bool ParseSymbolTable   (const uchar *&Buf, const uchar *End, SymbolTable *); | 
|  | 80 | bool ParseMethod        (const uchar *&Buf, const uchar *End, Module *); | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 81 | bool ParseBasicBlock    (const uchar *&Buf, const uchar *End, BasicBlock *&); | 
|  | 82 | bool ParseInstruction   (const uchar *&Buf, const uchar *End, Instruction *&); | 
|  | 83 | bool ParseRawInst       (const uchar *&Buf, const uchar *End, RawInst &); | 
|  | 84 |  | 
|  | 85 | bool ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 86 | ValueTable &Tab, TypeValuesListTy &TypeTab); | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 87 | bool parseConstPoolValue(const uchar *&Buf, const uchar *End, | 
|  | 88 | const Type *Ty, ConstPoolVal *&V); | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 89 | bool parseTypeConstants(const uchar *&Buf, const uchar *EndBuf, | 
|  | 90 | TypeValuesListTy &Tab, unsigned NumEntries); | 
|  | 91 | const Type *parseTypeConstant(const uchar *&Buf, const uchar *EndBuf); | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 92 |  | 
|  | 93 | Value      *getValue(const Type *Ty, unsigned num, bool Create = true); | 
|  | 94 | const Type *getType(unsigned ID); | 
|  | 95 |  | 
|  | 96 | bool insertValue(Value *D, vector<ValueList> &D); | 
|  | 97 | bool postResolveValues(ValueTable &ValTab); | 
|  | 98 |  | 
|  | 99 | bool getTypeSlot(const Type *Ty, unsigned &Slot); | 
| Chris Lattner | 1d670cc | 2001-09-07 16:37:43 +0000 | [diff] [blame] | 100 |  | 
|  | 101 |  | 
|  | 102 | // refineAbstractType - The callback method is invoked when one of the | 
|  | 103 | // elements of TypeValues becomes more concrete... | 
|  | 104 | // | 
|  | 105 | virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 106 | }; | 
|  | 107 |  | 
|  | 108 | template<class SuperType> | 
|  | 109 | class PlaceholderDef : public SuperType { | 
|  | 110 | unsigned ID; | 
|  | 111 | public: | 
|  | 112 | PlaceholderDef(const Type *Ty, unsigned id) : SuperType(Ty), ID(id) {} | 
|  | 113 | unsigned getID() { return ID; } | 
|  | 114 | }; | 
|  | 115 |  | 
|  | 116 | struct InstPlaceHolderHelper : public Instruction { | 
|  | 117 | InstPlaceHolderHelper(const Type *Ty) : Instruction(Ty, UserOp1, "") {} | 
| Chris Lattner | a41f50d | 2001-07-07 19:24:15 +0000 | [diff] [blame] | 118 | virtual const char *getOpcodeName() const { return "placeholder"; } | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 119 |  | 
|  | 120 | virtual Instruction *clone() const { abort(); return 0; } | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 121 | }; | 
|  | 122 |  | 
|  | 123 | struct BBPlaceHolderHelper : public BasicBlock { | 
|  | 124 | BBPlaceHolderHelper(const Type *Ty) : BasicBlock() { | 
|  | 125 | assert(Ty->isLabelType()); | 
|  | 126 | } | 
|  | 127 | }; | 
|  | 128 |  | 
|  | 129 | struct MethPlaceHolderHelper : public Method { | 
|  | 130 | MethPlaceHolderHelper(const Type *Ty) | 
|  | 131 | : Method((const MethodType*)Ty) { | 
|  | 132 | assert(Ty->isMethodType() && "Method placeholders must be method types!"); | 
|  | 133 | } | 
|  | 134 | }; | 
|  | 135 |  | 
|  | 136 | typedef PlaceholderDef<InstPlaceHolderHelper>  DefPHolder; | 
|  | 137 | typedef PlaceholderDef<BBPlaceHolderHelper>    BBPHolder; | 
|  | 138 | typedef PlaceholderDef<MethPlaceHolderHelper>  MethPHolder; | 
|  | 139 |  | 
|  | 140 | static inline unsigned getValueIDNumberFromPlaceHolder(Value *Def) { | 
|  | 141 | switch (Def->getType()->getPrimitiveID()) { | 
|  | 142 | case Type::LabelTyID:  return ((BBPHolder*)Def)->getID(); | 
|  | 143 | case Type::MethodTyID: return ((MethPHolder*)Def)->getID(); | 
|  | 144 | default:               return ((DefPHolder*)Def)->getID(); | 
|  | 145 | } | 
|  | 146 | } | 
|  | 147 |  | 
|  | 148 | static inline bool readBlock(const uchar *&Buf, const uchar *EndBuf, | 
|  | 149 | unsigned &Type, unsigned &Size) { | 
|  | 150 | #if DEBUG_OUTPUT | 
|  | 151 | bool Result = read(Buf, EndBuf, Type) || read(Buf, EndBuf, Size); | 
|  | 152 | cerr << "StartLoc = " << ((unsigned)Buf & 4095) | 
|  | 153 | << " Type = " << Type << " Size = " << Size << endl; | 
|  | 154 | return Result; | 
|  | 155 | #else | 
|  | 156 | return read(Buf, EndBuf, Type) || read(Buf, EndBuf, Size); | 
|  | 157 | #endif | 
|  | 158 | } | 
|  | 159 |  | 
| Chris Lattner | 3d3f289 | 2001-07-28 17:50:18 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | // failure Template - This template function is used as a place to put | 
|  | 162 | // breakpoints in to debug failures of the bytecode parser. | 
|  | 163 | // | 
|  | 164 | template <typename X> | 
|  | 165 | static X failure(X Value) { | 
|  | 166 | return Value; | 
|  | 167 | } | 
|  | 168 |  | 
| Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 169 | #endif |