2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5 /**************************************************************************/
6 /* asmParse is basically a wrapper around a YACC grammer COM+ assembly */
11 #include <stdio.h> // for FILE
13 #include "assembler.h" // for ErrorReporter Labels
18 /**************************************************************************/
19 /* an abstraction of a stream of input characters */
23 virtual unsigned getAll(__out char** ppch) = 0;
25 // read at most 'buffLen' bytes into 'buff', Return the
26 // number of characters read. On EOF return 0
27 virtual unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen) = 0;
29 // Return the name of the stream, (for error reporting).
30 //virtual const char* name() = 0;
31 // Return the Unicode name of the stream
32 virtual const WCHAR* namew() = 0;
33 //return ptr to buffer containing specified source line
34 virtual char* getLine(int lineNum) = 0;
37 /**************************************************************************/
38 class BinStrStream : public ReadStream {
40 BinStrStream(BinStr* pbs)
42 m_pStart = (char*)(pbs->ptr());
44 m_pEnd = m_pStart + pbs->length();
52 unsigned getAll(__out char **ppbuff)
55 return m_pBS->length();
57 unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
59 _ASSERTE(m_pStart != NULL);
60 unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
61 unsigned Len = buffLen;
62 if(Len > Remainder) Len = Remainder;
63 memcpy(buff,m_pCurr,Len);
67 memset(buff+Len,0,buffLen-Len);
74 return W("local_define");
79 return(m_pStart != NULL);
82 char* getLine(int lineNum)
84 return NULL; // this function is not used
95 /**************************************************************************/
96 class MappedFileStream : public ReadStream {
98 MappedFileStream(__in __nullterminated WCHAR* wFileName)
100 fileNameW = wFileName;
101 m_hFile = INVALID_HANDLE_VALUE;
103 m_pStart = open(wFileName);
105 m_pEnd = m_pStart + m_FileSize;
106 //memset(fileNameANSI,0,MAX_FILENAME_LENGTH*4);
107 //WszWideCharToMultiByte(CP_ACP,0,wFileName,-1,fileNameANSI,MAX_FILENAME_LENGTH*4,NULL,NULL);
111 if (m_hFile != INVALID_HANDLE_VALUE)
114 UnmapViewOfFile((void*)m_pStart);
116 CloseHandle(m_hMapFile);
117 CloseHandle(m_hFile);
121 m_hFile = INVALID_HANDLE_VALUE;
127 unsigned getAll(__out char** pbuff)
132 unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
134 _ASSERTE(m_pStart != NULL);
135 unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
136 unsigned Len = buffLen;
137 if(Len > Remainder) Len = Remainder;
138 memcpy(buff,m_pCurr,Len);
142 memset(buff+Len,0,buffLen-Len);
149 // return(&fileNameANSI[0]);
157 void set_namew(const WCHAR* namew)
164 return(m_pStart != NULL);
167 char* getLine(int lineNum)
169 return NULL; // this function is not used
177 dwFileSizeLow = GetFileSize( m_hFile, NULL);
178 if (dwFileSizeLow == INVALID_FILE_SIZE)
180 m_FileSize = dwFileSizeLow;
182 // No difference between A and W in this case: last param (LPCTSTR) is NULL
183 m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
184 if (m_hMapFile == NULL)
187 return (char*)(HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
189 char* open(const WCHAR* moduleName)
191 _ASSERTE(moduleName);
195 m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
196 0, OPEN_EXISTING, 0, 0);
197 return (m_hFile == INVALID_HANDLE_VALUE) ? NULL : map_file();
200 const WCHAR* fileNameW; // FileName (for error reporting)
201 //char fileNameANSI[MAX_FILENAME_LENGTH*4];
202 HANDLE m_hFile; // File we are reading from
211 typedef LIFO<ARG_NAME_LIST> ARG_NAME_LIST_STACK;
213 // functional pointers used in parsing
214 /*--------------------------------------------------------------------------*/
215 typedef char*(*PFN_NEXTCHAR)(char*);
217 char* nextcharA(__in __nullterminated char* pos);
218 char* nextcharU(__in __nullterminated char* pos);
219 char* nextcharW(__in __nullterminated char* pos);
221 /*--------------------------------------------------------------------------*/
222 typedef unsigned(*PFN_SYM)(char*);
224 unsigned SymAU(__in __nullterminated char* curPos);
225 unsigned SymW(__in __nullterminated char* curPos);
226 /*--------------------------------------------------------------------------*/
227 typedef char*(*PFN_NEWSTRFROMTOKEN)(char*,size_t);
229 char* NewStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen);
230 char* NewStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen);
231 /*--------------------------------------------------------------------------*/
232 typedef char*(*PFN_NEWSTATICSTRFROMTOKEN)(char*,size_t,char*,size_t);
234 char* NewStaticStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
235 char* NewStaticStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
236 /*--------------------------------------------------------------------------*/
237 typedef unsigned(*PFN_GETDOUBLE)(char*,unsigned,double**);
239 unsigned GetDoubleAU(__in __nullterminated char* begNum, unsigned L, double** ppRes);
240 unsigned GetDoubleW(__in __nullterminated char* begNum, unsigned L, double** ppRes);
241 /*--------------------------------------------------------------------------*/
242 struct PARSING_ENVIRONMENT
244 char* curTok; // The token we are in the process of processing (for error reporting)
245 char* curPos; // current place in input buffer
246 char* endPos; // points just past the end of valid data in the buffer
248 ReadStream* in; // how we fill up our buffer
250 PFN_NEXTCHAR pfn_nextchar;
252 PFN_NEWSTRFROMTOKEN pfn_NewStrFromToken;
253 PFN_NEWSTATICSTRFROMTOKEN pfn_NewStaticStrFromToken;
254 PFN_GETDOUBLE pfn_GetDouble;
257 bool bExternSourceAutoincrement;
260 unsigned nExtLineEnd;
262 unsigned curLine; // Line number (for error reporting)
266 char szFileName[MAX_FILENAME_LENGTH*3+1];
269 typedef LIFO<PARSING_ENVIRONMENT> PARSING_ENVIRONMENT_STACK;
271 /**************************************************************************/
272 /* AsmParse does all the parsing. It also builds up simple data structures,
273 (like signatures), but does not do the any 'heavy lifting' like define
274 methods or classes. Instead it calls to the Assembler object to do that */
276 class AsmParse : public ErrorReporter
279 AsmParse(ReadStream* stream, Assembler *aAssem);
281 void CreateEnvironment(ReadStream* stream);
282 void ParseFile(ReadStream* stream);
283 // The parser knows how to put line numbers on things and report the error
284 virtual void error(const char* fmt, ...);
285 virtual void warn(const char* fmt, ...);
286 virtual void msg(const char* fmt, ...);
287 char *getLine(int lineNum) { return penv->in->getLine(lineNum); };
288 unsigned getAll(__out char** pbuff) { return penv->in->getAll(pbuff); };
289 bool Success() {return success; };
290 void SetIncludePath(__in WCHAR* wz) { wzIncludePath = wz; };
292 ARG_NAME_LIST_STACK m_ANSFirst;
293 ARG_NAME_LIST_STACK m_ANSLast;
294 PARSING_ENVIRONMENT *penv;
295 PARSING_ENVIRONMENT_STACK PEStack;
298 BinStr* MakeSig(unsigned callConv, BinStr* retType, BinStr* args, int ntyargs = 0);
299 BinStr* MakeTypeClass(CorElementType kind, mdToken tk);
300 BinStr* MakeTypeArray(CorElementType kind, BinStr* elemType, BinStr* bounds);
302 char* fillBuff(__in_opt __nullterminated char* curPos); // refill the input buffer
303 DWORD IsItUnicode(CONST LPVOID pBuff, int cb, LPINT lpi);
308 friend void yyerror(__in __nullterminated const char* str);
309 friend int parse_literal(unsigned curSym, __inout __nullterminated char* &curPos, BOOL translate_escapes);
310 friend int yyparse();
312 friend Instr* SetupInstr(unsigned short opcode);
313 friend int findKeyword(const char* name, size_t nameLen, unsigned short* opcode);
314 friend TypeDefDescr* findTypedef(__in_ecount(nameLen) char* name, size_t nameLen);
315 friend char* skipBlanks(__in __nullterminated char*,unsigned*);
316 friend char* nextBlank(__in __nullterminated char*);
317 friend int ProcessEOF();
318 friend unsigned __int8* skipType(unsigned __int8* ptr, BOOL fFixupType);
319 friend void FixupConstraints();
321 Assembler* assem; // This does most of the semantic processing
322 bool success; // overall success of the compilation
323 WCHAR* wzIncludePath;