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 */
19class ReadStream {
20public:
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/**************************************************************************/
37class BinStrStream : public ReadStream {
38public:
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
86private:
87 char* m_pStart;
88 char* m_pEnd;
89 char* m_pCurr;
90 BinStr* m_pBS;
91
92
93};
94/**************************************************************************/
95class MappedFileStream : public ReadStream {
96public:
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
171private:
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
210typedef LIFO<ARG_NAME_LIST> ARG_NAME_LIST_STACK;
211
212// functional pointers used in parsing
213/*--------------------------------------------------------------------------*/
214typedef char*(*PFN_NEXTCHAR)(char*);
215
216char* nextcharA(__in __nullterminated char* pos);
217char* nextcharU(__in __nullterminated char* pos);
218char* nextcharW(__in __nullterminated char* pos);
219
220/*--------------------------------------------------------------------------*/
221typedef unsigned(*PFN_SYM)(char*);
222
223unsigned SymAU(__in __nullterminated char* curPos);
224unsigned SymW(__in __nullterminated char* curPos);
225/*--------------------------------------------------------------------------*/
226typedef char*(*PFN_NEWSTRFROMTOKEN)(char*,size_t);
227
228char* NewStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen);
229char* NewStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen);
230/*--------------------------------------------------------------------------*/
231typedef char*(*PFN_NEWSTATICSTRFROMTOKEN)(char*,size_t,char*,size_t);
232
233char* NewStaticStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
234char* NewStaticStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
235/*--------------------------------------------------------------------------*/
236typedef unsigned(*PFN_GETDOUBLE)(char*,unsigned,double**);
237
238unsigned GetDoubleAU(__in __nullterminated char* begNum, unsigned L, double** ppRes);
239unsigned GetDoubleW(__in __nullterminated char* begNum, unsigned L, double** ppRes);
240/*--------------------------------------------------------------------------*/
241struct 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};
268typedef 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
275class AsmParse : public ErrorReporter
276{
277public:
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
296private:
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
306private:
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
327