summaryrefslogtreecommitdiff
path: root/src/ilasm/grammar_after.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ilasm/grammar_after.cpp')
-rw-r--r--src/ilasm/grammar_after.cpp1722
1 files changed, 1722 insertions, 0 deletions
diff --git a/src/ilasm/grammar_after.cpp b/src/ilasm/grammar_after.cpp
new file mode 100644
index 0000000000..c8634801c7
--- /dev/null
+++ b/src/ilasm/grammar_after.cpp
@@ -0,0 +1,1722 @@
+// 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.
+/********************************************************************************/
+/* Code goes here */
+
+/********************************************************************************/
+extern int yyparse();
+
+struct Keywords {
+ const char* name;
+ unsigned short token;
+ unsigned short tokenVal;// this holds the instruction enumeration for those keywords that are instrs
+ size_t stname;
+};
+
+#define NO_VALUE ((unsigned short)-1) // The token has no value
+
+static Keywords keywords[] = {
+// Attention! Because of aliases, the instructions MUST go first!
+// Redefine all the instructions (defined in assembler.h <- asmenum.h <- opcode.def)
+#undef InlineNone
+#undef InlineVar
+#undef ShortInlineVar
+#undef InlineI
+#undef ShortInlineI
+#undef InlineI8
+#undef InlineR
+#undef ShortInlineR
+#undef InlineBrTarget
+#undef ShortInlineBrTarget
+#undef InlineMethod
+#undef InlineField
+#undef InlineType
+#undef InlineString
+#undef InlineSig
+#undef InlineTok
+#undef InlineSwitch
+#undef InlineVarTok
+
+
+#define InlineNone INSTR_NONE
+#define InlineVar INSTR_VAR
+#define ShortInlineVar INSTR_VAR
+#define InlineI INSTR_I
+#define ShortInlineI INSTR_I
+#define InlineI8 INSTR_I8
+#define InlineR INSTR_R
+#define ShortInlineR INSTR_R
+#define InlineBrTarget INSTR_BRTARGET
+#define ShortInlineBrTarget INSTR_BRTARGET
+#define InlineMethod INSTR_METHOD
+#define InlineField INSTR_FIELD
+#define InlineType INSTR_TYPE
+#define InlineString INSTR_STRING
+#define InlineSig INSTR_SIG
+#define InlineTok INSTR_TOK
+#define InlineSwitch INSTR_SWITCH
+
+#define InlineVarTok 0
+#define NEW_INLINE_NAMES
+ // The volatile instruction collides with the volatile keyword, so
+ // we treat it as a keyword everywhere and modify the grammar accordingly (Yuck!)
+#define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) { s, args, c, lengthof(s)-1 },
+#define OPALIAS(alias_c, s, c) { s, NO_VALUE, c, lengthof(s)-1 },
+#include "opcode.def"
+#undef OPALIAS
+#undef OPDEF
+
+ /* keywords */
+#define KYWD(name, sym, val) { name, sym, val, lengthof(name)-1 },
+#include "il_kywd.h"
+#undef KYWD
+
+};
+
+/********************************************************************************/
+/* File encoding-dependent functions */
+/*--------------------------------------------------------------------------*/
+char* nextcharA(__in __nullterminated char* pos)
+{
+ return (*pos > 0) ? ++pos : (char *)_mbsinc((const unsigned char *)pos);
+}
+
+char* nextcharU(__in __nullterminated char* pos)
+{
+ return ++pos;
+}
+
+char* nextcharW(__in __nullterminated char* pos)
+{
+ return (pos+2);
+}
+/*--------------------------------------------------------------------------*/
+unsigned SymAU(__in __nullterminated char* curPos)
+{
+ return (unsigned)*curPos;
+}
+
+unsigned SymW(__in __nullterminated char* curPos)
+{
+ return (unsigned)*((WCHAR*)curPos);
+}
+/*--------------------------------------------------------------------------*/
+char* NewStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen)
+{
+ char *nb = new char[tokLen+1];
+ if(nb != NULL)
+ {
+ memcpy(nb, curTok, tokLen);
+ nb[tokLen] = 0;
+ }
+ return nb;
+}
+char* NewStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen)
+{
+ WCHAR* wcurTok = (WCHAR*)curTok;
+ char *nb = new char[(tokLen<<1) + 2];
+ if(nb != NULL)
+ {
+ tokLen = WszWideCharToMultiByte(CP_UTF8,0,(LPCWSTR)wcurTok,(int)(tokLen >> 1),nb,(int)(tokLen<<1) + 2,NULL,NULL);
+ nb[tokLen] = 0;
+ }
+ return nb;
+}
+/*--------------------------------------------------------------------------*/
+char* NewStaticStrFromTokenAU(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize)
+{
+ if(tokLen >= bufSize) return NULL;
+ memcpy(staticBuf, curTok, tokLen);
+ staticBuf[tokLen] = 0;
+ return staticBuf;
+}
+char* NewStaticStrFromTokenW(__in_ecount(tokLen) char* curTok, size_t tokLen, __out_ecount(bufSize) char* staticBuf, size_t bufSize)
+{
+ WCHAR* wcurTok = (WCHAR*)curTok;
+ if(tokLen >= bufSize/2) return NULL;
+ tokLen = WszWideCharToMultiByte(CP_UTF8,0,(LPCWSTR)wcurTok,(int)(tokLen >> 1),staticBuf,(int)bufSize,NULL,NULL);
+ staticBuf[tokLen] = 0;
+ return staticBuf;
+}
+/*--------------------------------------------------------------------------*/
+unsigned GetDoubleAU(__in __nullterminated char* begNum, unsigned L, double** ppRes)
+{
+ static char dbuff[128];
+ char* pdummy;
+ if(L > 127) L = 127;
+ memcpy(dbuff,begNum,L);
+ dbuff[L] = 0;
+ *ppRes = new double(strtod(dbuff, &pdummy));
+ return ((unsigned)(pdummy - dbuff));
+}
+
+unsigned GetDoubleW(__in __nullterminated char* begNum, unsigned L, double** ppRes)
+{
+ static char dbuff[256];
+ char* pdummy;
+ if(L > 254) L = 254;
+ memcpy(dbuff,begNum,L);
+ dbuff[L] = 0;
+ dbuff[L+1] = 0;
+ *ppRes = new double(wcstod((const wchar_t*)dbuff, (wchar_t**)&pdummy));
+ return ((unsigned)(pdummy - dbuff));
+}
+/*--------------------------------------------------------------------------*/
+char* yygetline(int Line)
+{
+ static char buff[0x4000];
+ char *pLine=NULL, *pNextLine=NULL;
+ char *pBegin=NULL, *pEnd = NULL;
+ unsigned uCount = parser->getAll(&pBegin);
+ pEnd = pBegin + uCount;
+ buff[0] = 0;
+ for(uCount=0, pLine=pBegin; pLine < pEnd; pLine = nextchar(pLine))
+ {
+ if(Sym(pLine) == '\n') uCount++;
+ if(uCount == (unsigned int)(Line-1)) break;
+ }
+ pLine = nextchar(pLine);
+ if(pLine < pEnd)
+ {
+ for(pNextLine = pLine; pNextLine < pEnd; pNextLine = nextchar(pNextLine))
+ {
+ if(Sym(pNextLine) == '\n') break;
+ }
+ if(Sym == SymW) // Unicode file
+ {
+ if(*((WCHAR*)pNextLine - 1) == '\r') pNextLine -= 2;
+ uCount = (unsigned)(pNextLine - pLine);
+ uCount &= 0x1FFF; // limit: 8K wchars
+ WCHAR* wzBuff = (WCHAR*)buff;
+ memcpy(buff,pLine,uCount);
+ wzBuff[uCount >> 1] = 0;
+ }
+ else
+ {
+ if(*(pNextLine-1)=='\r') pNextLine--;
+ uCount = (unsigned)(pNextLine - pLine);
+ uCount &= 0x3FFF; // limit: 16K chars
+ memcpy(buff,pLine,uCount);
+ buff[uCount]=0;
+ }
+ }
+ return buff;
+}
+
+void yyerror(__in __nullterminated const char* str) {
+ char tokBuff[64];
+ WCHAR *wzfile = (WCHAR*)(PENV->in->namew());
+ int iline = PENV->curLine;
+
+ size_t len = PENV->curPos - PENV->curTok;
+ if (len > 62) len = 62;
+ memcpy(tokBuff, PENV->curTok, len);
+ tokBuff[len] = 0;
+ tokBuff[len+1] = 0;
+ if(PENV->bExternSource)
+ {
+ wzfile = PASM->m_wzSourceFileName;
+ iline = PENV->nExtLine;
+ }
+ if(Sym == SymW) // Unicode file
+ fprintf(stderr, "%S(%d) : error : %s at token '%S' in: %S\n",
+ wzfile, iline, str, (WCHAR*)tokBuff, (WCHAR*)yygetline(PENV->curLine));
+ else
+ fprintf(stderr, "%S(%d) : error : %s at token '%s' in: %s\n",
+ wzfile, iline, str, tokBuff, yygetline(PENV->curLine));
+ parser->success = false;
+}
+
+/********************************************************************************/
+/* looks up the typedef 'name' of length 'nameLen' (name does not need to be
+ null terminated) Returns 0 on failure */
+TypeDefDescr* findTypedef(__in_ecount(NameLen) char* name, size_t NameLen)
+{
+ TypeDefDescr* pRet = NULL;
+ static char Name[4096];
+ if(PASM->NumTypeDefs())
+ {
+ if(NewStaticStrFromToken(name,NameLen,Name,4096))
+ pRet = PASM->FindTypeDef(Name);
+ }
+ return pRet;
+}
+
+int TYPEDEF(TypeDefDescr* pTDD)
+{
+ switch(TypeFromToken(pTDD->m_tkTypeSpec))
+ {
+ case mdtTypeDef:
+ case mdtTypeRef:
+ return TYPEDEF_T;
+ case mdtMethodDef:
+ case 0x99000000:
+ return TYPEDEF_M;
+ case mdtFieldDef:
+ case 0x98000000:
+ return TYPEDEF_F;
+ case mdtMemberRef:
+ return TYPEDEF_MR;
+ case mdtTypeSpec:
+ return TYPEDEF_TS;
+ case mdtCustomAttribute:
+ return TYPEDEF_CA;
+ }
+ return ERROR_;
+
+}
+
+/********************************************************************************/
+void indexKeywords(Indx* indx) // called in Assembler constructor (assem.cpp)
+{
+ Keywords* low = keywords;
+ Keywords* high = keywords + (sizeof(keywords) / sizeof(Keywords));
+ Keywords* mid;
+ for(mid = low; mid < high; mid++)
+ {
+ indx->IndexString((char*)(mid->name),mid);
+ }
+}
+
+Instr* SetupInstr(unsigned short opcode)
+{
+ Instr* pVal = NULL;
+ if((pVal = PASM->GetInstr()))
+ {
+ pVal->opcode = opcode;
+ if((pVal->pWriter = PASM->m_pSymDocument)!=NULL)
+ {
+ if(PENV->bExternSource)
+ {
+ pVal->linenum = PENV->nExtLine;
+ pVal->column = PENV->nExtCol;
+ pVal->linenum_end = PENV->nExtLineEnd;
+ pVal->column_end = PENV->nExtColEnd;
+ pVal->pc = nCurrPC;
+ }
+ else
+ {
+ pVal->linenum = PENV->curLine;
+ pVal->column = 1;
+ pVal->linenum_end = PENV->curLine;
+ pVal->column_end = 0;
+ pVal->pc = PASM->m_CurPC;
+ }
+ }
+ }
+ return pVal;
+}
+/* looks up the keyword 'name' of length 'nameLen' (name does not need to be
+ null terminated) Returns 0 on failure */
+int findKeyword(const char* name, size_t nameLen, unsigned short* pOpcode)
+{
+ static char Name[128];
+ Keywords* mid;
+
+ if(NULL == NewStaticStrFromToken((char*)name,nameLen,Name,128)) return 0; // can't be a keyword
+ mid = (Keywords*)(PASM->indxKeywords.FindString(Name));
+ if(mid == NULL) return 0;
+ *pOpcode = mid->tokenVal;
+
+ return(mid->token);
+}
+
+/********************************************************************************/
+/* convert str to a uint64 */
+unsigned digits[128];
+void Init_str2uint64()
+{
+ int i;
+ memset(digits,255,sizeof(digits));
+ for(i='0'; i <= '9'; i++) digits[i] = i - '0';
+ for(i='A'; i <= 'Z'; i++) digits[i] = i + 10 - 'A';
+ for(i='a'; i <= 'z'; i++) digits[i] = i + 10 - 'a';
+}
+static unsigned __int64 str2uint64(const char* str, const char** endStr, unsigned radix)
+{
+ unsigned __int64 ret = 0;
+ unsigned digit,ix;
+ _ASSERTE(radix <= 36);
+ for(;;str = nextchar((char*)str))
+ {
+ ix = Sym((char*)str);
+ if(ix <= 0x7F)
+ {
+ digit = digits[ix];
+ if(digit < radix)
+ {
+ ret = ret * radix + digit;
+ continue;
+ }
+ }
+ *endStr = str;
+ return(ret);
+ }
+}
+/********************************************************************************/
+/* Append an UTF-8 string preceded by compressed length, no zero terminator, to a BinStr */
+static void AppendStringWithLength(BinStr* pbs, __in __nullterminated char* sz)
+{
+ if((pbs != NULL) && (sz != NULL))
+ {
+ unsigned L = (unsigned) strlen(sz);
+ BYTE* pb = NULL;
+ corEmitInt(pbs,L);
+ if((pb = pbs->getBuff(L)) != NULL)
+ memcpy(pb,sz,L);
+ }
+}
+
+/********************************************************************************/
+/* fetch the next token, and return it Also set the yylval.union if the
+ lexical token also has a value */
+
+#if (0)
+
+#define IsAlpha(x) ((('A' <= (x))&&((x) <= 'Z'))||(('a' <= (x))&&((x) <= 'z')))
+#define IsDigit(x) (('0' <= (x))&&((x) <= '9'))
+#define IsAlNum(x) (IsAlpha(x) || IsDigit(x))
+#define IsValidStartingSymbol(x) (IsAlpha(x)||((x)=='#')||((x)=='_')||((x)=='@')||((x)=='$'))
+#define IsValidContinuingSymbol(x) (IsAlNum(x)||((x)=='_')||((x)=='@')||((x)=='$')||((x)=='?'))
+void SetSymbolTables() { ; }
+
+#else
+
+BOOL _Alpha[128];
+BOOL _Digit[128];
+BOOL _AlNum[128];
+BOOL _ValidSS[128];
+BOOL _ValidCS[128];
+void SetSymbolTables()
+{
+ unsigned i;
+ memset(_Alpha,0,sizeof(_Alpha));
+ memset(_Digit,0,sizeof(_Digit));
+ memset(_AlNum,0,sizeof(_AlNum));
+ memset(_ValidSS,0,sizeof(_ValidSS));
+ memset(_ValidCS,0,sizeof(_ValidCS));
+ for(i = 'A'; i <= 'Z'; i++)
+ {
+ _Alpha[i] = TRUE;
+ _AlNum[i] = TRUE;
+ _ValidSS[i] = TRUE;
+ _ValidCS[i] = TRUE;
+ }
+ for(i = 'a'; i <= 'z'; i++)
+ {
+ _Alpha[i] = TRUE;
+ _AlNum[i] = TRUE;
+ _ValidSS[i] = TRUE;
+ _ValidCS[i] = TRUE;
+ }
+ for(i = '0'; i <= '9'; i++)
+ {
+ _Digit[i] = TRUE;
+ _AlNum[i] = TRUE;
+ _ValidCS[i] = TRUE;
+ }
+ _ValidSS[(unsigned char)'_'] = TRUE;
+ _ValidSS[(unsigned char)'#'] = TRUE;
+ _ValidSS[(unsigned char)'$'] = TRUE;
+ _ValidSS[(unsigned char)'@'] = TRUE;
+
+ _ValidCS[(unsigned char)'_'] = TRUE;
+ _ValidCS[(unsigned char)'?'] = TRUE;
+ _ValidCS[(unsigned char)'$'] = TRUE;
+ _ValidCS[(unsigned char)'@'] = TRUE;
+ _ValidCS[(unsigned char)'`'] = TRUE;
+}
+BOOL IsAlpha(unsigned x) { return (x < 128)&&_Alpha[x]; }
+BOOL IsDigit(unsigned x) { return (x < 128)&&_Digit[x]; }
+BOOL IsAlNum(unsigned x) { return (x < 128)&&_AlNum[x]; }
+BOOL IsValidStartingSymbol(unsigned x) { return (x < 128)&&_ValidSS[x]; }
+BOOL IsValidContinuingSymbol(unsigned x) { return (x < 128)&&_ValidCS[x]; }
+
+#endif
+
+char* nextBlank(__in __nullterminated char* curPos)
+{
+ for(;;)
+ {
+ switch(Sym(curPos))
+ {
+ case '/' :
+ if ((Sym(nextchar(curPos)) == '/')|| (Sym(nextchar(curPos)) == '*'))
+ return curPos;
+ else
+ {
+ curPos = nextchar(curPos);
+ break;
+ }
+ case 0:
+ case '\n':
+ case '\r':
+ case ' ' :
+ case '\t':
+ case '\f':
+ return curPos;
+
+ default:
+ curPos = nextchar(curPos);
+ }
+ }
+}
+
+char* skipBlanks(__in __nullterminated char* curPos, unsigned* pstate)
+{
+ const unsigned eolComment = 1;
+ const unsigned multiComment = 2;
+ unsigned nextSym, state = *pstate;
+ char* nextPos;
+ for(;;)
+ { // skip whitespace and comments
+ if (curPos >= PENV->endPos)
+ {
+ *pstate = state;
+ return NULL;
+ }
+ switch(Sym(curPos))
+ {
+ case 0:
+ return NULL; // EOF
+ case '\n':
+ state &= ~eolComment;
+ PENV->curLine++;
+ if(PENV->bExternSource)
+ {
+ if(PENV->bExternSourceAutoincrement) PENV->nExtLine++;
+ PASM->m_ulCurLine = PENV->nExtLine;
+ PASM->m_ulCurColumn = PENV->nExtCol;
+ }
+ else
+ {
+ PASM->m_ulCurLine = PENV->curLine;
+ PASM->m_ulCurColumn = 1;
+ }
+ break;
+ case '\r':
+ case ' ' :
+ case '\t':
+ case '\f':
+ break;
+
+ case '*' :
+ if(state == 0) goto PAST_WHITESPACE;
+ if(state & multiComment)
+ {
+ nextPos = nextchar(curPos);
+ if (Sym(nextPos) == '/')
+ {
+ curPos = nextPos;
+ state &= ~multiComment;
+ }
+ }
+ break;
+
+ case '/' :
+ if(state == 0)
+ {
+ nextPos = nextchar(curPos);
+ nextSym = Sym(nextPos);
+ if (nextSym == '/')
+ {
+ curPos = nextPos;
+ state |= eolComment;
+ }
+ else if (nextSym == '*')
+ {
+ curPos = nextPos;
+ state |= multiComment;
+ }
+ else goto PAST_WHITESPACE;
+ }
+ break;
+
+ default:
+ if (state == 0) goto PAST_WHITESPACE;
+ }
+ curPos = nextchar(curPos);
+ }
+PAST_WHITESPACE:
+ *pstate = state;
+ return curPos;
+}
+
+char* FullFileName(__in __nullterminated WCHAR* wzFileName, unsigned uCodePage);
+
+int ProcessEOF()
+{
+ PARSING_ENVIRONMENT* prev_penv = parser->PEStack.POP();
+ if(prev_penv != NULL)
+ {
+ //delete [] (WCHAR*)(PENV->in->namew());
+ delete PENV->in;
+ delete PENV;
+ parser->penv = prev_penv;
+ SetFunctionPtrs();
+ char* szFileName = new char[strlen(PENV->szFileName)+1];
+ strcpy_s(szFileName,strlen(PENV->szFileName)+1,PENV->szFileName);
+ PASM->SetSourceFileName(szFileName); // deletes the argument!
+ return ';';
+ }
+ //PENV->in = NULL;
+ return 0;
+}
+
+#define NEXT_TOKEN {state=0; curPos=PENV->curPos; goto NextToken;}
+
+int parse_literal(unsigned curSym, __inout __nullterminated char* &curPos, BOOL translate_escapes)
+{
+ unsigned quote = curSym;
+ curPos = nextchar(curPos);
+ char* fromPtr = curPos;
+ bool escape = false;
+
+ for(;;)
+ { // Find matching quote
+ curSym = (curPos >= PENV->endPos) ? 0 : Sym(curPos);
+ if(curSym == 0)
+ {
+ PENV->curPos = curPos;
+ return(BAD_LITERAL_);
+ }
+ else if(curSym == '\\')
+ escape = !escape;
+ else
+ {
+ if(curSym == '\n')
+ {
+ PENV->curLine++;
+ if(PENV->bExternSource)
+ {
+ if(PENV->bExternSourceAutoincrement) PENV->nExtLine++;
+ PASM->m_ulCurLine = PENV->nExtLine;
+ PASM->m_ulCurColumn = PENV->nExtCol;
+ }
+ else
+ {
+ PASM->m_ulCurLine = PENV->curLine;
+ PASM->m_ulCurColumn = 1;
+ }
+ if (!escape) { PENV->curPos = curPos; return(BAD_LITERAL_); }
+ }
+ else if ((curSym == quote) && (!escape)) break;
+ escape = false;
+ }
+ curPos = nextchar(curPos);
+ }
+ // translate escaped characters
+ unsigned tokLen = (unsigned)(curPos - fromPtr);
+ char* newstr = NewStrFromToken(fromPtr, tokLen);
+ char* toPtr;
+ curPos = nextchar(curPos); // skip closing quote
+ if(translate_escapes)
+ {
+ fromPtr = newstr;
+ //_ASSERTE(0);
+ tokLen = (unsigned)strlen(newstr);
+ toPtr = new char[tokLen+1];
+ if(toPtr==NULL) return BAD_LITERAL_;
+ yylval.string = toPtr;
+ char* endPtr = fromPtr+tokLen;
+ while(fromPtr < endPtr)
+ {
+ if (*fromPtr == '\\')
+ {
+ fromPtr++;
+ switch(*fromPtr)
+ {
+ case 't':
+ *toPtr++ = '\t';
+ break;
+ case 'n':
+ *toPtr++ = '\n';
+ break;
+ case 'b':
+ *toPtr++ = '\b';
+ break;
+ case 'f':
+ *toPtr++ = '\f';
+ break;
+ case 'v':
+ *toPtr++ = '\v';
+ break;
+ case '?':
+ *toPtr++ = '\?';
+ break;
+ case 'r':
+ *toPtr++ = '\r';
+ break;
+ case 'a':
+ *toPtr++ = '\a';
+ break;
+ case '\n':
+ do fromPtr++;
+ while(isspace(*fromPtr));
+ --fromPtr; // undo the increment below
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ if (IsDigit(fromPtr[1]) && IsDigit(fromPtr[2]))
+ {
+ *toPtr++ = ((fromPtr[0] - '0') * 8 + (fromPtr[1] - '0')) * 8 + (fromPtr[2] - '0');
+ fromPtr+= 2;
+ }
+ else if(*fromPtr == '0') *toPtr++ = 0;
+ else *toPtr++ = *fromPtr;
+ break;
+ default:
+ *toPtr++ = *fromPtr;
+ }
+ fromPtr++;
+ }
+ else
+ // *toPtr++ = *fromPtr++;
+ {
+ char* tmpPtr = fromPtr;
+ fromPtr = (nextchar == nextcharW) ? nextcharU(fromPtr) : nextchar(fromPtr);
+ while(tmpPtr < fromPtr) *toPtr++ = *tmpPtr++;
+ }
+
+ } //end while(fromPtr < endPtr)
+ *toPtr = 0; // terminate string
+ delete [] newstr;
+ }
+ else
+ {
+ yylval.string = newstr;
+ toPtr = newstr + strlen(newstr);
+ }
+
+ PENV->curPos = curPos;
+ if(quote == '"')
+ {
+ BinStr* pBS = new BinStr();
+ unsigned size = (unsigned)(toPtr - yylval.string);
+ memcpy(pBS->getBuff(size),yylval.string,size);
+ delete [] yylval.string;
+ yylval.binstr = pBS;
+ return QSTRING;
+ }
+ else
+ {
+ if(PASM->NumTypeDefs())
+ {
+ TypeDefDescr* pTDD = PASM->FindTypeDef(yylval.string);
+ if(pTDD != NULL)
+ {
+ delete [] yylval.string;
+ yylval.tdd = pTDD;
+ return(TYPEDEF(pTDD));
+ }
+ }
+ return SQSTRING;
+ }
+}
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
+int yylex()
+{
+ char* curPos = PENV->curPos;
+ unsigned state = 0;
+ const unsigned multiComment = 2;
+ unsigned curSym;
+
+ char* newstr;
+
+NextToken:
+ // Skip any leading whitespace and comments
+ curPos = skipBlanks(curPos, &state);
+ if(curPos == NULL)
+ {
+ if (state & multiComment) return (BAD_COMMENT_);
+ if(ProcessEOF() == 0) return 0; // EOF
+ NEXT_TOKEN;
+ }
+ char* curTok = curPos;
+ PENV->curTok = curPos;
+ PENV->curPos = curPos;
+ int tok = ERROR_;
+ yylval.string = 0;
+
+ curSym = Sym(curPos);
+ if(bParsingByteArray) // only hexadecimals w/o 0x, ')' and white space allowed!
+ {
+ int i,s=0;
+ for(i=0; i<2; i++, curPos = nextchar(curPos), curSym = Sym(curPos))
+ {
+ if(('0' <= curSym)&&(curSym <= '9')) s = s*16+(curSym - '0');
+ else if(('A' <= curSym)&&(curSym <= 'F')) s = s*16+(curSym - 'A' + 10);
+ else if(('a' <= curSym)&&(curSym <= 'f')) s = s*16+(curSym - 'a' + 10);
+ else break; // don't increase curPos!
+ }
+ if(i)
+ {
+ tok = HEXBYTE;
+ yylval.int32 = s;
+ }
+ else
+ {
+ if(curSym == ')' || curSym == '}')
+ {
+ bParsingByteArray = FALSE;
+ goto Just_A_Character;
+ }
+ }
+ PENV->curPos = curPos;
+ return(tok);
+ }
+ if(curSym == '?') // '?' may be part of an identifier, if it's not followed by punctuation
+ {
+ if(IsValidContinuingSymbol(Sym(nextchar(curPos)))) goto Its_An_Id;
+ goto Just_A_Character;
+ }
+
+ if (IsValidStartingSymbol(curSym))
+ { // is it an ID
+Its_An_Id:
+ size_t offsetDot = (size_t)-1; // first appearance of '.'
+ size_t offsetDotDigit = (size_t)-1; // first appearance of '.<digit>' (not DOTTEDNAME!)
+ do
+ {
+ curPos = nextchar(curPos);
+ if (Sym(curPos) == '.')
+ {
+ if (offsetDot == (size_t)-1) offsetDot = curPos - curTok;
+ curPos = nextchar(curPos);
+ if((offsetDotDigit==(size_t)-1)&&(Sym(curPos) >= '0')&&(Sym(curPos) <= '9'))
+ offsetDotDigit = curPos - curTok - 1;
+ }
+ } while(IsValidContinuingSymbol(Sym(curPos)));
+
+ size_t tokLen = curPos - curTok;
+ // check to see if it is a keyword
+ int token = findKeyword(curTok, tokLen, &yylval.opcode);
+ if (token != 0)
+ {
+ //printf("yylex: TOK = %d, curPos=0x%8.8X\n",token,curPos);
+ PENV->curPos = curPos;
+ PENV->curTok = curTok;
+ if(!SkipToken)
+ {
+ switch(token)
+ {
+ case P_INCLUDE:
+ //if(include_first_pass)
+ //{
+ // PENV->curPos = curTok;
+ // include_first_pass = FALSE;
+ // return ';';
+ //}
+ //include_first_pass = TRUE;
+ curPos = skipBlanks(curPos,&state);
+ if(curPos == NULL)
+ {
+ if (state & multiComment) return (BAD_COMMENT_);
+ if(ProcessEOF() == 0) return 0; // EOF
+ NEXT_TOKEN;
+ }
+ if(Sym(curPos) != '"') return ERROR_;
+ curPos = nextchar(curPos);
+ curTok = curPos;
+ PENV->curTok = curPos;
+ while(Sym(curPos) != '"')
+ {
+ curPos = nextchar(curPos);
+ if(curPos >= PENV->endPos) return ERROR_;
+ PENV->curPos = curPos;
+ }
+ tokLen = PENV->curPos - curTok;
+ curPos = nextchar(curPos);
+ PENV->curPos = curPos;
+ {
+ WCHAR* wzFile=NULL;
+ if(Sym == SymW)
+ {
+ if((wzFile = new WCHAR[tokLen/2 + 1]) != NULL)
+ {
+ memcpy(wzFile,curTok,tokLen);
+ wzFile[tokLen/2] = 0;
+ }
+ }
+ else
+ {
+ if((wzFile = new WCHAR[tokLen+1]) != NULL)
+ {
+ tokLen = WszMultiByteToWideChar(g_uCodePage,0,curTok,(int)tokLen,wzFile,(int)tokLen+1);
+ wzFile[tokLen] = 0;
+ }
+ }
+ if(wzFile != NULL)
+ {
+ if((parser->wzIncludePath != NULL)
+ &&(wcschr(wzFile,'\\')==NULL)&&(wcschr(wzFile,':')==NULL))
+ {
+ PathString wzFullName;
+
+ WCHAR* pwz;
+ DWORD dw = WszSearchPath(parser->wzIncludePath,wzFile,NULL,
+ TRUE, wzFullName,&pwz);
+ if(dw != 0)
+ {
+ wzFullName.CloseBuffer((COUNT_T)(dw));
+ delete [] wzFile;
+
+ wzFile = wzFullName.GetCopyOfUnicodeString();
+ }
+
+ }
+ if(PASM->m_fReportProgress)
+ parser->msg("\nIncluding '%S'\n",wzFile);
+ MappedFileStream *pIn = new MappedFileStream(wzFile);
+ if((pIn != NULL)&&pIn->IsValid())
+ {
+ parser->PEStack.PUSH(PENV);
+ PASM->SetSourceFileName(FullFileName(wzFile,CP_UTF8)); // deletes the argument!
+ parser->CreateEnvironment(pIn);
+ NEXT_TOKEN;
+ }
+ else
+ {
+ delete [] wzFile;
+ PASM->report->error("#include failed\n");
+ return ERROR_;
+ }
+ }
+ else
+ {
+ PASM->report->error("Out of memory\n");
+ return ERROR_;
+ }
+ }
+ curPos = PENV->curPos;
+ curTok = PENV->curTok;
+ break;
+ case P_IFDEF:
+ case P_IFNDEF:
+ case P_DEFINE:
+ case P_UNDEF:
+ curPos = skipBlanks(curPos,&state);
+ if(curPos == NULL)
+ {
+ if (state & multiComment) return (BAD_COMMENT_);
+ if(ProcessEOF() == 0) return 0; // EOF
+ NEXT_TOKEN;
+ }
+ curTok = curPos;
+ PENV->curTok = curPos;
+ PENV->curPos = curPos;
+ if (!IsValidStartingSymbol(Sym(curPos))) return ERROR_;
+ do
+ {
+ curPos = nextchar(curPos);
+ } while(IsValidContinuingSymbol(Sym(curPos)));
+ tokLen = curPos - curTok;
+
+ newstr = NewStrFromToken(curTok, tokLen);
+ if((token==P_DEFINE)||(token==P_UNDEF))
+ {
+ if(token == P_DEFINE)
+ {
+ curPos = skipBlanks(curPos,&state);
+ if ((curPos == NULL) && (ProcessEOF() == 0))
+ {
+ DefineVar(newstr, NULL);
+ return 0;
+ }
+ curSym = Sym(curPos);
+ if(curSym != '"')
+ DefineVar(newstr, NULL);
+ else
+ {
+ tok = parse_literal(curSym, curPos, FALSE);
+ if(tok == QSTRING)
+ {
+ // if not ANSI, then string is in UTF-8,
+ // insert prefix
+ if(nextchar != nextcharA)
+ {
+ yylval.binstr->insertInt8(0xEF);
+ yylval.binstr->insertInt8(0xBB);
+ yylval.binstr->insertInt8(0xBF);
+ }
+ yylval.binstr->appendInt8(' ');
+ DefineVar(newstr, yylval.binstr);
+ }
+ else
+ return tok;
+ }
+ }
+ else UndefVar(newstr);
+ }
+ else
+ {
+ SkipToken = IsVarDefined(newstr);
+ if(token == P_IFDEF) SkipToken = !SkipToken;
+ IfEndif++;
+ if(SkipToken) IfEndifSkip=IfEndif;
+ }
+ break;
+ case P_ELSE:
+ SkipToken = TRUE;
+ IfEndifSkip=IfEndif;
+ break;
+ case P_ENDIF:
+ if(IfEndif == 0)
+ {
+ PASM->report->error("Unmatched #endif\n");
+ return ERROR_;
+ }
+ IfEndif--;
+ break;
+ default:
+ return(token);
+ }
+ goto NextToken;
+ }
+ if(SkipToken)
+ {
+ switch(token)
+ {
+ case P_IFDEF:
+ case P_IFNDEF:
+ IfEndif++;
+ break;
+ case P_ELSE:
+ if(IfEndif == IfEndifSkip) SkipToken = FALSE;
+ break;
+ case P_ENDIF:
+ if(IfEndif == IfEndifSkip) SkipToken = FALSE;
+ IfEndif--;
+ break;
+ default:
+ break;
+ }
+ //if(yylval.instr) yylval.instr->opcode = -1;
+ goto NextToken;
+ }
+ return(token);
+ } // end if token != 0
+ if(SkipToken) { curPos = nextBlank(curPos); goto NextToken; }
+
+ VarName* pVarName = FindVarDef(NewStrFromToken(curTok, tokLen));
+ if(pVarName != NULL)
+ {
+ if(pVarName->pbody != NULL)
+ {
+ BinStrStream *pIn = new BinStrStream(pVarName->pbody);
+ if((pIn != NULL)&&pIn->IsValid())
+ {
+ PENV->curPos = curPos;
+ parser->PEStack.PUSH(PENV);
+ parser->CreateEnvironment(pIn);
+ NEXT_TOKEN;
+ }
+ }
+ }
+
+ TypeDefDescr* pTDD = findTypedef(curTok,tokLen);
+
+ if(pTDD != NULL)
+ {
+ yylval.tdd = pTDD;
+ PENV->curPos = curPos;
+ PENV->curTok = curTok;
+ return(TYPEDEF(pTDD));
+ }
+ if(Sym(curTok) == '#')
+ {
+ PENV->curPos = curPos;
+ PENV->curTok = curTok;
+ return(ERROR_);
+ }
+ // Not a keyword, normal identifiers don't have '.' in them
+ if (offsetDot < (size_t)-1)
+ {
+ if(offsetDotDigit < (size_t)-1)
+ {
+ curPos = curTok+offsetDotDigit;
+ tokLen = offsetDotDigit;
+ }
+ // protection against something like Foo.Bar..123 or Foo.Bar.
+ unsigned D = (Sym == SymW) ? 2 : 1; // Unicode or ANSI/UTF8!
+ while((Sym(curPos-D)=='.')&&(tokLen))
+ {
+ curPos -= D;
+ tokLen -= D;
+ }
+ }
+ if((yylval.string = NewStrFromToken(curTok,tokLen)))
+ {
+ tok = (offsetDot == (size_t)(-1))? ID : DOTTEDNAME;
+ //printf("yylex: ID = '%s', curPos=0x%8.8X\n",yylval.string,curPos);
+ }
+ else return BAD_LITERAL_;
+ }
+ else if(SkipToken) { curPos = nextBlank(curPos); goto NextToken; }
+ else if (IsDigit(curSym)
+ || (curSym == '.' && IsDigit(Sym(nextchar(curPos))))
+ || (curSym == '-' && IsDigit(Sym(nextchar(curPos)))))
+ {
+ const char* begNum = curPos;
+ unsigned radix = 10;
+
+ neg = (curSym == '-'); // always make it unsigned
+ if (neg) curPos = nextchar(curPos);
+
+ if (Sym(curPos) == '0' && Sym(nextchar(curPos)) != '.')
+ {
+ curPos = nextchar(curPos);
+ radix = 8;
+ if (Sym(curPos) == 'x' || Sym(curPos) == 'X')
+ {
+ curPos = nextchar(curPos);
+ radix = 16;
+ }
+ }
+ begNum = curPos;
+ {
+ unsigned __int64 i64 = str2uint64(begNum, const_cast<const char**>(&curPos), radix);
+ unsigned __int64 mask64 = neg ? UI64(0xFFFFFFFF80000000) : UI64(0xFFFFFFFF00000000);
+ unsigned __int64 largestNegVal32 = UI64(0x0000000080000000);
+ if ((i64 & mask64) && (i64 != largestNegVal32))
+ {
+ yylval.int64 = new __int64(i64);
+ tok = INT64;
+ if (neg) *yylval.int64 = -*yylval.int64;
+ }
+ else
+ {
+ yylval.int32 = (__int32)i64;
+ tok = INT32;
+ if(neg) yylval.int32 = -yylval.int32;
+ }
+ }
+ if (radix == 10 && ((Sym(curPos) == '.' && Sym(nextchar(curPos)) != '.') || Sym(curPos) == 'E' || Sym(curPos) == 'e'))
+ {
+ unsigned L = (unsigned)(PENV->endPos - begNum);
+ curPos = (char*)begNum + GetDouble((char*)begNum,L,&yylval.float64);
+ if (neg) *yylval.float64 = -*yylval.float64;
+ tok = FLOAT64;
+ }
+ }
+ else
+ { // punctuation
+ if (curSym == '"' || curSym == '\'')
+ {
+ return parse_literal(curSym, curPos, TRUE);
+ } // end if (*curPos == '"' || *curPos == '\'')
+ else if (curSym==':' && Sym(nextchar(curPos))==':')
+ {
+ curPos = nextchar(nextchar(curPos));
+ tok = DCOLON;
+ }
+ else if(curSym == '.')
+ {
+ if (Sym(nextchar(curPos))=='.' && Sym(nextchar(nextchar(curPos)))=='.')
+ {
+ curPos = nextchar(nextchar(nextchar(curPos)));
+ tok = ELIPSIS;
+ }
+ else
+ {
+ do
+ {
+ curPos = nextchar(curPos);
+ if (curPos >= PENV->endPos)
+ return ERROR_;
+ curSym = Sym(curPos);
+ }
+ while(IsAlNum(curSym) || curSym == '_' || curSym == '$'|| curSym == '@'|| curSym == '?');
+ size_t tokLen = curPos - curTok;
+
+ // check to see if it is a keyword
+ int token = findKeyword(curTok, tokLen, &yylval.opcode);
+ if(token)
+ {
+ //printf("yylex: TOK = %d, curPos=0x%8.8X\n",token,curPos);
+ PENV->curPos = curPos;
+ PENV->curTok = curTok;
+ return(token);
+ }
+ tok = '.';
+ curPos = nextchar(curTok);
+ }
+ }
+ else
+ {
+Just_A_Character:
+ tok = curSym;
+ curPos = nextchar(curPos);
+ }
+ //printf("yylex: PUNCT curPos=0x%8.8X\n",curPos);
+ }
+ dbprintf((" Line %d token %d (%c) val = %s\n", PENV->curLine, tok,
+ (tok < 128 && isprint(tok)) ? tok : ' ',
+ (tok > 255 && tok != INT32 && tok != INT64 && tok!= FLOAT64) ? yylval.string : ""));
+
+ PENV->curPos = curPos;
+ PENV->curTok = curTok;
+ return(tok);
+}
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+/**************************************************************************/
+static char* newString(__in __nullterminated const char* str1)
+{
+ char* ret = new char[strlen(str1)+1];
+ if(ret) strcpy_s(ret, strlen(str1)+1, str1);
+ return(ret);
+}
+
+/**************************************************************************/
+/* concatenate strings and release them */
+
+static char* newStringWDel(__in __nullterminated char* str1, char delimiter, __in __nullterminated char* str3)
+{
+ size_t len1 = strlen(str1);
+ size_t len = len1+2;
+ if (str3) len += strlen(str3);
+ char* ret = new char[len];
+ if(ret)
+ {
+ strcpy_s(ret, len, str1);
+ delete [] str1;
+ ret[len1] = delimiter;
+ ret[len1+1] = 0;
+ if (str3)
+ {
+ strcat_s(ret, len, str3);
+ delete [] str3;
+ }
+ }
+ return(ret);
+}
+
+/**************************************************************************/
+static void corEmitInt(BinStr* buff, unsigned data)
+{
+ unsigned cnt = CorSigCompressData(data, buff->getBuff(5));
+ buff->remove(5 - cnt);
+}
+
+
+/**************************************************************************/
+/* move 'ptr past the exactly one type description */
+
+unsigned __int8* skipType(unsigned __int8* ptr, BOOL fFixupType)
+{
+ mdToken tk;
+AGAIN:
+ switch(*ptr++) {
+ case ELEMENT_TYPE_VOID :
+ case ELEMENT_TYPE_BOOLEAN :
+ case ELEMENT_TYPE_CHAR :
+ case ELEMENT_TYPE_I1 :
+ case ELEMENT_TYPE_U1 :
+ case ELEMENT_TYPE_I2 :
+ case ELEMENT_TYPE_U2 :
+ case ELEMENT_TYPE_I4 :
+ case ELEMENT_TYPE_U4 :
+ case ELEMENT_TYPE_I8 :
+ case ELEMENT_TYPE_U8 :
+ case ELEMENT_TYPE_R4 :
+ case ELEMENT_TYPE_R8 :
+ case ELEMENT_TYPE_U :
+ case ELEMENT_TYPE_I :
+ case ELEMENT_TYPE_STRING :
+ case ELEMENT_TYPE_OBJECT :
+ case ELEMENT_TYPE_TYPEDBYREF :
+ case ELEMENT_TYPE_SENTINEL :
+ /* do nothing */
+ break;
+
+ case ELEMENT_TYPE_VALUETYPE :
+ case ELEMENT_TYPE_CLASS :
+ ptr += CorSigUncompressToken(ptr, &tk);
+ break;
+
+ case ELEMENT_TYPE_CMOD_REQD :
+ case ELEMENT_TYPE_CMOD_OPT :
+ ptr += CorSigUncompressToken(ptr, &tk);
+ goto AGAIN;
+
+ case ELEMENT_TYPE_ARRAY :
+ {
+ ptr = skipType(ptr, fFixupType); // element Type
+ unsigned rank = CorSigUncompressData((PCCOR_SIGNATURE&) ptr);
+ if (rank != 0)
+ {
+ unsigned numSizes = CorSigUncompressData((PCCOR_SIGNATURE&) ptr);
+ while(numSizes > 0)
+ {
+ CorSigUncompressData((PCCOR_SIGNATURE&) ptr);
+ --numSizes;
+ }
+ unsigned numLowBounds = CorSigUncompressData((PCCOR_SIGNATURE&) ptr);
+ while(numLowBounds > 0)
+ {
+ CorSigUncompressData((PCCOR_SIGNATURE&) ptr);
+ --numLowBounds;
+ }
+ }
+ }
+ break;
+
+ // Modifiers or depedant types
+ case ELEMENT_TYPE_PINNED :
+ case ELEMENT_TYPE_PTR :
+ case ELEMENT_TYPE_BYREF :
+ case ELEMENT_TYPE_SZARRAY :
+ // tail recursion optimization
+ // ptr = skipType(ptr, fFixupType);
+ // break
+ goto AGAIN;
+
+ case ELEMENT_TYPE_VAR:
+ case ELEMENT_TYPE_MVAR:
+ CorSigUncompressData((PCCOR_SIGNATURE&) ptr); // bound
+ break;
+
+ case ELEMENT_TYPE_VARFIXUP:
+ case ELEMENT_TYPE_MVARFIXUP:
+ if(fFixupType)
+ {
+ BYTE* pb = ptr-1; // ptr incremented in switch
+ unsigned __int8* ptr_save = ptr;
+ int n = CorSigUncompressData((PCCOR_SIGNATURE&) ptr); // fixup #
+ int compressed_size_n = (int)(ptr - ptr_save); // ptr was updated by CorSigUncompressData()
+ int m = -1;
+ if(PASM->m_TyParList)
+ m = PASM->m_TyParList->IndexOf(TyParFixupList.PEEK(n));
+ if(m == -1)
+ {
+ PASM->report->error("(fixupType) Invalid %stype parameter '%s'\n",
+ (*pb == ELEMENT_TYPE_MVARFIXUP)? "method ": "",
+ TyParFixupList.PEEK(n));
+ m = 0;
+ }
+ *pb = (*pb == ELEMENT_TYPE_MVARFIXUP)? ELEMENT_TYPE_MVAR : ELEMENT_TYPE_VAR;
+ int compressed_size_m = (int)CorSigCompressData(m,pb+1);
+
+ // Note that CorSigCompressData() (and hence, CorSigUncompressData()) store a number
+ // 0 <= x <= 0x1FFFFFFF in 1, 2, or 4 bytes. Above, 'n' is the fixup number being read,
+ // and 'm' is the generic parameter number being written out (in the same place where 'n'
+ // came from). If 'n' takes more space to compress than 'm' (e.g., 0x80 <= n <= 0x3fff so
+ // it takes 2 bytes, and m < 0x80 so it takes one byte), then when we overwrite the fixup
+ // number with the generic parameter number, we'll leave extra bytes in the signature following
+ // the written generic parameter number. Thus, we do something of a hack to ensure that the
+ // compressed number is correctly readable even if 'm' compresses smaller than 'n' did: we
+ // recompress 'm' to use the same amount of space as 'n' used. This is possible because smaller
+ // numbers can still be compressed in a larger amount of space, even though it's not optimal (and
+ // CorSigCompressData() would never do it). If, however, the compressed sizes are the other
+ // way around (m takes more space to compress than n), then we've already corrupted the
+ // signature that we're reading by writing beyond what we should (is there some reason why
+ // this is not possible?).
+ // Note that 'ptr' has already been adjusted, above, to point to the next type after this one.
+ // There is no need to update it when recompressing the data.
+
+ if (compressed_size_m > compressed_size_n)
+ {
+ // We've got a problem: we just corrupted the rest of the signature!
+ // (Can this ever happen in practice?)
+ PASM->report->error("(fixupType) Too many %stype parameters\n",
+ (*pb == ELEMENT_TYPE_MVARFIXUP)? "method ": "");
+ }
+ else if (compressed_size_m < compressed_size_n)
+ {
+ // We didn't write out as much data as we read. This will leave extra bytes in the
+ // signature that will be incorrectly recognized. Ideally, we would just shrink the
+ // signature. That's not easy to do here. Instead, pad the bytes to force it to use
+ // a larger encoding than needed. This assumes knowledge of the CorSigCompressData()
+ // encoding.
+ //
+ // The cases:
+ // compressed_size_m m bytes compressed_size_n result bytes
+ // 1 m1 2 0x80 m1
+ // 1 m1 4 0xC0 0x00 0x00 m1
+ // 2 m1 m2 4 0xC0 0x00 (m1 & 0x7f) m2
+
+ _ASSERTE((compressed_size_m == 1) || (compressed_size_m == 2) || (compressed_size_m == 4));
+ _ASSERTE((compressed_size_n == 1) || (compressed_size_n == 2) || (compressed_size_n == 4));
+
+ if ((compressed_size_m == 1) &&
+ (compressed_size_n == 2))
+ {
+ unsigned __int8 m1 = *(pb + 1);
+ _ASSERTE(m1 < 0x80);
+ *(pb + 1) = 0x80;
+ *(pb + 2) = m1;
+ }
+ else
+ if ((compressed_size_m == 1) &&
+ (compressed_size_n == 4))
+ {
+ unsigned __int8 m1 = *(pb + 1);
+ _ASSERTE(m1 < 0x80);
+ *(pb + 1) = 0xC0;
+ *(pb + 2) = 0x00;
+ *(pb + 3) = 0x00;
+ *(pb + 4) = m1;
+ }
+ else
+ if ((compressed_size_m == 2) &&
+ (compressed_size_n == 4))
+ {
+ unsigned __int8 m1 = *(pb + 1);
+ unsigned __int8 m2 = *(pb + 2);
+ _ASSERTE(m1 >= 0x80);
+ m1 &= 0x7f; // strip the bit indicating it's a 2-byte thing
+ *(pb + 1) = 0xC0;
+ *(pb + 2) = 0x00;
+ *(pb + 3) = m1;
+ *(pb + 4) = m2;
+ }
+ }
+ }
+ else
+ CorSigUncompressData((PCCOR_SIGNATURE&) ptr); // bound
+ break;
+
+ case ELEMENT_TYPE_FNPTR:
+ {
+ CorSigUncompressData((PCCOR_SIGNATURE&) ptr); // calling convention
+ unsigned argCnt = CorSigUncompressData((PCCOR_SIGNATURE&) ptr); // arg count
+ ptr = skipType(ptr, fFixupType); // return type
+ while(argCnt > 0)
+ {
+ ptr = skipType(ptr, fFixupType);
+ --argCnt;
+ }
+ }
+ break;
+
+ case ELEMENT_TYPE_GENERICINST:
+ {
+ ptr = skipType(ptr, fFixupType); // type constructor
+ unsigned argCnt = CorSigUncompressData((PCCOR_SIGNATURE&)ptr); // arg count
+ while(argCnt > 0) {
+ ptr = skipType(ptr, fFixupType);
+ --argCnt;
+ }
+ }
+ break;
+
+ default:
+ case ELEMENT_TYPE_END :
+ _ASSERTE(!"Unknown Type");
+ break;
+ }
+ return(ptr);
+}
+
+/**************************************************************************/
+void FixupTyPars(PCOR_SIGNATURE pSig, ULONG cSig)
+{
+ if(TyParFixupList.COUNT() > 0)
+ {
+ BYTE* ptr = (BYTE*)pSig;
+ BYTE* ptrEnd = ptr + cSig;
+ while(ptr < ptrEnd)
+ {
+ ptr = skipType(ptr, TRUE);
+ } // end while
+ } // end if(COUNT>0)
+}
+void FixupTyPars(BinStr* pbstype)
+{
+ FixupTyPars((PCOR_SIGNATURE)(pbstype->ptr()),(ULONG)(pbstype->length()));
+}
+/**************************************************************************/
+static unsigned corCountArgs(BinStr* args)
+{
+ unsigned __int8* ptr = args->ptr();
+ unsigned __int8* end = &args->ptr()[args->length()];
+ unsigned ret = 0;
+ while(ptr < end)
+ {
+ if (*ptr != ELEMENT_TYPE_SENTINEL)
+ {
+ ptr = skipType(ptr, FALSE);
+ ret++;
+ }
+ else ptr++;
+ }
+ return(ret);
+}
+
+/********************************************************************************/
+AsmParse::AsmParse(ReadStream* aIn, Assembler *aAssem)
+{
+#ifdef DEBUG_PARSING
+ extern int yydebug;
+ yydebug = 1;
+#endif
+
+ assem = aAssem;
+ assem->SetErrorReporter((ErrorReporter *)this);
+
+ assem->m_ulCurLine = 1;
+ assem->m_ulCurColumn = 1;
+
+ wzIncludePath = NULL;
+ penv = NULL;
+
+ hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ hstderr = GetStdHandle(STD_ERROR_HANDLE);
+
+ success = true;
+ _ASSERTE(parser == 0); // Should only be one parser instance at a time
+
+ // Resolve aliases
+ for (unsigned int i = 0; i < sizeof(keywords) / sizeof(Keywords); i++)
+ {
+ if (keywords[i].token == NO_VALUE)
+ keywords[i].token = keywords[keywords[i].tokenVal].token;
+ }
+ SetSymbolTables();
+ Init_str2uint64();
+ parser = this;
+ //yyparse();
+}
+
+/********************************************************************************/
+AsmParse::~AsmParse()
+{
+ parser = 0;
+ delete penv;
+ while(m_ANSLast.POP());
+}
+
+/**************************************************************************/
+DWORD AsmParse::IsItUnicode(CONST LPVOID pBuff, int cb, LPINT lpi)
+{
+ return IsTextUnicode(pBuff,cb,lpi);
+}
+
+/**************************************************************************/
+void AsmParse::CreateEnvironment(ReadStream* stream)
+{
+ penv = new PARSING_ENVIRONMENT;
+ memset(penv,0,sizeof(PARSING_ENVIRONMENT));
+ penv->in = stream;
+ penv->curLine = 1;
+ strcpy_s(penv->szFileName, MAX_FILENAME_LENGTH*3+1,assem->m_szSourceFileName);
+
+ penv->curPos = fillBuff(NULL);
+ penv->uCodePage = g_uCodePage;
+
+ SetFunctionPtrs();
+};
+
+/**************************************************************************/
+void AsmParse::ParseFile(ReadStream* stream)
+{
+ CreateEnvironment(stream);
+ yyparse();
+ penv->in = NULL;
+};
+
+/**************************************************************************/
+char* AsmParse::fillBuff(__in_opt __nullterminated char* pos)
+{
+ int iPutToBuffer;
+ int iOptions = IS_TEXT_UNICODE_UNICODE_MASK;
+ g_uCodePage = CP_ACP;
+ iPutToBuffer = (int)penv->in->getAll(&(penv->curPos));
+
+ penv->endPos = penv->curPos + iPutToBuffer;
+ if(iPutToBuffer > 128) iPutToBuffer = 128;
+ if(IsItUnicode(penv->curPos,iPutToBuffer,&iOptions))
+ {
+ g_uCodePage = CP_UTF8;
+ if(iOptions & IS_TEXT_UNICODE_SIGNATURE)
+ {
+ penv->curPos += 2;
+ }
+ if(assem->m_fReportProgress) printf("Source file is UNICODE\n\n");
+ penv->pfn_Sym = SymW;
+ penv->pfn_nextchar = nextcharW;
+ penv->pfn_NewStrFromToken = NewStrFromTokenW;
+ penv->pfn_NewStaticStrFromToken = NewStaticStrFromTokenW;
+ penv->pfn_GetDouble = GetDoubleW;
+ }
+ else
+ {
+ if(((penv->curPos[0]&0xFF)==0xEF)&&((penv->curPos[1]&0xFF)==0xBB)&&((penv->curPos[2]&0xFF)==0xBF))
+ {
+ g_uCodePage = CP_UTF8;
+ penv->curPos += 3;
+ if(assem->m_fReportProgress) printf("Source file is UTF-8\n\n");
+ penv->pfn_nextchar = nextcharU;
+ }
+ else
+ {
+ if(assem->m_fReportProgress) printf("Source file is ANSI\n\n");
+ penv->pfn_nextchar = nextcharA;
+ }
+ penv->pfn_Sym = SymAU;
+ penv->pfn_NewStrFromToken = NewStrFromTokenAU;
+ penv->pfn_NewStaticStrFromToken = NewStaticStrFromTokenAU;
+ penv->pfn_GetDouble = GetDoubleAU;
+ }
+ return(penv->curPos);
+}
+
+/********************************************************************************/
+BinStr* AsmParse::MakeSig(unsigned callConv, BinStr* retType, BinStr* args, int ntyargs)
+{
+ _ASSERTE((ntyargs != 0) == ((callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) != 0));
+ BinStr* ret = new BinStr();
+ if(ret)
+ {
+ //if (retType != 0)
+ ret->insertInt8(callConv);
+ if (ntyargs != 0)
+ corEmitInt(ret, ntyargs);
+ corEmitInt(ret, corCountArgs(args));
+
+ if (retType != 0)
+ {
+ ret->append(retType);
+ delete retType;
+ }
+ ret->append(args);
+ }
+ else
+ error("\nOut of memory!\n");
+
+ delete args;
+ return(ret);
+}
+
+/********************************************************************************/
+BinStr* AsmParse::MakeTypeArray(CorElementType kind, BinStr* elemType, BinStr* bounds)
+{
+ // 'bounds' is a binary buffer, that contains an array of 'struct Bounds'
+ struct Bounds {
+ int lowerBound;
+ unsigned numElements;
+ };
+
+ _ASSERTE(bounds->length() % sizeof(Bounds) == 0);
+ unsigned boundsLen = bounds->length() / sizeof(Bounds);
+ _ASSERTE(boundsLen > 0);
+ Bounds* boundsArr = (Bounds*) bounds->ptr();
+
+ BinStr* ret = new BinStr();
+
+ ret->appendInt8(kind);
+ ret->append(elemType);
+ corEmitInt(ret, boundsLen); // emit the rank
+
+ unsigned lowerBoundsDefined = 0;
+ unsigned numElementsDefined = 0;
+ unsigned i;
+ for(i=0; i < boundsLen; i++)
+ {
+ if(boundsArr[i].lowerBound < 0x7FFFFFFF) lowerBoundsDefined = i+1;
+ else boundsArr[i].lowerBound = 0;
+
+ if(boundsArr[i].numElements < 0x7FFFFFFF) numElementsDefined = i+1;
+ else boundsArr[i].numElements = 0;
+ }
+
+ corEmitInt(ret, numElementsDefined); // emit number of bounds
+
+ for(i=0; i < numElementsDefined; i++)
+ {
+ _ASSERTE (boundsArr[i].numElements >= 0); // enforced at rule time
+ corEmitInt(ret, boundsArr[i].numElements);
+
+ }
+
+ corEmitInt(ret, lowerBoundsDefined); // emit number of lower bounds
+ for(i=0; i < lowerBoundsDefined; i++)
+ {
+ unsigned cnt = CorSigCompressSignedInt(boundsArr[i].lowerBound, ret->getBuff(5));
+ ret->remove(5 - cnt);
+ }
+ delete elemType;
+ delete bounds;
+ return(ret);
+}
+
+/********************************************************************************/
+BinStr* AsmParse::MakeTypeClass(CorElementType kind, mdToken tk)
+{
+
+ BinStr* ret = new BinStr();
+ _ASSERTE(kind == ELEMENT_TYPE_CLASS || kind == ELEMENT_TYPE_VALUETYPE ||
+ kind == ELEMENT_TYPE_CMOD_REQD || kind == ELEMENT_TYPE_CMOD_OPT);
+ ret->appendInt8(kind);
+ unsigned cnt = CorSigCompressToken(tk, ret->getBuff(5));
+ ret->remove(5 - cnt);
+ return(ret);
+}
+/**************************************************************************/
+void PrintANSILine(FILE* pF, __in __nullterminated char* sz)
+{
+ WCHAR *wz = &wzUniBuf[0];
+ if(g_uCodePage != CP_ACP)
+ {
+ memset(wz,0,dwUniBuf); // dwUniBuf/2 WCHARs = dwUniBuf bytes
+ WszMultiByteToWideChar(g_uCodePage,0,sz,-1,wz,(dwUniBuf >> 1)-1);
+
+ memset(sz,0,dwUniBuf);
+ WszWideCharToMultiByte(g_uConsoleCP,0,wz,-1,sz,dwUniBuf-1,NULL,NULL);
+ }
+ fprintf(pF,"%s",sz);
+}
+/**************************************************************************/
+void AsmParse::error(const char* fmt, ...)
+{
+ char *sz = (char*)(&wzUniBuf[(dwUniBuf >> 1)]);
+ char *psz=&sz[0];
+ FILE* pF = ((!assem->m_fReportProgress)&&(assem->OnErrGo)) ? stdout : stderr;
+ success = false;
+ va_list args;
+ va_start(args, fmt);
+
+ if((penv) && (penv->in)) psz+=sprintf_s(psz, (dwUniBuf >> 1), "%S(%d) : ", penv->in->namew(), penv->curLine);
+ psz+=sprintf_s(psz, (dwUniBuf >> 1), "error : ");
+ _vsnprintf_s(psz, (dwUniBuf >> 1),(dwUniBuf >> 1)-strlen(sz)-1, fmt, args);
+ PrintANSILine(pF,sz);
+}
+
+/**************************************************************************/
+void AsmParse::warn(const char* fmt, ...)
+{
+ char *sz = (char*)(&wzUniBuf[(dwUniBuf >> 1)]);
+ char *psz=&sz[0];
+ FILE* pF = ((!assem->m_fReportProgress)&&(assem->OnErrGo)) ? stdout : stderr;
+ va_list args;
+ va_start(args, fmt);
+
+ if((penv) && (penv->in)) psz+=sprintf_s(psz, (dwUniBuf >> 1), "%S(%d) : ", penv->in->namew(), penv->curLine);
+ psz+=sprintf_s(psz, (dwUniBuf >> 1), "warning : ");
+ _vsnprintf_s(psz, (dwUniBuf >> 1),(dwUniBuf >> 1)-strlen(sz)-1, fmt, args);
+ PrintANSILine(pF,sz);
+}
+/**************************************************************************/
+void AsmParse::msg(const char* fmt, ...)
+{
+ char *sz = (char*)(&wzUniBuf[(dwUniBuf >> 1)]);
+ va_list args;
+ va_start(args, fmt);
+
+ _vsnprintf_s(sz, (dwUniBuf >> 1),(dwUniBuf >> 1)-1, fmt, args);
+ PrintANSILine(stdout,sz);
+}
+
+#ifdef _MSC_VER
+#pragma warning(default : 4640)
+#endif