Merge pull request #24002 from sandreenko/fixDesktopFailure
[platform/upstream/coreclr.git] / src / ilasm / asmparse.h
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 /* asmParse is basically a wrapper around a YACC grammer COM+ assembly  */
6
7 #ifndef asmparse_h
8 #define asmparse_h
9
10 #include <stdio.h>              // for FILE
11
12 #include "assembler.h"  // for ErrorReporter Labels 
13 //class Assembler;
14 //class BinStr;
15
16
17 /**************************************************************************/
18 /* an abstraction of a stream of input characters */
19 class ReadStream {
20 public:
21
22     virtual unsigned getAll(__out char** ppch) = 0;
23
24     // read at most 'buffLen' bytes into 'buff', Return the
25         // number of characters read.  On EOF return 0
26     virtual unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen) = 0;
27         
28         // Return the name of the stream, (for error reporting).  
29     //virtual const char* name() = 0;
30         // Return the Unicode name of the stream  
31     virtual const WCHAR* namew() = 0;
32                 //return ptr to buffer containing specified source line
33         virtual char* getLine(int lineNum) = 0;
34 };
35
36 /**************************************************************************/
37 class BinStrStream : public ReadStream {
38 public:
39     BinStrStream(BinStr* pbs)
40     {
41         m_pStart = (char*)(pbs->ptr());
42         m_pCurr = m_pStart;
43         m_pEnd = m_pStart + pbs->length();
44         m_pBS = pbs;
45     };
46     ~BinStrStream()
47     {
48         //if(m_pBS)
49         //    delete m_pBS;
50     };
51     unsigned getAll(__out char **ppbuff)
52     {
53         *ppbuff = m_pStart;
54         return m_pBS->length();
55     };
56     unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen) 
57     {
58         _ASSERTE(m_pStart != NULL);
59         unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
60         unsigned Len = buffLen;
61         if(Len > Remainder) Len = Remainder;
62         memcpy(buff,m_pCurr,Len);
63         m_pCurr += Len;
64         if(Len < buffLen)
65         {
66             memset(buff+Len,0,buffLen-Len);
67         }
68         return Len;
69     }
70
71     const WCHAR* namew()
72     {
73         return W("local_define");
74     }
75
76     BOOL IsValid()
77     {
78         return(m_pStart != NULL); 
79     }
80     
81         char* getLine(int lineNum)
82         {
83         return NULL; // this function is not used
84         }
85
86 private:
87     char*   m_pStart;
88     char*   m_pEnd;
89     char*   m_pCurr;
90     BinStr* m_pBS;
91
92
93 };
94 /**************************************************************************/
95 class MappedFileStream : public ReadStream {
96 public:
97     MappedFileStream(__in __nullterminated WCHAR* wFileName) 
98     {
99         fileNameW = wFileName;
100         m_hFile = INVALID_HANDLE_VALUE;
101         m_hMapFile = NULL;
102         m_pStart = open(wFileName);
103         m_pCurr = m_pStart;
104         m_pEnd = m_pStart + m_FileSize;
105                 //memset(fileNameANSI,0,MAX_FILENAME_LENGTH*4);
106                 //WszWideCharToMultiByte(CP_ACP,0,wFileName,-1,fileNameANSI,MAX_FILENAME_LENGTH*4,NULL,NULL);
107     }
108     ~MappedFileStream()
109     {
110         if (m_hFile != INVALID_HANDLE_VALUE)
111         {
112             if (m_pStart)
113                 UnmapViewOfFile((void*)m_pStart);
114             if (m_hMapFile)
115                 CloseHandle(m_hMapFile);
116             CloseHandle(m_hFile);
117
118             m_pStart = NULL;
119             m_hMapFile = NULL;
120             m_hFile = INVALID_HANDLE_VALUE;
121             m_FileSize = 0;
122             delete [] fileNameW;
123             fileNameW = NULL;
124         }
125     }
126     unsigned getAll(__out char** pbuff)
127     {
128         *pbuff = m_pStart;
129         return m_FileSize;
130     }
131     unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen) 
132     {
133         _ASSERTE(m_pStart != NULL);
134         unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
135         unsigned Len = buffLen;
136         if(Len > Remainder) Len = Remainder;
137         memcpy(buff,m_pCurr,Len);
138         m_pCurr += Len;
139         if(Len < buffLen)
140         {
141             memset(buff+Len,0,buffLen-Len);
142         }
143         return Len;
144     }
145
146     //const char* name() 
147     //{ 
148     //    return(&fileNameANSI[0]); 
149     //}
150
151     const WCHAR* namew()
152     {
153         return fileNameW;
154     }
155
156     void set_namew(const WCHAR* namew)
157     {
158         fileNameW = namew;
159     }
160
161     BOOL IsValid()
162     {
163         return(m_pStart != NULL); 
164     }
165     
166         char* getLine(int lineNum)
167         {
168         return NULL; // this function is not used
169         }
170
171 private:
172     char* map_file()
173     {
174         DWORD dwFileSizeLow;
175         
176         dwFileSizeLow = GetFileSize( m_hFile, NULL); 
177         if (dwFileSizeLow == INVALID_FILE_SIZE)
178             return NULL;
179         m_FileSize = dwFileSizeLow;
180     
181         // No difference between A and W in this case: last param (LPCTSTR) is NULL
182         m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
183         if (m_hMapFile == NULL)
184             return NULL;
185     
186         return (char*)(HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
187     }
188     char* open(const WCHAR* moduleName)
189     {
190         _ASSERTE(moduleName);
191         if (!moduleName)
192             return NULL;
193     
194         m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
195                              0, OPEN_EXISTING, 0, 0);
196         return (m_hFile == INVALID_HANDLE_VALUE) ? NULL : map_file();
197     }
198
199     const WCHAR* fileNameW;     // FileName (for error reporting)
200         //char  fileNameANSI[MAX_FILENAME_LENGTH*4];
201     HANDLE  m_hFile;                 // File we are reading from
202     DWORD   m_FileSize;
203     HANDLE  m_hMapFile;
204     char*   m_pStart;
205     char*   m_pEnd;
206     char*   m_pCurr;
207
208 };
209
210 typedef LIFO<ARG_NAME_LIST> ARG_NAME_LIST_STACK;
211
212 // functional pointers used in parsing
213 /*--------------------------------------------------------------------------*/
214 typedef char*(*PFN_NEXTCHAR)(char*);
215
216 char* nextcharA(__in __nullterminated char* pos);
217 char* nextcharU(__in __nullterminated char* pos);
218 char* nextcharW(__in __nullterminated char* pos);
219
220 /*--------------------------------------------------------------------------*/
221 typedef unsigned(*PFN_SYM)(char*);
222
223 unsigned SymAU(__in __nullterminated char* curPos);
224 unsigned SymW(__in __nullterminated char* curPos);
225 /*--------------------------------------------------------------------------*/
226 typedef char*(*PFN_NEWSTRFROMTOKEN)(char*,size_t);
227
228 char* NewStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen);
229 char* NewStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen);
230 /*--------------------------------------------------------------------------*/
231 typedef char*(*PFN_NEWSTATICSTRFROMTOKEN)(char*,size_t,char*,size_t);
232
233 char* NewStaticStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
234 char* NewStaticStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
235 /*--------------------------------------------------------------------------*/
236 typedef unsigned(*PFN_GETDOUBLE)(char*,unsigned,double**);
237
238 unsigned GetDoubleAU(__in __nullterminated char* begNum, unsigned L, double** ppRes);
239 unsigned GetDoubleW(__in __nullterminated char* begNum, unsigned L, double** ppRes);
240 /*--------------------------------------------------------------------------*/
241 struct PARSING_ENVIRONMENT
242 {
243     char* curTok;                       // The token we are in the process of processing (for error reporting)
244     char* curPos;               // current place in input buffer
245     char* endPos;                               // points just past the end of valid data in the buffer
246
247     ReadStream* in;             // how we fill up our buffer
248
249     PFN_NEXTCHAR    pfn_nextchar;
250     PFN_SYM         pfn_Sym;
251     PFN_NEWSTRFROMTOKEN pfn_NewStrFromToken;
252     PFN_NEWSTATICSTRFROMTOKEN pfn_NewStaticStrFromToken;
253     PFN_GETDOUBLE   pfn_GetDouble;
254
255     bool bExternSource;
256     bool bExternSourceAutoincrement;
257     unsigned  nExtLine;
258     unsigned  nExtCol;
259     unsigned  nExtLineEnd;
260     unsigned  nExtColEnd;
261     unsigned curLine;           // Line number (for error reporting)
262
263     unsigned  uCodePage;
264
265     char    szFileName[MAX_FILENAME_LENGTH*3+1];
266
267 };
268 typedef LIFO<PARSING_ENVIRONMENT> PARSING_ENVIRONMENT_STACK;
269
270 /**************************************************************************/
271 /* AsmParse does all the parsing.  It also builds up simple data structures,  
272    (like signatures), but does not do the any 'heavy lifting' like define
273    methods or classes.  Instead it calls to the Assembler object to do that */
274
275 class AsmParse : public ErrorReporter 
276 {
277 public:
278     AsmParse(ReadStream* stream, Assembler *aAssem);
279     ~AsmParse();
280     void CreateEnvironment(ReadStream* stream);
281         void ParseFile(ReadStream* stream); 
282         // The parser knows how to put line numbers on things and report the error 
283     virtual void error(const char* fmt, ...);
284     virtual void warn(const char* fmt, ...);
285     virtual void msg(const char* fmt, ...);
286         char *getLine(int lineNum) { return penv->in->getLine(lineNum); };
287     unsigned getAll(__out char** pbuff) { return penv->in->getAll(pbuff); };
288         bool Success() {return success; };
289     void SetIncludePath(__in WCHAR* wz) { wzIncludePath = wz; };
290
291     ARG_NAME_LIST_STACK  m_ANSFirst;
292     ARG_NAME_LIST_STACK  m_ANSLast;
293     PARSING_ENVIRONMENT *penv;
294     PARSING_ENVIRONMENT_STACK   PEStack;
295
296 private:
297     BinStr* MakeSig(unsigned callConv, BinStr* retType, BinStr* args, int ntyargs = 0);
298     BinStr* MakeTypeClass(CorElementType kind, mdToken tk);
299     BinStr* MakeTypeArray(CorElementType kind, BinStr* elemType, BinStr* bounds);
300
301     char* fillBuff(__in_opt __nullterminated char* curPos);   // refill the input buffer
302     DWORD IsItUnicode(CONST LPVOID pBuff, int cb, LPINT lpi);
303         HANDLE  hstdout;
304         HANDLE  hstderr;
305
306 private:
307     friend void yyerror(__in __nullterminated const char* str);
308     friend int parse_literal(unsigned curSym, __inout __nullterminated char* &curPos, BOOL translate_escapes);
309     friend int yyparse();
310     friend int yylex();
311     friend Instr* SetupInstr(unsigned short opcode);
312     friend int findKeyword(const char* name, size_t nameLen, unsigned short* opcode);
313     friend TypeDefDescr* findTypedef(__in_ecount(nameLen) char* name, size_t nameLen);
314     friend char* skipBlanks(__in __nullterminated char*,unsigned*);
315     friend char* nextBlank(__in __nullterminated char*);
316     friend int ProcessEOF();
317     friend unsigned __int8* skipType(unsigned __int8* ptr, BOOL fFixupType);
318     friend void FixupConstraints();
319
320         Assembler* assem;                       // This does most of the semantic processing
321     bool success;               // overall success of the compilation
322     WCHAR* wzIncludePath;
323 };
324
325 #endif
326