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 */
10 #include <stdio.h> // for FILE
12 #include "assembler.h" // for ErrorReporter Labels
17 /**************************************************************************/
18 /* an abstraction of a stream of input characters */
22 virtual unsigned getAll(__out char** ppch) = 0;
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;
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;
36 /**************************************************************************/
37 class BinStrStream : public ReadStream {
39 BinStrStream(BinStr* pbs)
41 m_pStart = (char*)(pbs->ptr());
43 m_pEnd = m_pStart + pbs->length();
51 unsigned getAll(__out char **ppbuff)
54 return m_pBS->length();
56 unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
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);
66 memset(buff+Len,0,buffLen-Len);
73 return W("local_define");
78 return(m_pStart != NULL);
81 char* getLine(int lineNum)
83 return NULL; // this function is not used
94 /**************************************************************************/
95 class MappedFileStream : public ReadStream {
97 MappedFileStream(__in __nullterminated WCHAR* wFileName)
99 fileNameW = wFileName;
100 m_hFile = INVALID_HANDLE_VALUE;
102 m_pStart = open(wFileName);
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);
110 if (m_hFile != INVALID_HANDLE_VALUE)
113 UnmapViewOfFile((void*)m_pStart);
115 CloseHandle(m_hMapFile);
116 CloseHandle(m_hFile);
120 m_hFile = INVALID_HANDLE_VALUE;
126 unsigned getAll(__out char** pbuff)
131 unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
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);
141 memset(buff+Len,0,buffLen-Len);
148 // return(&fileNameANSI[0]);
156 void set_namew(const WCHAR* namew)
163 return(m_pStart != NULL);
166 char* getLine(int lineNum)
168 return NULL; // this function is not used
176 dwFileSizeLow = GetFileSize( m_hFile, NULL);
177 if (dwFileSizeLow == INVALID_FILE_SIZE)
179 m_FileSize = dwFileSizeLow;
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)
186 return (char*)(HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
188 char* open(const WCHAR* moduleName)
190 _ASSERTE(moduleName);
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();
199 const WCHAR* fileNameW; // FileName (for error reporting)
200 //char fileNameANSI[MAX_FILENAME_LENGTH*4];
201 HANDLE m_hFile; // File we are reading from
210 typedef LIFO<ARG_NAME_LIST> ARG_NAME_LIST_STACK;
212 // functional pointers used in parsing
213 /*--------------------------------------------------------------------------*/
214 typedef char*(*PFN_NEXTCHAR)(char*);
216 char* nextcharA(__in __nullterminated char* pos);
217 char* nextcharU(__in __nullterminated char* pos);
218 char* nextcharW(__in __nullterminated char* pos);
220 /*--------------------------------------------------------------------------*/
221 typedef unsigned(*PFN_SYM)(char*);
223 unsigned SymAU(__in __nullterminated char* curPos);
224 unsigned SymW(__in __nullterminated char* curPos);
225 /*--------------------------------------------------------------------------*/
226 typedef char*(*PFN_NEWSTRFROMTOKEN)(char*,size_t);
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);
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**);
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
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
247 ReadStream* in; // how we fill up our buffer
249 PFN_NEXTCHAR pfn_nextchar;
251 PFN_NEWSTRFROMTOKEN pfn_NewStrFromToken;
252 PFN_NEWSTATICSTRFROMTOKEN pfn_NewStaticStrFromToken;
253 PFN_GETDOUBLE pfn_GetDouble;
256 bool bExternSourceAutoincrement;
259 unsigned nExtLineEnd;
261 unsigned curLine; // Line number (for error reporting)
265 char szFileName[MAX_FILENAME_LENGTH*3+1];
268 typedef LIFO<PARSING_ENVIRONMENT> PARSING_ENVIRONMENT_STACK;
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 */
275 class AsmParse : public ErrorReporter
278 AsmParse(ReadStream* stream, Assembler *aAssem);
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; };
291 ARG_NAME_LIST_STACK m_ANSFirst;
292 ARG_NAME_LIST_STACK m_ANSLast;
293 PARSING_ENVIRONMENT *penv;
294 PARSING_ENVIRONMENT_STACK PEStack;
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);
301 char* fillBuff(__in_opt __nullterminated char* curPos); // refill the input buffer
302 DWORD IsItUnicode(CONST LPVOID pBuff, int cb, LPINT lpi);
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();
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();
320 Assembler* assem; // This does most of the semantic processing
321 bool success; // overall success of the compilation
322 WCHAR* wzIncludePath;