| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | // |
| 5 | // method.hpp |
| 6 | // |
| 7 | #ifndef _METHOD_HPP |
| 8 | #define _METHOD_HPP |
| 9 | |
| 10 | class Assembler; |
| 11 | class PermissionDecl; |
| 12 | class PermissionSetDecl; |
| 13 | |
| 14 | #define MAX_EXCEPTIONS 16 // init.number; increased by 16 when needed |
| 15 | |
| 16 | extern unsigned int g_uCodePage; |
| 17 | extern WCHAR wzUniBuf[]; |
| 18 | |
| 19 | /**************************************************************************/ |
| 20 | struct LinePC |
| 21 | { |
| 22 | ULONG Line; |
| 23 | ULONG Column; |
| 24 | ULONG LineEnd; |
| 25 | ULONG ColumnEnd; |
| 26 | ULONG PC; |
| 27 | ISymUnmanagedDocumentWriter* pWriter; |
| 28 | }; |
| 29 | typedef FIFO<LinePC> LinePCList; |
| 30 | |
| 31 | |
| 32 | struct PInvokeDescriptor |
| 33 | { |
| 34 | mdModuleRef mrDll; |
| 35 | char* szAlias; |
| 36 | DWORD dwAttrs; |
| 37 | }; |
| 38 | |
| 39 | struct TokenRelocDescr // for OBJ generation only! |
| 40 | { |
| 41 | DWORD offset; |
| 42 | mdToken token; |
| 43 | TokenRelocDescr(DWORD off, mdToken tk) { offset = off; token = tk; }; |
| 44 | }; |
| 45 | typedef FIFO<TokenRelocDescr> TRDList; |
| 46 | /* structure - element of [local] signature name list */ |
| 47 | |
| 48 | struct ARG_NAME_LIST |
| 49 | { |
| 50 | LPCUTF8 szName; //szName[1024]; |
| 51 | DWORD dwName; |
| 52 | BinStr* pSig; // argument's signature ptr |
| 53 | BinStr* pMarshal; |
| 54 | BinStr* pValue; |
| 55 | int nNum; |
| 56 | DWORD dwAttr; |
| 57 | CustomDescrList CustDList; |
| 58 | ARG_NAME_LIST *pNext; |
| 59 | __forceinline ARG_NAME_LIST(int i, LPCUTF8 sz, BinStr *pbSig, BinStr *pbMarsh, DWORD attr) |
| 60 | { |
| 61 | nNum = i; |
| 62 | //dwName = (DWORD)strlen(sz); |
| 63 | //strcpy(szName,sz); |
| 64 | szName = sz; |
| 65 | dwName = (sz == NULL) ? 0 : (DWORD)strlen(sz); |
| 66 | pNext = NULL; |
| 67 | pSig=pbSig; |
| 68 | pMarshal = pbMarsh; |
| 69 | dwAttr = attr; |
| 70 | pValue=NULL; |
| 71 | }; |
| 72 | inline ~ARG_NAME_LIST() |
| 73 | { |
| 74 | if(pSig) delete pSig; |
| 75 | if(pMarshal) delete pMarshal; |
| 76 | if(pValue) delete pValue; |
| 77 | if(szName) delete [] szName; |
| 78 | } |
| 79 | }; |
| 80 | |
| 81 | class Scope; |
| 82 | typedef FIFO<Scope> ScopeList; |
| 83 | class Scope |
| 84 | { |
| 85 | public: |
| 86 | DWORD dwStart; |
| 87 | DWORD dwEnd; |
| 88 | ARG_NAME_LIST* pLocals; |
| 89 | ScopeList SubScope; |
| 90 | Scope* pSuperScope; |
| 91 | Scope() { dwStart = dwEnd = 0; pLocals = NULL; pSuperScope = NULL; }; |
| 92 | ~Scope() { Reset(); }; |
| 93 | void Reset() |
| 94 | { |
| 95 | ARG_NAME_LIST* pNext; |
| 96 | while(pLocals) { pNext = pLocals->pNext; delete pLocals; pLocals = pNext; } |
| 97 | Scope* pS; |
| 98 | while((pS = SubScope.POP()) != NULL) delete pS; |
| 99 | pSuperScope = NULL; |
| 100 | dwStart = dwEnd = 0; |
| 101 | }; |
| 102 | }; |
| 103 | struct VarDescr |
| 104 | { |
| 105 | DWORD dwSlot; |
| 106 | BinStr* pbsSig; |
| 107 | BOOL bInScope; |
| 108 | VarDescr() { dwSlot = (DWORD) -1; pbsSig = NULL; bInScope = FALSE; }; |
| 109 | }; |
| 110 | typedef FIFO<VarDescr> VarDescrList; |
| 111 | |
| 112 | |
| 113 | struct Label |
| 114 | { |
| 115 | //public: |
| 116 | LPCUTF8 m_szName; |
| 117 | DWORD m_PC; |
| 118 | |
| 119 | Label() :m_szName(NULL),m_PC(0){}; |
| 120 | Label(LPCUTF8 pszName, DWORD PC):m_szName(pszName),m_PC(PC){}; |
| 121 | ~Label(){ delete [] m_szName; }; |
| 122 | int ComparedTo(Label* L) { return strcmp(m_szName,L->m_szName); }; |
| 123 | //int Compare(char* L) { return strcmp(L,m_szName); }; |
| 124 | LPCUTF8 NameOf() { return m_szName; }; |
| 125 | }; |
| 126 | //typedef SORTEDARRAY<Label> LabelList; |
| 127 | typedef FIFO_INDEXED<Label> LabelList; |
| 128 | |
| 129 | class GlobalFixup |
| 130 | { |
| 131 | public: |
| 132 | LPCUTF8 m_szLabel; |
| 133 | BYTE * m_pReference; // The place to fix up |
| 134 | |
| 135 | GlobalFixup(LPCUTF8 pszName, BYTE* pReference) |
| 136 | { |
| 137 | m_pReference = pReference; |
| 138 | m_szLabel = pszName; |
| 139 | } |
| 140 | ~GlobalFixup(){ delete [] m_szLabel; } |
| 141 | }; |
| 142 | typedef FIFO<GlobalFixup> GlobalFixupList; |
| 143 | |
| 144 | |
| 145 | class Fixup |
| 146 | { |
| 147 | public: |
| 148 | LPCUTF8 m_szLabel; |
| 149 | BYTE * m_pBytes; // where to make the fixup |
| 150 | DWORD m_RelativeToPC; |
| 151 | BYTE m_FixupSize; |
| 152 | |
| 153 | Fixup(LPCUTF8 pszName, BYTE *pBytes, DWORD RelativeToPC, BYTE FixupSize) |
| 154 | { |
| 155 | m_pBytes = pBytes; |
| 156 | m_RelativeToPC = RelativeToPC; |
| 157 | m_FixupSize = FixupSize; |
| 158 | m_szLabel = pszName; |
| 159 | } |
| 160 | ~Fixup(){ delete [] m_szLabel; } |
| 161 | }; |
| 162 | typedef FIFO<Fixup> FixupList; |
| 163 | |
| 164 | typedef enum { ilRVA, ilToken, ilGlobal} ILFixupType; |
| 165 | |
| 166 | class ILFixup |
| 167 | { |
| 168 | public: |
| 169 | ILFixupType m_Kind; |
| 170 | DWORD m_OffsetInMethod; |
| 171 | GlobalFixup * m_Fixup; |
| 172 | |
| 173 | ILFixup(DWORD Offset, ILFixupType Kind, GlobalFixup *Fix) |
| 174 | { |
| 175 | m_Kind = Kind; |
| 176 | m_OffsetInMethod = Offset; |
| 177 | m_Fixup = Fix; |
| 178 | } |
| 179 | }; |
| 180 | typedef FIFO<ILFixup> ILFixupList; |
| 181 | |
| 182 | class Method |
| 183 | { |
| 184 | public: |
| 185 | Class *m_pClass; |
| 186 | //BinStr **m_TyParBounds; |
| 187 | //LPCWSTR *m_TyParNames; |
| 188 | TyParDescr* m_TyPars; |
| 189 | DWORD m_NumTyPars; |
| 190 | DWORD m_SigInfoCount; |
| 191 | USHORT m_MaxStack; |
| 192 | mdSignature m_LocalsSig; |
| 193 | DWORD m_Flags; |
| 194 | char* m_szName; |
| 195 | DWORD m_dwName; |
| 196 | char* m_szExportAlias; |
| 197 | DWORD m_dwExportOrdinal; |
| 198 | COR_ILMETHOD_SECT_EH_CLAUSE_FAT *m_ExceptionList; |
| 199 | DWORD m_dwNumExceptions; |
| 200 | DWORD m_dwMaxNumExceptions; |
| 201 | DWORD* m_EndfilterOffsetList; |
| 202 | DWORD m_dwNumEndfilters; |
| 203 | DWORD m_dwMaxNumEndfilters; |
| 204 | DWORD m_Attr; |
| 205 | BOOL m_fEntryPoint; |
| 206 | BOOL m_fGlobalMethod; |
| 207 | BOOL m_fNewBody; |
| 208 | BOOL m_fNew; |
| 209 | DWORD m_methodOffset; |
| 210 | DWORD ; |
| 211 | BYTE * m_pCode; |
| 212 | DWORD m_CodeSize; |
| 213 | WORD m_wImplAttr; |
| 214 | ULONG m_ulLines[2]; |
| 215 | ULONG m_ulColumns[2]; |
| 216 | // PInvoke attributes |
| 217 | PInvokeDescriptor* m_pPInvoke; |
| 218 | // Security attributes |
| 219 | PermissionDecl* m_pPermissions; |
| 220 | PermissionSetDecl* m_pPermissionSets; |
| 221 | // VTable attributes |
| 222 | WORD m_wVTEntry; |
| 223 | WORD m_wVTSlot; |
| 224 | // Return marshaling |
| 225 | BinStr* m_pRetMarshal; |
| 226 | BinStr* m_pRetValue; |
| 227 | DWORD m_dwRetAttr; |
| 228 | CustomDescrList m_RetCustDList; |
| 229 | ILFixupList m_lstILFixup; |
| 230 | FixupList m_lstFixup; |
| 231 | // LabelList m_lstLabel; |
| 232 | // Member ref fixups |
| 233 | LocalMemberRefFixupList m_LocalMemberRefFixupList; |
| 234 | // Method body (header+code+EH) |
| 235 | BinStr* m_pbsBody; |
| 236 | mdToken m_Tok; |
| 237 | Method(Assembler *pAssembler, Class *pClass, __in __nullterminated char *pszName, BinStr* pbsSig, DWORD Attr); |
| 238 | ~Method() |
| 239 | { |
| 240 | m_lstFixup.RESET(true); |
| 241 | //m_lstLabel.RESET(true); |
| 242 | delete [] m_szName; |
| 243 | if(m_szExportAlias) delete [] m_szExportAlias; |
| 244 | delArgNameList(m_firstArgName); |
| 245 | delArgNameList(m_firstVarName); |
| 246 | delete m_pbsMethodSig; |
| 247 | delete [] m_ExceptionList; |
| 248 | delete [] m_EndfilterOffsetList; |
| 249 | if(m_pRetMarshal) delete m_pRetMarshal; |
| 250 | if(m_pRetValue) delete m_pRetValue; |
| 251 | while(m_MethodImplDList.POP()); // ptrs in m_MethodImplDList are dups of those in Assembler |
| 252 | if(m_pbsBody) delete m_pbsBody; |
| 253 | if(m_TyPars) delete [] m_TyPars; |
| 254 | }; |
| 255 | |
| 256 | BOOL IsGlobalMethod() |
| 257 | { |
| 258 | return m_fGlobalMethod; |
| 259 | }; |
| 260 | |
| 261 | void SetIsGlobalMethod() |
| 262 | { |
| 263 | m_fGlobalMethod = TRUE; |
| 264 | }; |
| 265 | |
| 266 | void delArgNameList(ARG_NAME_LIST *pFirst) |
| 267 | { |
| 268 | ARG_NAME_LIST *pArgList=pFirst, *pArgListNext; |
| 269 | for(; pArgList; pArgListNext=pArgList->pNext, |
| 270 | delete pArgList, |
| 271 | pArgList=pArgListNext); |
| 272 | }; |
| 273 | |
| 274 | ARG_NAME_LIST *catArgNameList(ARG_NAME_LIST *pBase, ARG_NAME_LIST *pAdd) |
| 275 | { |
| 276 | if(pAdd) //even if nothing to concatenate, result == head |
| 277 | { |
| 278 | ARG_NAME_LIST *pAN = pBase; |
| 279 | if(pBase) |
| 280 | { |
| 281 | int i; |
| 282 | for(; pAN->pNext; pAN = pAN->pNext) ; |
| 283 | pAN->pNext = pAdd; |
| 284 | i = pAN->nNum; |
| 285 | for(pAN = pAdd; pAN; pAN->nNum = ++i, pAN = pAN->pNext); |
| 286 | } |
| 287 | else pBase = pAdd; //nothing to concatenate to, result == tail |
| 288 | } |
| 289 | return pBase; |
| 290 | }; |
| 291 | |
| 292 | int findArgNum(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName) |
| 293 | { |
| 294 | int ret=-1; |
| 295 | if(dwArgName) |
| 296 | { |
| 297 | ARG_NAME_LIST *pAN; |
| 298 | for(pAN=pFirst; pAN; pAN = pAN->pNext) |
| 299 | { |
| 300 | if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName)))) |
| 301 | { |
| 302 | ret = pAN->nNum; |
| 303 | break; |
| 304 | } |
| 305 | } |
| 306 | } |
| 307 | return ret; |
| 308 | }; |
| 309 | |
| 310 | int findLocSlot(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName) |
| 311 | { |
| 312 | int ret=-1; |
| 313 | if(dwArgName) |
| 314 | { |
| 315 | ARG_NAME_LIST *pAN; |
| 316 | for(pAN=pFirst; pAN; pAN = pAN->pNext) |
| 317 | { |
| 318 | if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName)))) |
| 319 | { |
| 320 | ret = (int)(pAN->dwAttr); |
| 321 | break; |
| 322 | } |
| 323 | } |
| 324 | } |
| 325 | return ret; |
| 326 | }; |
| 327 | |
| 328 | BinStr *m_pbsMethodSig; |
| 329 | COR_SIGNATURE* m_pMethodSig; |
| 330 | DWORD m_dwMethodCSig; |
| 331 | ARG_NAME_LIST *m_firstArgName; |
| 332 | ARG_NAME_LIST *m_firstVarName; |
| 333 | // to call error() from Method: |
| 334 | const char* m_FileName; |
| 335 | unsigned m_LineNum; |
| 336 | // debug info |
| 337 | LinePCList m_LinePCList; |
| 338 | // custom values |
| 339 | CustomDescrList m_CustomDescrList; |
| 340 | // token relocs (used for OBJ generation only) |
| 341 | TRDList m_TRDList; |
| 342 | // method's own list of method impls |
| 343 | MethodImplDList m_MethodImplDList; |
| 344 | // lexical scope handling |
| 345 | Assembler* m_pAssembler; |
| 346 | Scope m_MainScope; |
| 347 | Scope* m_pCurrScope; |
| 348 | VarDescrList m_Locals; |
| 349 | void OpenScope(); |
| 350 | void CloseScope(); |
| 351 | |
| 352 | Label *FindLabel(LPCUTF8 pszName); |
| 353 | Label *FindLabel(DWORD PC); |
| 354 | |
| 355 | int FindTyPar(__in __nullterminated WCHAR* wz) |
| 356 | { |
| 357 | int i,retval=-1; |
| 358 | for(i=0; i < (int)m_NumTyPars; i++) |
| 359 | { |
| 360 | if(!wcscmp(wz,m_TyPars[i].Name())) |
| 361 | { |
| 362 | retval = i; |
| 363 | } |
| 364 | } |
| 365 | return retval; |
| 366 | }; |
| 367 | int FindTyPar(__in __nullterminated char* sz) |
| 368 | { |
| 369 | if(sz) |
| 370 | { |
| 371 | wzUniBuf[0] = 0; |
| 372 | WszMultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf); |
| 373 | return FindTyPar(wzUniBuf); |
| 374 | } |
| 375 | else return -1; |
| 376 | }; |
| 377 | }; |
| 378 | |
| 379 | #endif /* _METHOD_HPP */ |
| 380 | |
| 381 | |