summaryrefslogtreecommitdiff
path: root/src/ilasm/asmparse.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ilasm/asmparse.h')
-rw-r--r--src/ilasm/asmparse.h326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/ilasm/asmparse.h b/src/ilasm/asmparse.h
new file mode 100644
index 0000000000..3c18f35a75
--- /dev/null
+++ b/src/ilasm/asmparse.h
@@ -0,0 +1,326 @@
+// 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.
+/**************************************************************************/
+/* asmParse is basically a wrapper around a YACC grammer COM+ assembly */
+
+#ifndef asmparse_h
+#define asmparse_h
+
+#include <stdio.h> // for FILE
+
+#include "assembler.h" // for ErrorReporter Labels
+//class Assembler;
+//class BinStr;
+
+
+/**************************************************************************/
+/* an abstraction of a stream of input characters */
+class ReadStream {
+public:
+
+ virtual unsigned getAll(__out char** ppch) = 0;
+
+ // read at most 'buffLen' bytes into 'buff', Return the
+ // number of characters read. On EOF return 0
+ virtual unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen) = 0;
+
+ // Return the name of the stream, (for error reporting).
+ //virtual const char* name() = 0;
+ // Return the Unicode name of the stream
+ virtual const WCHAR* namew() = 0;
+ //return ptr to buffer containing specified source line
+ virtual char* getLine(int lineNum) = 0;
+};
+
+/**************************************************************************/
+class BinStrStream : public ReadStream {
+public:
+ BinStrStream(BinStr* pbs)
+ {
+ m_pStart = (char*)(pbs->ptr());
+ m_pCurr = m_pStart;
+ m_pEnd = m_pStart + pbs->length();
+ m_pBS = pbs;
+ };
+ ~BinStrStream()
+ {
+ //if(m_pBS)
+ // delete m_pBS;
+ };
+ unsigned getAll(__out char **ppbuff)
+ {
+ *ppbuff = m_pStart;
+ return m_pBS->length();
+ };
+ unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
+ {
+ _ASSERTE(m_pStart != NULL);
+ unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
+ unsigned Len = buffLen;
+ if(Len > Remainder) Len = Remainder;
+ memcpy(buff,m_pCurr,Len);
+ m_pCurr += Len;
+ if(Len < buffLen)
+ {
+ memset(buff+Len,0,buffLen-Len);
+ }
+ return Len;
+ }
+
+ const WCHAR* namew()
+ {
+ return W("local_define");
+ }
+
+ BOOL IsValid()
+ {
+ return(m_pStart != NULL);
+ }
+
+ char* getLine(int lineNum)
+ {
+ return NULL; // this function is not used
+ }
+
+private:
+ char* m_pStart;
+ char* m_pEnd;
+ char* m_pCurr;
+ BinStr* m_pBS;
+
+
+};
+/**************************************************************************/
+class MappedFileStream : public ReadStream {
+public:
+ MappedFileStream(__in __nullterminated WCHAR* wFileName)
+ {
+ fileNameW = wFileName;
+ m_hFile = INVALID_HANDLE_VALUE;
+ m_hMapFile = NULL;
+ m_pStart = open(wFileName);
+ m_pCurr = m_pStart;
+ m_pEnd = m_pStart + m_FileSize;
+ //memset(fileNameANSI,0,MAX_FILENAME_LENGTH*4);
+ //WszWideCharToMultiByte(CP_ACP,0,wFileName,-1,fileNameANSI,MAX_FILENAME_LENGTH*4,NULL,NULL);
+ }
+ ~MappedFileStream()
+ {
+ if (m_hFile != INVALID_HANDLE_VALUE)
+ {
+ if (m_pStart)
+ UnmapViewOfFile((void*)m_pStart);
+ if (m_hMapFile)
+ CloseHandle(m_hMapFile);
+ CloseHandle(m_hFile);
+
+ m_pStart = NULL;
+ m_hMapFile = NULL;
+ m_hFile = INVALID_HANDLE_VALUE;
+ m_FileSize = 0;
+ delete [] fileNameW;
+ fileNameW = NULL;
+ }
+ }
+ unsigned getAll(__out char** pbuff)
+ {
+ *pbuff = m_pStart;
+ return m_FileSize;
+ }
+ unsigned read(__out_ecount(buffLen) char* buff, unsigned buffLen)
+ {
+ _ASSERTE(m_pStart != NULL);
+ unsigned Remainder = (unsigned)(m_pEnd - m_pCurr);
+ unsigned Len = buffLen;
+ if(Len > Remainder) Len = Remainder;
+ memcpy(buff,m_pCurr,Len);
+ m_pCurr += Len;
+ if(Len < buffLen)
+ {
+ memset(buff+Len,0,buffLen-Len);
+ }
+ return Len;
+ }
+
+ //const char* name()
+ //{
+ // return(&fileNameANSI[0]);
+ //}
+
+ const WCHAR* namew()
+ {
+ return fileNameW;
+ }
+
+ void set_namew(const WCHAR* namew)
+ {
+ fileNameW = namew;
+ }
+
+ BOOL IsValid()
+ {
+ return(m_pStart != NULL);
+ }
+
+ char* getLine(int lineNum)
+ {
+ return NULL; // this function is not used
+ }
+
+private:
+ char* map_file()
+ {
+ DWORD dwFileSizeLow;
+
+ dwFileSizeLow = GetFileSize( m_hFile, NULL);
+ if (dwFileSizeLow == INVALID_FILE_SIZE)
+ return NULL;
+ m_FileSize = dwFileSizeLow;
+
+ // No difference between A and W in this case: last param (LPCTSTR) is NULL
+ m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (m_hMapFile == NULL)
+ return NULL;
+
+ return (char*)(HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
+ }
+ char* open(const WCHAR* moduleName)
+ {
+ _ASSERTE(moduleName);
+ if (!moduleName)
+ return NULL;
+
+ m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
+ 0, OPEN_EXISTING, 0, 0);
+ return (m_hFile == INVALID_HANDLE_VALUE) ? NULL : map_file();
+ }
+
+ const WCHAR* fileNameW; // FileName (for error reporting)
+ //char fileNameANSI[MAX_FILENAME_LENGTH*4];
+ HANDLE m_hFile; // File we are reading from
+ DWORD m_FileSize;
+ HANDLE m_hMapFile;
+ char* m_pStart;
+ char* m_pEnd;
+ char* m_pCurr;
+
+};
+
+typedef LIFO<ARG_NAME_LIST> ARG_NAME_LIST_STACK;
+
+// functional pointers used in parsing
+/*--------------------------------------------------------------------------*/
+typedef char*(*PFN_NEXTCHAR)(char*);
+
+char* nextcharA(__in __nullterminated char* pos);
+char* nextcharU(__in __nullterminated char* pos);
+char* nextcharW(__in __nullterminated char* pos);
+
+/*--------------------------------------------------------------------------*/
+typedef unsigned(*PFN_SYM)(char*);
+
+unsigned SymAU(__in __nullterminated char* curPos);
+unsigned SymW(__in __nullterminated char* curPos);
+/*--------------------------------------------------------------------------*/
+typedef char*(*PFN_NEWSTRFROMTOKEN)(char*,size_t);
+
+char* NewStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen);
+char* NewStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen);
+/*--------------------------------------------------------------------------*/
+typedef char*(*PFN_NEWSTATICSTRFROMTOKEN)(char*,size_t,char*,size_t);
+
+char* NewStaticStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
+char* NewStaticStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize);
+/*--------------------------------------------------------------------------*/
+typedef unsigned(*PFN_GETDOUBLE)(char*,unsigned,double**);
+
+unsigned GetDoubleAU(__in __nullterminated char* begNum, unsigned L, double** ppRes);
+unsigned GetDoubleW(__in __nullterminated char* begNum, unsigned L, double** ppRes);
+/*--------------------------------------------------------------------------*/
+struct PARSING_ENVIRONMENT
+{
+ char* curTok; // The token we are in the process of processing (for error reporting)
+ char* curPos; // current place in input buffer
+ char* endPos; // points just past the end of valid data in the buffer
+
+ ReadStream* in; // how we fill up our buffer
+
+ PFN_NEXTCHAR pfn_nextchar;
+ PFN_SYM pfn_Sym;
+ PFN_NEWSTRFROMTOKEN pfn_NewStrFromToken;
+ PFN_NEWSTATICSTRFROMTOKEN pfn_NewStaticStrFromToken;
+ PFN_GETDOUBLE pfn_GetDouble;
+
+ bool bExternSource;
+ bool bExternSourceAutoincrement;
+ unsigned nExtLine;
+ unsigned nExtCol;
+ unsigned nExtLineEnd;
+ unsigned nExtColEnd;
+ unsigned curLine; // Line number (for error reporting)
+
+ unsigned uCodePage;
+
+ char szFileName[MAX_FILENAME_LENGTH*3+1];
+
+};
+typedef LIFO<PARSING_ENVIRONMENT> PARSING_ENVIRONMENT_STACK;
+
+/**************************************************************************/
+/* AsmParse does all the parsing. It also builds up simple data structures,
+ (like signatures), but does not do the any 'heavy lifting' like define
+ methods or classes. Instead it calls to the Assembler object to do that */
+
+class AsmParse : public ErrorReporter
+{
+public:
+ AsmParse(ReadStream* stream, Assembler *aAssem);
+ ~AsmParse();
+ void CreateEnvironment(ReadStream* stream);
+ void ParseFile(ReadStream* stream);
+ // The parser knows how to put line numbers on things and report the error
+ virtual void error(const char* fmt, ...);
+ virtual void warn(const char* fmt, ...);
+ virtual void msg(const char* fmt, ...);
+ char *getLine(int lineNum) { return penv->in->getLine(lineNum); };
+ unsigned getAll(__out char** pbuff) { return penv->in->getAll(pbuff); };
+ bool Success() {return success; };
+ void SetIncludePath(__in WCHAR* wz) { wzIncludePath = wz; };
+
+ ARG_NAME_LIST_STACK m_ANSFirst;
+ ARG_NAME_LIST_STACK m_ANSLast;
+ PARSING_ENVIRONMENT *penv;
+ PARSING_ENVIRONMENT_STACK PEStack;
+
+private:
+ BinStr* MakeSig(unsigned callConv, BinStr* retType, BinStr* args, int ntyargs = 0);
+ BinStr* MakeTypeClass(CorElementType kind, mdToken tk);
+ BinStr* MakeTypeArray(CorElementType kind, BinStr* elemType, BinStr* bounds);
+
+ char* fillBuff(__in_opt __nullterminated char* curPos); // refill the input buffer
+ DWORD IsItUnicode(CONST LPVOID pBuff, int cb, LPINT lpi);
+ HANDLE hstdout;
+ HANDLE hstderr;
+
+private:
+ friend void yyerror(__in __nullterminated const char* str);
+ friend int parse_literal(unsigned curSym, __inout __nullterminated char* &curPos, BOOL translate_escapes);
+ friend int yyparse();
+ friend int yylex();
+ friend Instr* SetupInstr(unsigned short opcode);
+ friend int findKeyword(const char* name, size_t nameLen, unsigned short* opcode);
+ friend TypeDefDescr* findTypedef(__in_ecount(nameLen) char* name, size_t nameLen);
+ friend char* skipBlanks(__in __nullterminated char*,unsigned*);
+ friend char* nextBlank(__in __nullterminated char*);
+ friend int ProcessEOF();
+ friend unsigned __int8* skipType(unsigned __int8* ptr, BOOL fFixupType);
+ friend void FixupConstraints();
+
+ Assembler* assem; // This does most of the semantic processing
+ bool success; // overall success of the compilation
+ WCHAR* wzIncludePath;
+};
+
+#endif
+