summaryrefslogtreecommitdiff
path: root/src/ilasm/method.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ilasm/method.hpp')
-rw-r--r--src/ilasm/method.hpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/ilasm/method.hpp b/src/ilasm/method.hpp
new file mode 100644
index 0000000000..a70fab43a8
--- /dev/null
+++ b/src/ilasm/method.hpp
@@ -0,0 +1,380 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// method.hpp
+//
+#ifndef _METHOD_HPP
+#define _METHOD_HPP
+
+class Assembler;
+class PermissionDecl;
+class PermissionSetDecl;
+
+#define MAX_EXCEPTIONS 16 // init.number; increased by 16 when needed
+
+extern unsigned int g_uCodePage;
+extern WCHAR wzUniBuf[];
+
+/**************************************************************************/
+struct LinePC
+{
+ ULONG Line;
+ ULONG Column;
+ ULONG LineEnd;
+ ULONG ColumnEnd;
+ ULONG PC;
+ ISymUnmanagedDocumentWriter* pWriter;
+};
+typedef FIFO<LinePC> LinePCList;
+
+
+struct PInvokeDescriptor
+{
+ mdModuleRef mrDll;
+ char* szAlias;
+ DWORD dwAttrs;
+};
+
+struct TokenRelocDescr // for OBJ generation only!
+{
+ DWORD offset;
+ mdToken token;
+ TokenRelocDescr(DWORD off, mdToken tk) { offset = off; token = tk; };
+};
+typedef FIFO<TokenRelocDescr> TRDList;
+/* structure - element of [local] signature name list */
+
+struct ARG_NAME_LIST
+{
+ LPCUTF8 szName; //szName[1024];
+ DWORD dwName;
+ BinStr* pSig; // argument's signature ptr
+ BinStr* pMarshal;
+ BinStr* pValue;
+ int nNum;
+ DWORD dwAttr;
+ CustomDescrList CustDList;
+ ARG_NAME_LIST *pNext;
+ __forceinline ARG_NAME_LIST(int i, LPCUTF8 sz, BinStr *pbSig, BinStr *pbMarsh, DWORD attr)
+ {
+ nNum = i;
+ //dwName = (DWORD)strlen(sz);
+ //strcpy(szName,sz);
+ szName = sz;
+ dwName = (sz == NULL) ? 0 : (DWORD)strlen(sz);
+ pNext = NULL;
+ pSig=pbSig;
+ pMarshal = pbMarsh;
+ dwAttr = attr;
+ pValue=NULL;
+ };
+ inline ~ARG_NAME_LIST()
+ {
+ if(pSig) delete pSig;
+ if(pMarshal) delete pMarshal;
+ if(pValue) delete pValue;
+ if(szName) delete [] szName;
+ }
+};
+
+class Scope;
+typedef FIFO<Scope> ScopeList;
+class Scope
+{
+public:
+ DWORD dwStart;
+ DWORD dwEnd;
+ ARG_NAME_LIST* pLocals;
+ ScopeList SubScope;
+ Scope* pSuperScope;
+ Scope() { dwStart = dwEnd = 0; pLocals = NULL; pSuperScope = NULL; };
+ ~Scope() { Reset(); };
+ void Reset()
+ {
+ ARG_NAME_LIST* pNext;
+ while(pLocals) { pNext = pLocals->pNext; delete pLocals; pLocals = pNext; }
+ Scope* pS;
+ while((pS = SubScope.POP()) != NULL) delete pS;
+ pSuperScope = NULL;
+ dwStart = dwEnd = 0;
+ };
+};
+struct VarDescr
+{
+ DWORD dwSlot;
+ BinStr* pbsSig;
+ BOOL bInScope;
+ VarDescr() { dwSlot = (DWORD) -1; pbsSig = NULL; bInScope = FALSE; };
+};
+typedef FIFO<VarDescr> VarDescrList;
+
+
+struct Label
+{
+//public:
+ LPCUTF8 m_szName;
+ DWORD m_PC;
+
+ Label() :m_szName(NULL),m_PC(0){};
+ Label(LPCUTF8 pszName, DWORD PC):m_szName(pszName),m_PC(PC){};
+ ~Label(){ delete [] m_szName; };
+ int ComparedTo(Label* L) { return strcmp(m_szName,L->m_szName); };
+ //int Compare(char* L) { return strcmp(L,m_szName); };
+ LPCUTF8 NameOf() { return m_szName; };
+};
+//typedef SORTEDARRAY<Label> LabelList;
+typedef FIFO_INDEXED<Label> LabelList;
+
+class GlobalFixup
+{
+public:
+ LPCUTF8 m_szLabel;
+ BYTE * m_pReference; // The place to fix up
+
+ GlobalFixup(LPCUTF8 pszName, BYTE* pReference)
+ {
+ m_pReference = pReference;
+ m_szLabel = pszName;
+ }
+ ~GlobalFixup(){ delete [] m_szLabel; }
+};
+typedef FIFO<GlobalFixup> GlobalFixupList;
+
+
+class Fixup
+{
+public:
+ LPCUTF8 m_szLabel;
+ BYTE * m_pBytes; // where to make the fixup
+ DWORD m_RelativeToPC;
+ BYTE m_FixupSize;
+
+ Fixup(LPCUTF8 pszName, BYTE *pBytes, DWORD RelativeToPC, BYTE FixupSize)
+ {
+ m_pBytes = pBytes;
+ m_RelativeToPC = RelativeToPC;
+ m_FixupSize = FixupSize;
+ m_szLabel = pszName;
+ }
+ ~Fixup(){ delete [] m_szLabel; }
+};
+typedef FIFO<Fixup> FixupList;
+
+typedef enum { ilRVA, ilToken, ilGlobal} ILFixupType;
+
+class ILFixup
+{
+public:
+ ILFixupType m_Kind;
+ DWORD m_OffsetInMethod;
+ GlobalFixup * m_Fixup;
+
+ ILFixup(DWORD Offset, ILFixupType Kind, GlobalFixup *Fix)
+ {
+ m_Kind = Kind;
+ m_OffsetInMethod = Offset;
+ m_Fixup = Fix;
+ }
+};
+typedef FIFO<ILFixup> ILFixupList;
+
+class Method
+{
+public:
+ Class *m_pClass;
+ //BinStr **m_TyParBounds;
+ //LPCWSTR *m_TyParNames;
+ TyParDescr* m_TyPars;
+ DWORD m_NumTyPars;
+ DWORD m_SigInfoCount;
+ USHORT m_MaxStack;
+ mdSignature m_LocalsSig;
+ DWORD m_Flags;
+ char* m_szName;
+ DWORD m_dwName;
+ char* m_szExportAlias;
+ DWORD m_dwExportOrdinal;
+ COR_ILMETHOD_SECT_EH_CLAUSE_FAT *m_ExceptionList;
+ DWORD m_dwNumExceptions;
+ DWORD m_dwMaxNumExceptions;
+ DWORD* m_EndfilterOffsetList;
+ DWORD m_dwNumEndfilters;
+ DWORD m_dwMaxNumEndfilters;
+ DWORD m_Attr;
+ BOOL m_fEntryPoint;
+ BOOL m_fGlobalMethod;
+ BOOL m_fNewBody;
+ BOOL m_fNew;
+ DWORD m_methodOffset;
+ DWORD m_headerOffset;
+ BYTE * m_pCode;
+ DWORD m_CodeSize;
+ WORD m_wImplAttr;
+ ULONG m_ulLines[2];
+ ULONG m_ulColumns[2];
+ // PInvoke attributes
+ PInvokeDescriptor* m_pPInvoke;
+ // Security attributes
+ PermissionDecl* m_pPermissions;
+ PermissionSetDecl* m_pPermissionSets;
+ // VTable attributes
+ WORD m_wVTEntry;
+ WORD m_wVTSlot;
+ // Return marshaling
+ BinStr* m_pRetMarshal;
+ BinStr* m_pRetValue;
+ DWORD m_dwRetAttr;
+ CustomDescrList m_RetCustDList;
+ ILFixupList m_lstILFixup;
+ FixupList m_lstFixup;
+// LabelList m_lstLabel;
+ // Member ref fixups
+ LocalMemberRefFixupList m_LocalMemberRefFixupList;
+ // Method body (header+code+EH)
+ BinStr* m_pbsBody;
+ mdToken m_Tok;
+ Method(Assembler *pAssembler, Class *pClass, __in __nullterminated char *pszName, BinStr* pbsSig, DWORD Attr);
+ ~Method()
+ {
+ m_lstFixup.RESET(true);
+ //m_lstLabel.RESET(true);
+ delete [] m_szName;
+ if(m_szExportAlias) delete [] m_szExportAlias;
+ delArgNameList(m_firstArgName);
+ delArgNameList(m_firstVarName);
+ delete m_pbsMethodSig;
+ delete [] m_ExceptionList;
+ delete [] m_EndfilterOffsetList;
+ if(m_pRetMarshal) delete m_pRetMarshal;
+ if(m_pRetValue) delete m_pRetValue;
+ while(m_MethodImplDList.POP()); // ptrs in m_MethodImplDList are dups of those in Assembler
+ if(m_pbsBody) delete m_pbsBody;
+ if(m_TyPars) delete [] m_TyPars;
+ };
+
+ BOOL IsGlobalMethod()
+ {
+ return m_fGlobalMethod;
+ };
+
+ void SetIsGlobalMethod()
+ {
+ m_fGlobalMethod = TRUE;
+ };
+
+ void delArgNameList(ARG_NAME_LIST *pFirst)
+ {
+ ARG_NAME_LIST *pArgList=pFirst, *pArgListNext;
+ for(; pArgList; pArgListNext=pArgList->pNext,
+ delete pArgList,
+ pArgList=pArgListNext);
+ };
+
+ ARG_NAME_LIST *catArgNameList(ARG_NAME_LIST *pBase, ARG_NAME_LIST *pAdd)
+ {
+ if(pAdd) //even if nothing to concatenate, result == head
+ {
+ ARG_NAME_LIST *pAN = pBase;
+ if(pBase)
+ {
+ int i;
+ for(; pAN->pNext; pAN = pAN->pNext) ;
+ pAN->pNext = pAdd;
+ i = pAN->nNum;
+ for(pAN = pAdd; pAN; pAN->nNum = ++i, pAN = pAN->pNext);
+ }
+ else pBase = pAdd; //nothing to concatenate to, result == tail
+ }
+ return pBase;
+ };
+
+ int findArgNum(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName)
+ {
+ int ret=-1;
+ if(dwArgName)
+ {
+ ARG_NAME_LIST *pAN;
+ for(pAN=pFirst; pAN; pAN = pAN->pNext)
+ {
+ if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName))))
+ {
+ ret = pAN->nNum;
+ break;
+ }
+ }
+ }
+ return ret;
+ };
+
+ int findLocSlot(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName)
+ {
+ int ret=-1;
+ if(dwArgName)
+ {
+ ARG_NAME_LIST *pAN;
+ for(pAN=pFirst; pAN; pAN = pAN->pNext)
+ {
+ if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName))))
+ {
+ ret = (int)(pAN->dwAttr);
+ break;
+ }
+ }
+ }
+ return ret;
+ };
+
+ BinStr *m_pbsMethodSig;
+ COR_SIGNATURE* m_pMethodSig;
+ DWORD m_dwMethodCSig;
+ ARG_NAME_LIST *m_firstArgName;
+ ARG_NAME_LIST *m_firstVarName;
+ // to call error() from Method:
+ const char* m_FileName;
+ unsigned m_LineNum;
+ // debug info
+ LinePCList m_LinePCList;
+ // custom values
+ CustomDescrList m_CustomDescrList;
+ // token relocs (used for OBJ generation only)
+ TRDList m_TRDList;
+ // method's own list of method impls
+ MethodImplDList m_MethodImplDList;
+ // lexical scope handling
+ Assembler* m_pAssembler;
+ Scope m_MainScope;
+ Scope* m_pCurrScope;
+ VarDescrList m_Locals;
+ void OpenScope();
+ void CloseScope();
+
+ Label *FindLabel(LPCUTF8 pszName);
+ Label *FindLabel(DWORD PC);
+
+ int FindTyPar(__in __nullterminated WCHAR* wz)
+ {
+ int i,retval=-1;
+ for(i=0; i < (int)m_NumTyPars; i++)
+ {
+ if(!wcscmp(wz,m_TyPars[i].Name()))
+ {
+ retval = i;
+ }
+ }
+ return retval;
+ };
+ int FindTyPar(__in __nullterminated char* sz)
+ {
+ if(sz)
+ {
+ wzUniBuf[0] = 0;
+ WszMultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf);
+ return FindTyPar(wzUniBuf);
+ }
+ else return -1;
+ };
+};
+
+#endif /* _METHOD_HPP */
+