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 | |