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
10class Assembler;
11class PermissionDecl;
12class PermissionSetDecl;
13
14#define MAX_EXCEPTIONS 16 // init.number; increased by 16 when needed
15
16extern unsigned int g_uCodePage;
17extern WCHAR wzUniBuf[];
18
19/**************************************************************************/
20struct LinePC
21{
22 ULONG Line;
23 ULONG Column;
24 ULONG LineEnd;
25 ULONG ColumnEnd;
26 ULONG PC;
27 ISymUnmanagedDocumentWriter* pWriter;
28};
29typedef FIFO<LinePC> LinePCList;
30
31
32struct PInvokeDescriptor
33{
34 mdModuleRef mrDll;
35 char* szAlias;
36 DWORD dwAttrs;
37};
38
39struct TokenRelocDescr // for OBJ generation only!
40{
41 DWORD offset;
42 mdToken token;
43 TokenRelocDescr(DWORD off, mdToken tk) { offset = off; token = tk; };
44};
45typedef FIFO<TokenRelocDescr> TRDList;
46/* structure - element of [local] signature name list */
47
48struct 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
81class Scope;
82typedef FIFO<Scope> ScopeList;
83class Scope
84{
85public:
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};
103struct VarDescr
104{
105 DWORD dwSlot;
106 BinStr* pbsSig;
107 BOOL bInScope;
108 VarDescr() { dwSlot = (DWORD) -1; pbsSig = NULL; bInScope = FALSE; };
109};
110typedef FIFO<VarDescr> VarDescrList;
111
112
113struct 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;
127typedef FIFO_INDEXED<Label> LabelList;
128
129class GlobalFixup
130{
131public:
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};
142typedef FIFO<GlobalFixup> GlobalFixupList;
143
144
145class Fixup
146{
147public:
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};
162typedef FIFO<Fixup> FixupList;
163
164typedef enum { ilRVA, ilToken, ilGlobal} ILFixupType;
165
166class ILFixup
167{
168public:
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};
180typedef FIFO<ILFixup> ILFixupList;
181
182class Method
183{
184public:
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 m_headerOffset;
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