diff options
Diffstat (limited to 'src/ilasm/grammar_after.cpp')
-rw-r--r-- | src/ilasm/grammar_after.cpp | 1722 |
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 |