Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomáš Rylek <trylek@microsoft.com>2020-12-08 05:19:44 +0300
committerGitHub <noreply@github.com>2020-12-08 05:19:44 +0300
commit69e114c1abf91241a0eeecf1ecceab4711b8aa62 (patch)
treeb81a0b35748f5e598412bcc504335cdbd322cd43 /src/coreclr/ilasm
parent0ec07945a9759a72a689edbb01e69b232e26e05a (diff)
December infra rollout - remove duplicated 'src' from coreclr subrepo (src/coreclr/src becomes src/coreclr) (#44973)
* Move src/coreclr/src/Directory.Build.targets to src/coreclr Merge src/coreclr/src/CMakeLists.txt into src/coreclr/CMakeLists.txt * Mechanical move of src/coreclr/src to src/coreclr * Scripts adjustments to reflect the changed paths
Diffstat (limited to 'src/coreclr/ilasm')
-rw-r--r--src/coreclr/ilasm/CMakeLists.txt130
-rw-r--r--src/coreclr/ilasm/Native.rc7
-rw-r--r--src/coreclr/ilasm/asmenum.h40
-rw-r--r--src/coreclr/ilasm/asmman.cpp1031
-rw-r--r--src/coreclr/ilasm/asmman.hpp295
-rw-r--r--src/coreclr/ilasm/asmparse.h325
-rw-r--r--src/coreclr/ilasm/asmparse.y2063
-rw-r--r--src/coreclr/ilasm/asmtemplates.h795
-rw-r--r--src/coreclr/ilasm/assem.cpp1641
-rw-r--r--src/coreclr/ilasm/assembler.cpp2792
-rw-r--r--src/coreclr/ilasm/assembler.h1304
-rw-r--r--src/coreclr/ilasm/binstr.h76
-rw-r--r--src/coreclr/ilasm/class.hpp119
-rw-r--r--src/coreclr/ilasm/extractGrammar.pl59
-rw-r--r--src/coreclr/ilasm/grammar_after.cpp1695
-rw-r--r--src/coreclr/ilasm/grammar_before.cpp137
-rw-r--r--src/coreclr/ilasm/ilasmpch.h28
-rw-r--r--src/coreclr/ilasm/main.cpp1010
-rw-r--r--src/coreclr/ilasm/method.cpp176
-rw-r--r--src/coreclr/ilasm/method.hpp385
-rw-r--r--src/coreclr/ilasm/nvpair.h45
-rw-r--r--src/coreclr/ilasm/portable_pdb.cpp398
-rw-r--r--src/coreclr/ilasm/portable_pdb.h68
-rw-r--r--src/coreclr/ilasm/prebuilt/asmparse.cpp4949
-rw-r--r--src/coreclr/ilasm/prebuilt/asmparse.grammar1280
-rw-r--r--src/coreclr/ilasm/typar.hpp182
-rw-r--r--src/coreclr/ilasm/writer.cpp1663
-rw-r--r--src/coreclr/ilasm/writer_enc.cpp608
28 files changed, 23301 insertions, 0 deletions
diff --git a/src/coreclr/ilasm/CMakeLists.txt b/src/coreclr/ilasm/CMakeLists.txt
new file mode 100644
index 00000000000..3e6c15b657a
--- /dev/null
+++ b/src/coreclr/ilasm/CMakeLists.txt
@@ -0,0 +1,130 @@
+project(ilasm)
+
+add_definitions(-DUNICODE)
+add_definitions(-D_UNICODE)
+add_definitions(-D_FEATURE_NO_HOST)
+add_definitions(-D__ILASM__)
+add_definitions(-DFEATURE_METADATA_EMIT_PORTABLE_PDB)
+
+add_definitions(-DFEATURE_CORECLR)
+
+include_directories(.)
+
+set(ILASM_SOURCES
+ assem.cpp
+ writer.cpp
+ writer_enc.cpp
+ method.cpp
+ asmman.cpp
+ main.cpp
+ assembler.cpp
+ prebuilt/asmparse.cpp
+ portable_pdb.cpp
+)
+
+set(ILASM_HEADERS
+ asmenum.h
+ asmman.hpp
+ asmparse.h
+ asmtemplates.h
+ assembler.h
+ binstr.h
+ class.hpp
+ ilasmpch.h
+ method.hpp
+ nvpair.h
+ typar.hpp
+ portable_pdb.h
+)
+
+if(CLR_CMAKE_TARGET_WIN32)
+ list(APPEND ILASM_SOURCES ${ILASM_HEADERS})
+
+ set(ILASM_RESOURCES Native.rc)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=ilasm.exe)
+endif(CLR_CMAKE_TARGET_WIN32)
+
+
+if(CLR_CMAKE_HOST_UNIX)
+ # Need generate a right form of asmparse.cpp to avoid the following options.
+ # Clang also produces a bad-codegen on this prebuilt file with optimization.
+ # https://github.com/dotnet/runtime/issues/4776
+ add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-Wno-register>")
+ add_compile_options(-Wno-array-bounds)
+ add_compile_options(-Wno-unused-label)
+ set_source_files_properties( prebuilt/asmparse.cpp PROPERTIES COMPILE_FLAGS "-O0" )
+endif(CLR_CMAKE_HOST_UNIX)
+
+if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS)
+ # This option is necessary to ensure that the overloaded delete operator defined inside
+ # of the utilcode will be used instead of the standard library delete operator.
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic")
+
+ # The following linked options can be inserted into the linker libraries list to
+ # ensure proper resolving of circular references between a subset of the libraries.
+ set(START_LIBRARY_GROUP -Wl,--start-group)
+ set(END_LIBRARY_GROUP -Wl,--end-group)
+endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS)
+
+_add_executable(ilasm
+ ${ILASM_SOURCES}
+ ${ILASM_RESOURCES}
+)
+
+set(ILASM_LINK_LIBRARIES
+ utilcodestaticnohost
+ mscorpe
+ ${START_LIBRARY_GROUP} # Start group of libraries that have circular references
+ mdhotdata_ppdb
+ mdcompiler_ppdb
+ mdruntime_ppdb
+ mdruntimerw_ppdb
+ mdstaticapi_ppdb
+ ${END_LIBRARY_GROUP} # End group of libraries that have circular references
+ ceefgen
+ corguids
+)
+
+if(CLR_CMAKE_TARGET_WIN32)
+ list(APPEND ILASM_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ RuntimeObject.lib
+ )
+else()
+ list(APPEND ILASM_LINK_LIBRARIES
+ coreclrpal
+ mscorrc
+ palrt
+ )
+endif(CLR_CMAKE_TARGET_WIN32)
+
+
+if(CLR_CMAKE_HOST_UNIX)
+ target_link_libraries(ilasm
+ ${ILASM_LINK_LIBRARIES}
+ utilcodestaticnohost
+ mscorrc
+ coreclrpal
+ palrt
+ ${CMAKE_DL_LIBS}
+ )
+else()
+ target_link_libraries(ilasm
+ ${ILASM_LINK_LIBRARIES}
+ ole32
+ oleaut32
+ shell32
+ )
+endif(CLR_CMAKE_HOST_UNIX)
+
+install_clr(TARGETS ilasm)
diff --git a/src/coreclr/ilasm/Native.rc b/src/coreclr/ilasm/Native.rc
new file mode 100644
index 00000000000..b9622b6c47e
--- /dev/null
+++ b/src/coreclr/ilasm/Native.rc
@@ -0,0 +1,7 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#define FX_VER_FILEDESCRIPTION_STR "Microsoft .NET Framework IL assembler\0"
+
+#include <fxver.h>
+#include <fxver.rc>
diff --git a/src/coreclr/ilasm/asmenum.h b/src/coreclr/ilasm/asmenum.h
new file mode 100644
index 00000000000..f2e79c81eb9
--- /dev/null
+++ b/src/coreclr/ilasm/asmenum.h
@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+#ifndef __asmenum_h__
+#define __asmenum_h__
+
+#include "openum.h"
+
+typedef struct
+{
+ const char * pszName;
+ OPCODE op;
+
+ BYTE Type; // Inline0 etc.
+
+ BYTE Len; // std mapping
+ BYTE Std1;
+ BYTE Std2;
+} opcodeinfo_t;
+
+#ifdef DECLARE_DATA
+opcodeinfo_t OpcodeInfo[] =
+{
+#define OPALIAS(c,s,real) { s, real, 0, 0, 0, 0 },
+#define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) { s, c, args,l,s1,s2 },
+#include "opcode.def"
+#undef OPDEF
+#undef OPALIAS
+};
+
+unsigned OpcodeInfoLen = sizeof(OpcodeInfo) / sizeof(opcodeinfo_t);
+#else
+extern opcodeinfo_t OpcodeInfo[];
+extern unsigned OpcodeInfoLen;
+#endif
+
+
+
+#endif /* __openum_h__ */
+
+
diff --git a/src/coreclr/ilasm/asmman.cpp b/src/coreclr/ilasm/asmman.cpp
new file mode 100644
index 00000000000..dc45b8f9f01
--- /dev/null
+++ b/src/coreclr/ilasm/asmman.cpp
@@ -0,0 +1,1031 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// asmman.cpp - manifest info handling (implementation of class AsmMan, see asmman.hpp)
+//
+
+//
+#include "ilasmpch.h"
+
+#include "assembler.h"
+#include "strongnameinternal.h"
+#include <limits.h>
+#include <fusion.h>
+
+extern WCHAR* pwzInputFiles[];
+
+BinStr* BinStrToUnicode(BinStr* pSource, bool Swap)
+{
+ if(pSource)
+ {
+ pSource->appendInt8(0);
+ BinStr* tmp = new BinStr();
+ char* pb = (char*)(pSource->ptr());
+ int l=pSource->length(), L = sizeof(WCHAR)*l;
+ if(tmp)
+ {
+ WCHAR* wz = (WCHAR*)(tmp->getBuff(L));
+ if(wz)
+ {
+ memset(wz,0,L);
+ WszMultiByteToWideChar(g_uCodePage,0,pb,-1,wz,l);
+ tmp->remove(L-(DWORD)wcslen(wz)*sizeof(WCHAR));
+#if BIGENDIAN
+ if (Swap)
+ SwapStringLength(wz, (DWORD)wcslen(wz));
+#endif
+ delete pSource;
+ }
+ else
+ {
+ delete tmp;
+ tmp = NULL;
+ fprintf(stderr,"\nOut of memory!\n");
+ }
+ }
+ else
+ fprintf(stderr,"\nOut of memory!\n");
+ return tmp;
+ }
+ return NULL;
+}
+
+AsmManFile* AsmMan::GetFileByName(__in __nullterminated char* szFileName)
+{
+ AsmManFile* ret = NULL;
+ if(szFileName)
+ {
+ //AsmManFile X;
+ //X.szName = szFileName;
+ //ret = m_FileLst.FIND(&X);
+ //X.szName = NULL;
+ for(int i=0; (ret = m_FileLst.PEEK(i))&&strcmp(ret->szName,szFileName); i++);
+ }
+ return ret;
+}
+
+mdToken AsmMan::GetFileTokByName(__in __nullterminated char* szFileName)
+{
+ AsmManFile* tmp = GetFileByName(szFileName);
+ return(tmp ? tmp->tkTok : mdFileNil);
+}
+
+AsmManComType* AsmMan::GetComTypeByName(__in_opt __nullterminated char* szComTypeName,
+ __in_opt __nullterminated char* szComEnclosingTypeName)
+{
+ AsmManComType* ret = NULL;
+ if(szComTypeName)
+ {
+ //AsmManComType X;
+ //X.szName = szComTypeName;
+ //ret = m_ComTypeLst.FIND(&X);
+ //X.szName = NULL;
+ for(int i=0; (ret = m_ComTypeLst.PEEK(i)) != NULL; i++)
+ {
+ if (strcmp(ret->szName, szComTypeName) == 0)
+ {
+ if (ret->szComTypeName == NULL && szComEnclosingTypeName == NULL)
+ {
+ break;
+ }
+
+ if (ret->szComTypeName != NULL && szComEnclosingTypeName != NULL)
+ {
+ if (strcmp(ret->szComTypeName, szComEnclosingTypeName) == 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+mdToken AsmMan::GetComTypeTokByName(
+ __in_opt __nullterminated char* szComTypeName,
+ __in_opt __nullterminated char* szComEnclosingTypeName)
+{
+ AsmManComType* tmp = GetComTypeByName(szComTypeName, szComEnclosingTypeName);
+ return(tmp ? tmp->tkTok : mdExportedTypeNil);
+}
+
+AsmManAssembly* AsmMan::GetAsmRefByName(__in __nullterminated const char* szAsmRefName)
+{
+ AsmManAssembly* ret = NULL;
+ if(szAsmRefName)
+ {
+ //AsmManAssembly X;
+ //X.szAlias = szAsmRefName;
+ //ret = m_AsmRefLst.FIND(&X);
+ //X.szAlias = NULL;
+ DWORD L = (DWORD)strlen(szAsmRefName);
+ for(int i=0; (ret = m_AsmRefLst.PEEK(i))&&
+ ((ret->dwAlias != L)||strcmp(ret->szAlias,szAsmRefName)); i++);
+ }
+ return ret;
+}
+mdToken AsmMan::GetAsmRefTokByName(__in __nullterminated const char* szAsmRefName)
+{
+ AsmManAssembly* tmp = GetAsmRefByName(szAsmRefName);
+ return(tmp ? tmp->tkTok : mdAssemblyRefNil);
+}
+AsmManAssembly* AsmMan::GetAsmRefByAsmName(__in __nullterminated const char* szAsmName)
+{
+ AsmManAssembly* ret = NULL;
+ if(szAsmName)
+ {
+ for(int i=0; (ret = m_AsmRefLst.PEEK(i))&&
+ (strcmp(ret->szName,szAsmName)); i++);
+ }
+ return ret;
+}
+
+//==============================================================================================================
+void AsmMan::SetModuleName(__inout_opt __nullterminated char* szName)
+{
+ if(m_szScopeName == NULL) // ignore all duplicate declarations
+ {
+ if(szName && *szName)
+ {
+ ULONG L = (ULONG)strlen(szName);
+ if(L >= MAX_SCOPE_LENGTH)
+ {
+ ((Assembler*)m_pAssembler)->report->warn("Module name too long (%d chars, max.allowed: %d chars), truncated\n",L,MAX_SCOPE_LENGTH-1);
+ szName[MAX_SCOPE_LENGTH-1] = 0;
+ }
+ m_szScopeName = szName;
+ strcpy_s(((Assembler*)m_pAssembler)->m_szScopeName, MAX_SCOPE_LENGTH, szName);
+ }
+ }
+}
+//==============================================================================================================
+
+void AsmMan::AddFile(__in __nullterminated char* szName, DWORD dwAttr, BinStr* pHashBlob)
+{
+ AsmManFile* tmp = GetFileByName(szName);
+ Assembler* pAsm = (Assembler*)m_pAssembler;
+ if(tmp==NULL)
+ {
+ tmp = new AsmManFile;
+ if(tmp==NULL)
+ {
+ pAsm->report->error("\nOut of memory!\n");
+ return;
+ }
+ memset(tmp,0,sizeof(AsmManFile));
+ if((dwAttr & 0x80000000)!=0) pAsm->m_fEntryPointPresent = TRUE;
+ tmp->szName = szName;
+ tmp->dwAttr = dwAttr;
+ tmp->pHash = pHashBlob;
+ tmp->m_fNew = TRUE;
+ m_FileLst.PUSH(tmp);
+ tmp->tkTok = TokenFromRid(m_FileLst.COUNT(),mdtFile);
+ }
+ pAsm->m_tkCurrentCVOwner = 0;
+ if(tmp) pAsm->m_pCustomDescrList = &(tmp->m_CustomDescrList);
+}
+//==============================================================================================================
+
+void AsmMan::EmitFiles()
+{
+ AsmManFile* tmp;
+ Assembler* pAsm = (Assembler*)m_pAssembler;
+ int i;
+ HRESULT hr = S_OK;
+ mdToken tk;
+ for(i = 0; (tmp=m_FileLst.PEEK(i)) != NULL; i++)
+ {
+ BOOL fEntry = ((tmp->dwAttr & 0x80000000)!=0);
+
+ wzUniBuf[0] = 0;
+
+ BYTE* pHash=NULL;
+ DWORD cbHash= 0;
+
+ if(!tmp->m_fNew) continue;
+ tmp->m_fNew = FALSE;
+
+ WszMultiByteToWideChar(g_uCodePage,0,tmp->szName,-1,wzUniBuf,dwUniBuf);
+ if(tmp->pHash==NULL) // if hash not explicitly specified
+ {
+ if(m_pAssembly // and assembly is defined
+ && m_pAssembly->ulHashAlgorithm) // and hash algorithm is defined...
+ { // then try to compute it
+ {
+ pHash = NULL;
+ cbHash = 0;
+ }
+ }
+ }
+ else
+ {
+ pHash = tmp->pHash->ptr();
+ cbHash = tmp->pHash->length();
+ }
+
+ hr = m_pAsmEmitter->DefineFile(wzUniBuf,
+ (const void*)pHash,
+ cbHash,
+ tmp->dwAttr & 0x7FFFFFFF,
+ (mdFile*)&tk);
+ _ASSERTE(tk == tmp->tkTok);
+ if(FAILED(hr)) report->error("Failed to define file '%s': 0x%08X\n",tmp->szName,hr);
+ else
+ {
+ if(fEntry)
+ {
+ if (FAILED(pAsm->m_pCeeFileGen->SetEntryPoint(pAsm->m_pCeeFile, tmp->tkTok)))
+ {
+ pAsm->report->error("Failed to set external entry point for file '%s'\n",tmp->szName);
+ }
+ }
+ pAsm->EmitCustomAttributes(tmp->tkTok, &(tmp->m_CustomDescrList));
+ }
+ } //end for(i = 0; tmp=m_FileLst.PEEK(i); i++)
+}
+
+void AsmMan::StartAssembly(__in __nullterminated char* szName, __in_opt __nullterminated char* szAlias, DWORD dwAttr, BOOL isRef)
+{
+ if(!isRef && (0==strcmp(szName, "mscorlib"))) ((Assembler*)m_pAssembler)->m_fIsMscorlib = TRUE;
+ if(!isRef && (m_pAssembly != NULL))
+ {
+ if(strcmp(szName, m_pAssembly->szName))
+ report->error("Multiple assembly declarations\n");
+ // if name is the same, just ignore it
+ m_pCurAsmRef = NULL;
+ }
+ else
+ {
+ if((m_pCurAsmRef = new AsmManAssembly))
+ {
+ memset(m_pCurAsmRef,0,sizeof(AsmManAssembly));
+ m_pCurAsmRef->usVerMajor = (USHORT)0xFFFF;
+ m_pCurAsmRef->usVerMinor = (USHORT)0xFFFF;
+ m_pCurAsmRef->usBuild = (USHORT)0xFFFF;
+ m_pCurAsmRef->usRevision = (USHORT)0xFFFF;
+ m_pCurAsmRef->szName = szName;
+ m_pCurAsmRef->szAlias = szAlias ? szAlias : szName;
+ m_pCurAsmRef->dwAlias = (DWORD)strlen(m_pCurAsmRef->szAlias);
+ m_pCurAsmRef->dwAttr = dwAttr;
+ m_pCurAsmRef->isRef = isRef;
+ m_pCurAsmRef->isAutodetect = FALSE;
+ m_pCurAsmRef->m_fNew = TRUE;
+ if(!isRef) m_pAssembly = m_pCurAsmRef;
+ }
+ else
+ report->error("Failed to allocate AsmManAssembly structure\n");
+ }
+ ((Assembler*)m_pAssembler)->m_tkCurrentCVOwner = 0;
+ ((Assembler*)m_pAssembler)->m_CustomDescrListStack.PUSH(((Assembler*)m_pAssembler)->m_pCustomDescrList);
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = m_pCurAsmRef ? &(m_pCurAsmRef->m_CustomDescrList) : NULL;
+
+}
+// copied from asmparse.y
+static void corEmitInt(BinStr* buff, unsigned data)
+{
+ unsigned cnt = CorSigCompressData(data, buff->getBuff(5));
+ buff->remove(5 - cnt);
+}
+
+void AsmMan::EmitDebuggableAttribute(mdToken tkOwner)
+{
+ mdToken tkCA;
+ Assembler* pAsm = (Assembler*)m_pAssembler;
+ mdToken tkTypeSpec, tkMscorlib, tkParamType;
+ BinStr *pbsSig = new BinStr();
+ BinStr* bsBytes = new BinStr();;
+ char* szName;
+ tkMscorlib = pAsm->m_fIsMscorlib ? 1 : pAsm->GetBaseAsmRef();
+ tkTypeSpec = pAsm->ResolveClassRef(tkMscorlib,"System.Diagnostics.DebuggableAttribute",NULL);
+
+ EmitAssemblyRefs(); // just in case we gained 'mscorlib' AsmRef in GetAsmRef above
+
+ BOOL fOldStyle = FALSE;
+ if(tkMscorlib == 1)
+ fOldStyle = (m_pAssembly->usVerMajor == 1);
+ else
+ {
+ AsmManAssembly *pAssembly = GetAsmRefByName("mscorlib");
+ if(pAssembly != NULL)
+ {
+ fOldStyle = (pAssembly->usVerMajor == 1);
+ }
+ }
+
+ bsBytes->appendInt8(1);
+ bsBytes->appendInt8(0);
+ if(fOldStyle)
+ {
+ pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
+ corEmitInt(pbsSig,2);
+ pbsSig->appendInt8(ELEMENT_TYPE_VOID);
+ pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN);
+ pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN);
+
+ //New to old: 0x101->(true,true),0x03->(true,false),0x103->(true,true)+warning
+ bsBytes->appendInt8(1);
+ bsBytes->appendInt8((pAsm->m_dwIncludeDebugInfo==0x03 ? 0 : 1));
+ if(pAsm->m_dwIncludeDebugInfo == 0x103)
+ {
+ report->warn("\nOption /DEBUG=IMPL is invalid for legacy DebuggableAttribute, /DEBUG used.\n" );
+ }
+ }
+ else
+ {
+ BinStr bsSigArg;
+ char buffer[80];
+ sprintf_s(buffer,80,
+ "%s%c%s",
+ "System.Diagnostics.DebuggableAttribute",
+ NESTING_SEP,
+ "DebuggingModes"
+ );
+
+ tkParamType = pAsm->ResolveClassRef(tkMscorlib,buffer, NULL);
+
+ bsSigArg.appendInt8(ELEMENT_TYPE_VALUETYPE);
+
+ unsigned cnt = CorSigCompressToken(tkParamType, bsSigArg.getBuff(5));
+ bsSigArg.remove(5 - cnt);
+
+ pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
+ corEmitInt(pbsSig,1);
+ pbsSig->appendInt8(ELEMENT_TYPE_VOID);
+ pbsSig->append(&bsSigArg);
+
+ bsBytes->appendInt32(pAsm->m_dwIncludeDebugInfo);
+ }
+ bsBytes->appendInt8(0);
+ bsBytes->appendInt8(0);
+
+ szName = new char[16];
+ strcpy_s(szName,16,".ctor");
+ tkCA = pAsm->MakeMemberRef(tkTypeSpec,szName,pbsSig);
+ pAsm->DefineCV(new CustomDescr(tkOwner,tkCA,bsBytes));
+}
+
+void AsmMan::EndAssembly()
+{
+ if(m_pCurAsmRef)
+ {
+ if(m_pCurAsmRef->isRef)
+ { // list the assembly ref
+ if(GetAsmRefByName(m_pCurAsmRef->szAlias))
+ {
+ //report->warn("Multiple declarations of Assembly Ref '%s', ignored except the 1st one\n",m_pCurAsmRef->szName);
+ delete m_pCurAsmRef;
+ m_pCurAsmRef = NULL;
+ return;
+ }
+ m_AsmRefLst.PUSH(m_pCurAsmRef);
+ m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef);
+ }
+ else
+ {
+ HRESULT hr = S_OK;
+ m_pCurAsmRef->tkTok = TokenFromRid(1,mdtAssembly);
+
+ // Determine the strong name public key. This may have been set
+ // via a directive in the source or from the command line (which
+ // overrides the directive). From the command line we may have
+ // been provided with a file or the name of a CAPI key
+ // container. Either may contain a public key or a full key
+ // pair.
+ if (((Assembler*)m_pAssembler)->m_wzKeySourceName)
+ {
+ // Key file versus container is determined by the first
+ // character of the source ('@' for container).
+ if (*(((Assembler*)m_pAssembler)->m_wzKeySourceName) == L'@')
+ {
+ report->error("Error: ilasm on CoreCLR does not support getting public key from container.\n");
+ m_pCurAsmRef = NULL;
+ return;
+ }
+ else
+ {
+ // Read public key or key pair from file.
+ HANDLE hFile = WszCreateFile(((Assembler*)m_pAssembler)->m_wzKeySourceName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL);
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ hr = GetLastError();
+ report->error("Failed to open key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr);
+ m_pCurAsmRef = NULL;
+ return;
+ }
+
+ // Determine file size and allocate an appropriate buffer.
+ m_sStrongName.m_cbPublicKey = SafeGetFileSize(hFile, NULL);
+ if (m_sStrongName.m_cbPublicKey == 0xffffffff) {
+ report->error("File size too large\n");
+ m_pCurAsmRef = NULL;
+ CloseHandle(hFile);
+ return;
+ }
+
+ m_sStrongName.m_pbPublicKey = new BYTE[m_sStrongName.m_cbPublicKey];
+ if (m_sStrongName.m_pbPublicKey == NULL) {
+ report->error("Failed to allocate key buffer\n");
+ m_pCurAsmRef = NULL;
+ CloseHandle(hFile);
+ return;
+ }
+ m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedByNew;
+
+ // Read the file into the buffer.
+ DWORD dwBytesRead;
+ if (!ReadFile(hFile, m_sStrongName.m_pbPublicKey, m_sStrongName.m_cbPublicKey, &dwBytesRead, NULL)) {
+ hr = GetLastError();
+ report->error("Failed to read key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr);
+ m_pCurAsmRef = NULL;
+ CloseHandle(hFile);
+ return;
+ }
+
+ CloseHandle(hFile);
+
+ // Guess whether we're full or delay signing based on
+ // whether the blob passed to us looks like a public
+ // key. (I.e. we may just have copied a full key pair
+ // into the public key buffer).
+ if (m_sStrongName.m_cbPublicKey >= sizeof(PublicKeyBlob) &&
+ (offsetof(PublicKeyBlob, PublicKey) +
+ ((PublicKeyBlob*)m_sStrongName.m_pbPublicKey)->cbPublicKey) == m_sStrongName.m_cbPublicKey)
+ m_sStrongName.m_fFullSign = FALSE;
+ else
+ m_sStrongName.m_fFullSign = TRUE;
+
+ // If we really have a key pair, we'll move it into a
+ // key container so the signing code gets the key pair
+ // from a consistent place.
+ if (m_sStrongName.m_fFullSign)
+ {
+ report->error("Error: ilasm on CoreCLR does not support full sign.\n");
+ m_pCurAsmRef = NULL;
+ return;
+ }
+ }
+ }
+ else
+ {
+ if (m_pAssembly->pPublicKey)
+ {
+ m_sStrongName.m_pbPublicKey = m_pAssembly->pPublicKey->ptr();
+ m_sStrongName.m_cbPublicKey = m_pAssembly->pPublicKey->length();
+ }
+ else
+ {
+ m_sStrongName.m_pbPublicKey = NULL;
+ m_sStrongName.m_cbPublicKey = 0;
+ }
+
+ m_sStrongName.m_wzKeyContainer = NULL;
+ m_sStrongName.m_fFullSign = FALSE;
+ m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::NotAllocated;
+ }
+ }
+ m_pCurAsmRef = NULL;
+ }
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP();
+}
+
+void FillAssemblyMetadata(AsmManAssembly *pAsm, ASSEMBLYMETADATA *pmd)
+{
+ pmd->usMajorVersion = pAsm->usVerMajor;
+ pmd->usMinorVersion = pAsm->usVerMinor;
+ pmd->usBuildNumber = pAsm->usBuild;
+ pmd->usRevisionNumber = pAsm->usRevision;
+ if(pmd->usMajorVersion == 0xFFFF) pmd->usMajorVersion = 0;
+ if(pmd->usMinorVersion == 0xFFFF) pmd->usMinorVersion = 0;
+ if(pmd->usBuildNumber == 0xFFFF) pmd->usBuildNumber = 0;
+ if(pmd->usRevisionNumber == 0xFFFF) pmd->usRevisionNumber = 0;
+
+ if(pAsm->pLocale != NULL)
+ {
+ pmd->szLocale = (LPWSTR)(pAsm->pLocale->ptr());
+ pmd->cbLocale = pAsm->pLocale->length()/((ULONG)sizeof(WCHAR));
+ }
+ else
+ {
+ pmd->szLocale = NULL;
+ pmd->cbLocale = 0;
+ }
+
+ pmd->rProcessor = NULL;
+ pmd->rOS = NULL;
+ pmd->ulProcessor = 0;
+ pmd->ulOS = 0;
+}
+
+void AsmMan::EmitAssemblyRefs()
+{
+ int i;
+ HRESULT hr = S_OK;
+ ASSEMBLYMETADATA md;
+ mdToken tk;
+
+ for(i=0; (m_pCurAsmRef=m_AsmRefLst.PEEK(i)) != NULL; i++)
+ {
+ if(!m_pCurAsmRef->m_fNew) continue;
+ m_pCurAsmRef->m_fNew = FALSE;
+
+ wzUniBuf[0] = 0;
+ FillAssemblyMetadata(m_pCurAsmRef,&md);
+
+ // See if we've got a full public key or the tokenized version (or neither).
+ BYTE *pbPublicKeyOrToken = NULL;
+ DWORD cbPublicKeyOrToken = 0;
+ DWORD dwFlags = m_pCurAsmRef->dwAttr;
+ if (m_pCurAsmRef->pPublicKeyToken)
+ {
+ pbPublicKeyOrToken = m_pCurAsmRef->pPublicKeyToken->ptr();
+ cbPublicKeyOrToken = m_pCurAsmRef->pPublicKeyToken->length();
+
+ }
+ else if (m_pCurAsmRef->pPublicKey)
+ {
+ pbPublicKeyOrToken = m_pCurAsmRef->pPublicKey->ptr();
+ cbPublicKeyOrToken = m_pCurAsmRef->pPublicKey->length();
+ dwFlags |= afPublicKey;
+ }
+ // Convert name to Unicode
+ WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf);
+ hr = m_pAsmEmitter->DefineAssemblyRef( // S_OK or error.
+ pbPublicKeyOrToken, // [IN] Public key or token of the assembly.
+ cbPublicKeyOrToken, // [IN] Count of bytes in the key or token.
+ (LPCWSTR)wzUniBuf, // [IN] Name of the assembly being referenced.
+ (const ASSEMBLYMETADATA*)&md, // [IN] Assembly MetaData.
+ (m_pCurAsmRef->pHashBlob ? (const void*)(m_pCurAsmRef->pHashBlob->ptr()) : NULL), // [IN] Hash Blob.
+ (m_pCurAsmRef->pHashBlob ? m_pCurAsmRef->pHashBlob->length() : 0), // [IN] Count of bytes in the Hash Blob.
+ dwFlags, // [IN] Flags.
+ (mdAssemblyRef*)&tk); // [OUT] Returned AssemblyRef token.
+ if(m_pCurAsmRef->tkTok != tk)
+ {
+ report->error("AsmRef'%S' tok %8.8X -> %8.8X\n",wzUniBuf,m_pCurAsmRef->tkTok,tk);
+ }
+ if(FAILED(hr)) report->error("Failed to define assembly ref '%s': 0x%08X\n",m_pCurAsmRef->szName,hr);
+ else
+ {
+ ((Assembler*)m_pAssembler)->EmitCustomAttributes(m_pCurAsmRef->tkTok, &(m_pCurAsmRef->m_CustomDescrList));
+ }
+ } // end for(i=0; m_pCurAsmRef=m_AsmRefLst.PEEK(i); i++)
+}
+
+void AsmMan::EmitAssembly()
+{
+ HRESULT hr = S_OK;
+ ASSEMBLYMETADATA md;
+
+ wzUniBuf[0] = 0;
+ if(m_pAssembly == NULL) return;
+ if(!m_pAssembly->m_fNew) return;
+ m_pAssembly->m_fNew = FALSE;
+
+ FillAssemblyMetadata(m_pAssembly, &md);
+
+ // Convert name to Unicode
+ WszMultiByteToWideChar(g_uCodePage,0,m_pAssembly->szName,-1,wzUniBuf,dwUniBuf);
+
+ hr = m_pAsmEmitter->DefineAssembly( // S_OK or error.
+ (const void*)(m_sStrongName.m_pbPublicKey), // [IN] Public key of the assembly.
+ m_sStrongName.m_cbPublicKey, // [IN] Count of bytes in the public key.
+ m_pAssembly->ulHashAlgorithm, // [IN] Hash algorithm used to hash the files.
+ (LPCWSTR)wzUniBuf, // [IN] Name of the assembly.
+ (const ASSEMBLYMETADATA*)&md, // [IN] Assembly MetaData.
+ m_pAssembly->dwAttr, // [IN] Flags.
+ (mdAssembly*)&(m_pAssembly->tkTok)); // [OUT] Returned Assembly token.
+
+ if(FAILED(hr)) report->error("Failed to define assembly '%s': 0x%08X\n",m_pAssembly->szName,hr);
+ else
+ {
+ Assembler* pAsm = ((Assembler*)m_pAssembler);
+ pAsm->EmitSecurityInfo(m_pAssembly->tkTok,
+ m_pAssembly->m_pPermissions,
+ m_pAssembly->m_pPermissionSets);
+ if(pAsm->m_dwIncludeDebugInfo)
+ {
+ EmitDebuggableAttribute(m_pAssembly->tkTok);
+ }
+ pAsm->EmitCustomAttributes(m_pAssembly->tkTok, &(m_pAssembly->m_CustomDescrList));
+ }
+}
+
+void AsmMan::SetAssemblyPublicKey(BinStr* pPublicKey)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->pPublicKey = pPublicKey;
+ }
+}
+
+void AsmMan::SetAssemblyPublicKeyToken(BinStr* pPublicKeyToken)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->pPublicKeyToken = pPublicKeyToken;
+ }
+}
+
+void AsmMan::SetAssemblyHashAlg(ULONG ulAlgID)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->ulHashAlgorithm = ulAlgID;
+ }
+}
+
+void AsmMan::SetAssemblyVer(USHORT usMajor, USHORT usMinor, USHORT usBuild, USHORT usRevision)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->usVerMajor = usMajor;
+ m_pCurAsmRef->usVerMinor = usMinor;
+ m_pCurAsmRef->usBuild = usBuild;
+ m_pCurAsmRef->usRevision = usRevision;
+ }
+}
+
+void AsmMan::SetAssemblyLocale(BinStr* pLocale, BOOL bConvertToUnicode)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->pLocale = bConvertToUnicode ? ::BinStrToUnicode(pLocale) : pLocale;
+ }
+}
+
+void AsmMan::SetAssemblyHashBlob(BinStr* pHashBlob)
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->pHashBlob = pHashBlob;
+ }
+}
+
+void AsmMan::SetAssemblyAutodetect()
+{
+ if(m_pCurAsmRef)
+ {
+ m_pCurAsmRef->isAutodetect = TRUE;
+ }
+}
+
+void AsmMan::StartComType(__in __nullterminated char* szName, DWORD dwAttr)
+{
+ if((m_pCurComType = new AsmManComType))
+ {
+ memset(m_pCurComType,0,sizeof(AsmManComType));
+ m_pCurComType->szName = szName;
+ m_pCurComType->dwAttr = dwAttr;
+ m_pCurComType->m_fNew = TRUE;
+ ((Assembler*)m_pAssembler)->m_tkCurrentCVOwner = 0;
+ ((Assembler*)m_pAssembler)->m_CustomDescrListStack.PUSH(((Assembler*)m_pAssembler)->m_pCustomDescrList);
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = &(m_pCurComType->m_CustomDescrList);
+ }
+ else
+ report->error("Failed to allocate AsmManComType structure\n");
+}
+
+void AsmMan::EndComType()
+{
+ if(m_pCurComType)
+ {
+ if(m_pAssembler)
+ {
+ Class* pClass =((Assembler*)m_pAssembler)->m_pCurClass;
+ if(pClass)
+ {
+ m_pCurComType->tkClass = pClass->m_cl;
+ if(pClass->m_pEncloser)
+ {
+ mdTypeDef tkEncloser = pClass->m_pEncloser->m_cl;
+ AsmManComType* pCT;
+ for(unsigned i=0; (pCT=m_ComTypeLst.PEEK(i)); i++)
+ {
+ if(pCT->tkClass == tkEncloser)
+ {
+ m_pCurComType->szComTypeName = pCT->szName;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (IsTdNested(m_pCurComType->dwAttr) && GetComTypeByName(m_pCurComType->szName, m_pCurComType->szComTypeName) != NULL)
+ {
+ report->error("Invalid TypeDefID of exported type\n");
+ delete m_pCurComType;
+ }
+ else
+ {
+ m_ComTypeLst.PUSH(m_pCurComType);
+ }
+
+ m_pCurComType = NULL;
+ ((Assembler*)m_pAssembler)->m_tkCurrentCVOwner = 0;
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP();
+ }
+}
+
+void AsmMan::SetComTypeFile(__in __nullterminated char* szFileName)
+{
+ if(m_pCurComType)
+ {
+ m_pCurComType->szFileName = szFileName;
+ }
+}
+
+void AsmMan::SetComTypeAsmRef(__in __nullterminated char* szAsmRefName)
+{
+ if(m_pCurComType)
+ {
+ m_pCurComType->szAsmRefName = szAsmRefName;
+ }
+}
+
+void AsmMan::SetComTypeComType(__in __nullterminated char* szComTypeName)
+{
+ if(m_pCurComType)
+ {
+ m_pCurComType->szComTypeName = szComTypeName;
+ }
+}
+BOOL AsmMan::SetComTypeImplementationTok(mdToken tk)
+{
+ if(m_pCurComType)
+ {
+ switch(TypeFromToken(tk))
+ {
+ case mdtAssemblyRef:
+ case mdtExportedType:
+ case mdtFile:
+ m_pCurComType->tkImpl = tk;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+BOOL AsmMan::SetComTypeClassTok(mdToken tkClass)
+{
+ if((m_pCurComType)&&(TypeFromToken(tkClass)==mdtTypeDef))
+ {
+ m_pCurComType->tkClass = tkClass;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void AsmMan::StartManifestRes(__in __nullterminated char* szName, __in __nullterminated char* szAlias, DWORD dwAttr)
+{
+ if((m_pCurManRes = new AsmManRes))
+ {
+ m_pCurManRes->szName = szName;
+ m_pCurManRes->szAlias = szAlias;
+ m_pCurManRes->dwAttr = dwAttr;
+ m_pCurManRes->m_fNew = TRUE;
+ ((Assembler*)m_pAssembler)->m_tkCurrentCVOwner = 0;
+ ((Assembler*)m_pAssembler)->m_CustomDescrListStack.PUSH(((Assembler*)m_pAssembler)->m_pCustomDescrList);
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = &(m_pCurManRes->m_CustomDescrList);
+ }
+ else
+ report->error("Failed to allocate AsmManRes structure\n");
+}
+
+void AsmMan::EndManifestRes()
+{
+ if(m_pCurManRes)
+ {
+ m_ManResLst.PUSH(m_pCurManRes);
+ m_pCurManRes = NULL;
+ ((Assembler*)m_pAssembler)->m_tkCurrentCVOwner = 0;
+ ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP();
+ }
+}
+
+
+void AsmMan::SetManifestResFile(__in __nullterminated char* szFileName, ULONG ulOffset)
+{
+ if(m_pCurManRes)
+ {
+ m_pCurManRes->szFileName = szFileName;
+ m_pCurManRes->ulOffset = ulOffset;
+ }
+}
+
+void AsmMan::SetManifestResAsmRef(__in __nullterminated char* szAsmRefName)
+{
+ if(m_pCurManRes)
+ {
+ m_pCurManRes->szAsmRefName = szAsmRefName;
+ }
+}
+
+HRESULT AsmMan::EmitManifest()
+{
+ //AsmManAssembly* pAsmRef;
+ AsmManComType* pComType;
+ AsmManRes* pManRes;
+ HRESULT hr = S_OK;
+
+ wzUniBuf[0] = 0;
+
+ if(m_pAsmEmitter==NULL)
+ hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &m_pAsmEmitter);
+
+ if(SUCCEEDED(hr))
+ {
+ EmitFiles();
+ EmitAssembly();
+
+ if((((Assembler*)m_pAssembler)->m_dwIncludeDebugInfo != 0) && (m_pAssembly == NULL)
+ && !(((Assembler*)m_pAssembler)->m_fENCMode))
+ {
+ mdToken tkOwner, tkMscorlib;
+ tkMscorlib = ((Assembler*)m_pAssembler)->GetAsmRef("mscorlib");
+ tkOwner = ((Assembler*)m_pAssembler)->ResolveClassRef(tkMscorlib,
+ "System.Runtime.CompilerServices.AssemblyAttributesGoHere",
+ NULL);
+ EmitDebuggableAttribute(tkOwner);
+ }
+
+ // Emit all com types
+ unsigned i;
+ for(i = 0; (pComType = m_ComTypeLst.PEEK(i)); i++)
+ {
+ if(!pComType->m_fNew) continue;
+ pComType->m_fNew = FALSE;
+
+ WszMultiByteToWideChar(g_uCodePage,0,pComType->szName,-1,wzUniBuf,dwUniBuf);
+ mdToken tkImplementation = mdTokenNil;
+ if(pComType->tkImpl) tkImplementation = pComType->tkImpl;
+ else if(pComType->szFileName)
+ {
+ tkImplementation = GetFileTokByName(pComType->szFileName);
+ if(tkImplementation==mdFileNil)
+ {
+ report->error("Undefined File '%s' in ExportedType '%s'\n",pComType->szFileName,pComType->szName);
+ if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
+ }
+ }
+ else if(pComType->szAsmRefName)
+ {
+ tkImplementation = GetAsmRefTokByName(pComType->szAsmRefName);
+ if(RidFromToken(tkImplementation)==0)
+ {
+ report->error("Undefined AssemblyRef '%s' in ExportedType '%s'\n",pComType->szAsmRefName,pComType->szName);
+ if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
+ }
+ }
+ else if(pComType->szComTypeName)
+ {
+ char* szLastName = strrchr(pComType->szComTypeName, NESTING_SEP);
+
+ if(szLastName)
+ {
+ *szLastName = 0;
+ szLastName ++;
+ tkImplementation = GetComTypeTokByName(szLastName, pComType->szComTypeName);
+ *(szLastName-1) = NESTING_SEP; // not really necessary
+ }
+
+ else
+ {
+ tkImplementation = GetComTypeTokByName(pComType->szComTypeName);
+ }
+
+ if(tkImplementation==mdExportedTypeNil)
+ {
+ report->error("Undefined ExportedType '%s' in ExportedType '%s'\n",pComType->szComTypeName,pComType->szName);
+ if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
+ }
+ }
+ else
+ {
+ report->warn("Undefined implementation in ExportedType '%s' -- ExportType not emitted\n",pComType->szName);
+ if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
+ }
+ hr = m_pAsmEmitter->DefineExportedType( // S_OK or error.
+ (LPCWSTR)wzUniBuf, // [IN] Name of the Com Type.
+ tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ComType.
+ (mdTypeDef)pComType->tkClass, // [IN] TypeDef token within the file.
+ pComType->dwAttr, // [IN] Flags.
+ (mdExportedType*)&(pComType->tkTok)); // [OUT] Returned ComType token.
+ if(FAILED(hr)) report->error("Failed to define ExportedType '%s': 0x%08X\n",pComType->szName,hr);
+ else
+ {
+ ((Assembler*)m_pAssembler)->EmitCustomAttributes(pComType->tkTok, &(pComType->m_CustomDescrList));
+ }
+ }
+
+ // Emit all manifest resources
+ m_dwMResSizeTotal = 0;
+ m_dwMResNum = 0;
+ for(i = 0; (pManRes = m_ManResLst.PEEK(i)); i++)
+ {
+ BOOL fOK = TRUE;
+ mdToken tkImplementation = mdFileNil;
+
+ if(!pManRes->m_fNew) continue;
+ pManRes->m_fNew = FALSE;
+
+ WszMultiByteToWideChar(g_uCodePage,0,pManRes->szAlias,-1,wzUniBuf,dwUniBuf);
+ if(pManRes->szAsmRefName)
+ {
+ tkImplementation = GetAsmRefTokByName(pManRes->szAsmRefName);
+ if(RidFromToken(tkImplementation)==0)
+ {
+ report->error("Undefined AssemblyRef '%s' in MResource '%s'\n",pManRes->szAsmRefName,pManRes->szName);
+ fOK = FALSE;
+ }
+ }
+ else if(pManRes->szFileName)
+ {
+ tkImplementation = GetFileTokByName(pManRes->szFileName);
+ if(RidFromToken(tkImplementation)==0)
+ {
+ report->error("Undefined File '%s' in MResource '%s'\n",pManRes->szFileName,pManRes->szName);
+ fOK = FALSE;
+ }
+ }
+ else // embedded mgd.resource, go after the file
+ {
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ int j;
+ WCHAR wzFileName[2048];
+ WCHAR* pwz;
+
+ pManRes->ulOffset = m_dwMResSizeTotal;
+ for(j=0; (hFile == INVALID_HANDLE_VALUE)&&(pwzInputFiles[j] != NULL); j++)
+ {
+ wcscpy_s(wzFileName,2048,pwzInputFiles[j]);
+ pwz = wcsrchr(wzFileName,DIRECTORY_SEPARATOR_CHAR_A);
+#ifdef TARGET_WINDOWS
+ if(pwz == NULL) pwz = wcsrchr(wzFileName,':');
+#endif
+ if(pwz == NULL) pwz = &wzFileName[0];
+ else pwz++;
+ wcscpy_s(pwz,2048-(pwz-wzFileName),wzUniBuf);
+ hFile = WszCreateFile(wzFileName, GENERIC_READ, FILE_SHARE_READ,
+ 0, OPEN_EXISTING, 0, 0);
+ }
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ report->error("Failed to open managed resource file '%s'\n",pManRes->szAlias);
+ fOK = FALSE;
+ }
+ else
+ {
+ if (m_dwMResNum >= MAX_MANIFEST_RESOURCES)
+ {
+ report->error("Too many resources (implementation limit: %d); skipping file '%s'\n",MAX_MANIFEST_RESOURCES,pManRes->szAlias);
+ fOK = FALSE;
+ }
+ else
+ {
+ m_dwMResSize[m_dwMResNum] = SafeGetFileSize(hFile,NULL);
+ if(m_dwMResSize[m_dwMResNum] == 0xFFFFFFFF)
+ {
+ report->error("Failed to get size of managed resource file '%s'\n",pManRes->szAlias);
+ fOK = FALSE;
+ }
+ else
+ {
+ m_dwMResSizeTotal += m_dwMResSize[m_dwMResNum]+sizeof(DWORD);
+ m_wzMResName[m_dwMResNum] = new WCHAR[wcslen(wzFileName)+1];
+ wcscpy_s(m_wzMResName[m_dwMResNum],wcslen(wzFileName)+1,wzFileName);
+ m_fMResNew[m_dwMResNum] = TRUE;
+ m_dwMResNum++;
+ }
+ CloseHandle(hFile);
+ }
+ }
+ }
+ if(fOK || ((Assembler*)m_pAssembler)->OnErrGo)
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pManRes->szName,-1,wzUniBuf,dwUniBuf);
+ hr = m_pAsmEmitter->DefineManifestResource( // S_OK or error.
+ (LPCWSTR)wzUniBuf, // [IN] Name of the resource.
+ tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource.
+ pManRes->ulOffset, // [IN] Offset to the beginning of the resource within the file.
+ pManRes->dwAttr, // [IN] Flags.
+ (mdManifestResource*)&(pManRes->tkTok)); // [OUT] Returned ManifestResource token.
+ if(FAILED(hr))
+ report->error("Failed to define manifest resource '%s': 0x%08X\n",pManRes->szName,hr);
+ }
+ }
+
+
+ m_pAsmEmitter->Release();
+ m_pAsmEmitter = NULL;
+ }
+ else
+ report->error("Failed to obtain IMetaDataAssemblyEmit interface: 0x%08X\n",hr);
+ return hr;
+}
+
diff --git a/src/coreclr/ilasm/asmman.hpp b/src/coreclr/ilasm/asmman.hpp
new file mode 100644
index 00000000000..1290c9b2707
--- /dev/null
+++ b/src/coreclr/ilasm/asmman.hpp
@@ -0,0 +1,295 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// asmman.hpp - header file for manifest-related ILASM functions
+//
+
+#ifndef ASMMAN_HPP
+#define ASMMAN_HPP
+
+#include "specstrings.h"
+
+struct AsmManFile
+{
+ char* szName;
+ mdToken tkTok;
+ DWORD dwAttr;
+ BinStr* pHash;
+ BOOL m_fNew;
+ CustomDescrList m_CustomDescrList;
+ AsmManFile()
+ {
+ szName = NULL;
+ pHash = NULL;
+ m_fNew = TRUE;
+ }
+ ~AsmManFile()
+ {
+ if(szName) delete szName;
+ if(pHash) delete pHash;
+ }
+ int ComparedTo(AsmManFile* pX){ return strcmp(szName,pX->szName); }
+};
+//typedef SORTEDARRAY<AsmManFile> AsmManFileList;
+typedef FIFO<AsmManFile> AsmManFileList;
+
+struct AsmManAssembly
+{
+ BOOL isRef;
+ BOOL isAutodetect;
+ char* szName;
+ char* szAlias;
+ DWORD dwAlias;
+ mdToken tkTok;
+ DWORD dwAttr;
+ BinStr* pPublicKey;
+ BinStr* pPublicKeyToken;
+ ULONG ulHashAlgorithm;
+ BinStr* pHashBlob;
+ BinStr* pLocale;
+ BOOL m_fNew;
+ // Security attributes
+ PermissionDecl* m_pPermissions;
+ PermissionSetDecl* m_pPermissionSets;
+ CustomDescrList m_CustomDescrList;
+ USHORT usVerMajor;
+ USHORT usVerMinor;
+ USHORT usBuild;
+ USHORT usRevision;
+ AsmManAssembly()
+ {
+ /*
+ usVerMajor = usVerMinor = usBuild = usRevision = 0xFFFF;
+ szName = szAlias = NULL;
+ dwAlias = dwAttr = 0;
+ tkTok = 0;
+ pPublicKey = pPublicKeyToken =pHashBlob = pLocale = NULL;
+ ulHashAlgorithm = 0;
+ m_fNew = TRUE;
+ isAutodetect = isRef = FALSE;
+ */
+ }
+ ~AsmManAssembly()
+ {
+ if(szAlias && (szAlias != szName)) delete [] szAlias;
+ if(szName) delete [] szName;
+ if(pPublicKey) delete pPublicKey;
+ if(pPublicKeyToken) delete pPublicKeyToken;
+ if(pHashBlob) delete pHashBlob;
+ if(pLocale) delete pLocale;
+ }
+ int ComparedTo(AsmManAssembly* pX){ return strcmp(szAlias,pX->szAlias); }
+};
+//typedef SORTEDARRAY<AsmManAssembly> AsmManAssemblyList;
+typedef FIFO<AsmManAssembly> AsmManAssemblyList;
+
+struct AsmManComType
+{
+ char* szName;
+ mdToken tkTok;
+ mdToken tkImpl;
+ DWORD dwAttr;
+ char* szFileName;
+ char* szAsmRefName;
+ char* szComTypeName;
+ mdToken tkClass;
+ BOOL m_fNew;
+ CustomDescrList m_CustomDescrList;
+ AsmManComType()
+ {
+ szName = szFileName = szAsmRefName = szComTypeName = NULL;
+ m_fNew = TRUE;
+ tkImpl = 0;
+ };
+ ~AsmManComType()
+ {
+ if(szName) delete szName;
+ if(szFileName) delete szFileName;
+ };
+ int ComparedTo(AsmManComType* pX){ return strcmp(szName,pX->szName); };
+};
+//typedef SORTEDARRAY<AsmManComType> AsmManComTypeList;
+typedef FIFO<AsmManComType> AsmManComTypeList;
+
+
+struct AsmManRes
+{
+ char* szName;
+ char* szAlias;
+ mdToken tkTok;
+ DWORD dwAttr;
+ char* szFileName;
+ ULONG ulOffset;
+ BOOL m_fNew;
+ CustomDescrList m_CustomDescrList;
+ char* szAsmRefName;
+ AsmManRes() { szName = szAlias = szAsmRefName = szFileName = NULL; ulOffset = 0; tkTok = 0; dwAttr = 0; m_fNew = TRUE; };
+ ~AsmManRes()
+ {
+ if(szAlias && (szAlias != szName)) delete szAlias;
+ if(szName) delete szName;
+ if(szFileName) delete szFileName;
+ if(szAsmRefName) delete szAsmRefName;
+ }
+};
+typedef FIFO<AsmManRes> AsmManResList;
+
+struct AsmManModRef
+{
+ char* szName;
+ mdToken tkTok;
+ BOOL m_fNew;
+ AsmManModRef() {szName = NULL; tkTok = 0; m_fNew = TRUE; };
+ ~AsmManModRef() { if(szName) delete szName; };
+};
+typedef FIFO<AsmManModRef> AsmManModRefList;
+
+struct AsmManStrongName
+{
+ enum AllocationState
+ {
+ NotAllocated = 0,
+ AllocatedBySNApi,
+ AllocatedByNew
+ };
+
+ BYTE *m_pbSignatureKey;
+ DWORD m_cbSignatureKey;
+ BYTE *m_pbPublicKey;
+ DWORD m_cbPublicKey;
+ BYTE *m_pbPrivateKey;
+ DWORD m_cbPrivateKey;
+ WCHAR *m_wzKeyContainer;
+ BOOL m_fFullSign;
+
+ // Where has the memory pointed to by m_pbPublicKey been taken from:
+ AllocationState m_dwPublicKeyAllocated;
+
+ AsmManStrongName() { ZeroMemory(this, sizeof(*this)); }
+ ~AsmManStrongName()
+ {
+ if (m_dwPublicKeyAllocated == AllocatedByNew)
+ delete [] m_pbPublicKey;
+
+ if (m_pbPrivateKey)
+ delete [] m_pbPrivateKey;
+
+ if (m_pbSignatureKey)
+ delete [] m_pbSignatureKey;
+ }
+};
+
+class ErrorReporter;
+
+class AsmMan
+{
+ AsmManFileList m_FileLst;
+ AsmManComTypeList m_ComTypeLst;
+ AsmManResList m_ManResLst;
+ AsmManModRefList m_ModRefLst;
+
+ AsmManComType* m_pCurComType;
+ AsmManRes* m_pCurManRes;
+ ErrorReporter* report;
+ void* m_pAssembler;
+
+ AsmManFile* GetFileByName(__in __nullterminated char* szFileName);
+ AsmManAssembly* GetAsmRefByName(__in __nullterminated const char* szAsmRefName);
+ AsmManComType* GetComTypeByName(__in_opt __nullterminated char* szComTypeName,
+ __in_opt __nullterminated char* szComEnclosingTypeName = NULL);
+ mdToken GetComTypeTokByName(__in_opt __nullterminated char* szComTypeName,
+ __in_opt __nullterminated char* szComEnclosingTypeName = NULL);
+
+ IMetaDataEmit* m_pEmitter;
+
+public:
+ IMetaDataAssemblyEmit* m_pAsmEmitter;
+ AsmManAssemblyList m_AsmRefLst;
+ AsmManAssembly* m_pAssembly;
+ AsmManAssembly* m_pCurAsmRef;
+ char* m_szScopeName;
+ BinStr* m_pGUID;
+ AsmManStrongName m_sStrongName;
+ // Embedded manifest resources paraphernalia:
+ WCHAR* m_wzMResName[MAX_MANIFEST_RESOURCES];
+ DWORD m_dwMResSize[MAX_MANIFEST_RESOURCES];
+ BOOL m_fMResNew[MAX_MANIFEST_RESOURCES];
+ DWORD m_dwMResNum;
+ DWORD m_dwMResSizeTotal;
+ AsmMan() { m_pAssembly = NULL; m_szScopeName = NULL; m_pGUID = NULL; m_pAsmEmitter = NULL;
+ memset(m_wzMResName,0,sizeof(m_wzMResName));
+ memset(m_dwMResSize,0,sizeof(m_dwMResSize));
+ m_dwMResNum = m_dwMResSizeTotal = 0; };
+ AsmMan(void* pAsm) { m_pAssembly = NULL; m_szScopeName = NULL; m_pGUID = NULL; m_pAssembler = pAsm; m_pAsmEmitter = NULL;
+ memset(m_wzMResName,0,sizeof(m_wzMResName));
+ memset(m_dwMResSize,0,sizeof(m_dwMResSize));
+ m_dwMResNum = m_dwMResSizeTotal = 0; };
+ AsmMan(ErrorReporter* rpt) { m_pAssembly = NULL; m_szScopeName = NULL; m_pGUID = NULL; report = rpt; m_pAsmEmitter = NULL;
+ memset(m_wzMResName,0,sizeof(m_wzMResName));
+ memset(m_dwMResSize,0,sizeof(m_dwMResSize));
+ m_dwMResNum = m_dwMResSizeTotal = 0; };
+ ~AsmMan()
+ {
+ if(m_pAssembly) delete m_pAssembly;
+ if(m_szScopeName) delete m_szScopeName;
+ if(m_pGUID) delete m_pGUID;
+ };
+ void SetErrorReporter(ErrorReporter* rpt) { report = rpt; };
+ HRESULT EmitManifest(void);
+
+ void SetEmitter( IMetaDataEmit* pEmitter) { m_pEmitter = pEmitter; };
+
+ void SetModuleName(__inout_opt __nullterminated char* szName);
+
+ void AddFile(__in __nullterminated char* szName, DWORD dwAttr, BinStr* pHashBlob);
+ void EmitFiles();
+ void EmitDebuggableAttribute(mdToken tkOwner);
+
+ void StartAssembly(__in __nullterminated char* szName, __in_opt __nullterminated char* szAlias, DWORD dwAttr, BOOL isRef);
+ void EndAssembly();
+ void EmitAssemblyRefs();
+ void EmitAssembly();
+ void SetAssemblyPublicKey(BinStr* pPublicKey);
+ void SetAssemblyPublicKeyToken(BinStr* pPublicKeyToken);
+ void SetAssemblyHashAlg(ULONG ulAlgID);
+ void SetAssemblyVer(USHORT usMajor, USHORT usMinor, USHORT usBuild, USHORT usRevision);
+ void SetAssemblyLocale(BinStr* pLocale, BOOL bConvertToUnicode);
+ void SetAssemblyHashBlob(BinStr* pHashBlob);
+ void SetAssemblyAutodetect();
+
+ void StartComType(__in __nullterminated char* szName, DWORD dwAttr);
+ void EndComType();
+ void SetComTypeFile(__in __nullterminated char* szFileName);
+ void SetComTypeAsmRef(__in __nullterminated char* szAsmRefName);
+ void SetComTypeComType(__in __nullterminated char* szComTypeName);
+ BOOL SetComTypeImplementationTok(mdToken tk);
+ BOOL SetComTypeClassTok(mdToken tkClass);
+
+ void StartManifestRes(__in __nullterminated char* szName, __in __nullterminated char* szAlias, DWORD dwAttr);
+ void EndManifestRes();
+ void SetManifestResFile(__in __nullterminated char* szFileName, ULONG ulOffset);
+ void SetManifestResAsmRef(__in __nullterminated char* szAsmRefName);
+
+ AsmManAssembly* GetAsmRefByAsmName(__in __nullterminated const char* szAsmName);
+
+ mdToken GetFileTokByName(__in __nullterminated char* szFileName);
+ mdToken GetAsmRefTokByName(__in __nullterminated const char* szAsmRefName);
+ mdToken GetAsmTokByName(__in __nullterminated const char* szAsmName)
+ { return (m_pAssembly && (strcmp(m_pAssembly->szName,szAsmName)==0)) ? m_pAssembly->tkTok : 0; };
+
+ mdToken GetModuleRefTokByName(__in __nullterminated char* szName)
+ {
+ if(szName && *szName)
+ {
+ AsmManModRef* pMR;
+ for(unsigned i=0; (pMR=m_ModRefLst.PEEK(i)); i++)
+ {
+ if(!strcmp(szName, pMR->szName)) return pMR->tkTok;
+ }
+ }
+ return 0;
+ };
+
+};
+
+#endif
diff --git a/src/coreclr/ilasm/asmparse.h b/src/coreclr/ilasm/asmparse.h
new file mode 100644
index 00000000000..ef377b5e430
--- /dev/null
+++ b/src/coreclr/ilasm/asmparse.h
@@ -0,0 +1,325 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/**************************************************************************/
+/* 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 ~ReadStream() = default;
+
+ 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* 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);
+ virtual ~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
+ 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
+
diff --git a/src/coreclr/ilasm/asmparse.y b/src/coreclr/ilasm/asmparse.y
new file mode 100644
index 00000000000..29179ffcec8
--- /dev/null
+++ b/src/coreclr/ilasm/asmparse.y
@@ -0,0 +1,2063 @@
+%{
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+//
+// File asmparse.y
+//
+#include "ilasmpch.h"
+
+#include "grammar_before.cpp"
+
+%}
+
+%union {
+ CorRegTypeAttr classAttr;
+ CorMethodAttr methAttr;
+ CorFieldAttr fieldAttr;
+ CorMethodImpl implAttr;
+ CorEventAttr eventAttr;
+ CorPropertyAttr propAttr;
+ CorPinvokeMap pinvAttr;
+ CorDeclSecurity secAct;
+ CorFileFlags fileAttr;
+ CorAssemblyFlags asmAttr;
+ CorAssemblyFlags asmRefAttr;
+ CorTypeAttr exptAttr;
+ CorManifestResourceFlags manresAttr;
+ double* float64;
+ __int64* int64;
+ __int32 int32;
+ char* string;
+ BinStr* binstr;
+ Labels* labels;
+ Instr* instr; // instruction opcode
+ NVPair* pair;
+ pTyParList typarlist;
+ mdToken token;
+ TypeDefDescr* tdd;
+ CustomDescr* cad;
+ unsigned short opcode;
+};
+
+ /* These are returned by the LEXER and have values */
+%token ERROR_ BAD_COMMENT_ BAD_LITERAL_ /* bad strings, */
+%token <string> ID /* testing343 */
+%token <string> DOTTEDNAME /* System.Object */
+%token <binstr> QSTRING /* "Hello World\n" */
+%token <string> SQSTRING /* 'Hello World\n' */
+%token <int32> INT32 /* 3425 0x34FA 0352 */
+%token <int64> INT64 /* 342534523534534 0x34FA434644554 */
+%token <float64> FLOAT64 /* -334234 24E-34 */
+%token <int32> HEXBYTE /* 05 1A FA */
+%token <tdd> TYPEDEF_T
+%token <tdd> TYPEDEF_M
+%token <tdd> TYPEDEF_F
+%token <tdd> TYPEDEF_TS
+%token <tdd> TYPEDEF_MR
+%token <tdd> TYPEDEF_CA
+
+
+ /* multi-character punctuation */
+%token DCOLON /* :: */
+%token ELIPSIS /* ... */
+
+ /* Keywords Note the undersores are to avoid collisions as these are common names */
+%token VOID_ BOOL_ CHAR_ UNSIGNED_ INT_ INT8_ INT16_ INT32_ INT64_ FLOAT_ FLOAT32_ FLOAT64_ BYTEARRAY_
+%token UINT_ UINT8_ UINT16_ UINT32_ UINT64_ FLAGS_ CALLCONV_ MDTOKEN_
+%token OBJECT_ STRING_ NULLREF_
+ /* misc keywords */
+%token DEFAULT_ CDECL_ VARARG_ STDCALL_ THISCALL_ FASTCALL_ CLASS_
+%token TYPEDREF_ UNMANAGED_ FINALLY_ HANDLER_ CATCH_ FILTER_ FAULT_
+%token EXTENDS_ IMPLEMENTS_ TO_ AT_ TLS_ TRUE_ FALSE_ _INTERFACEIMPL
+
+ /* class, method, field attributes */
+
+%token VALUE_ VALUETYPE_ NATIVE_ INSTANCE_ SPECIALNAME_ FORWARDER_
+%token STATIC_ PUBLIC_ PRIVATE_ FAMILY_ FINAL_ SYNCHRONIZED_ INTERFACE_ SEALED_ NESTED_
+%token ABSTRACT_ AUTO_ SEQUENTIAL_ EXPLICIT_ ANSI_ UNICODE_ AUTOCHAR_ IMPORT_ ENUM_
+%token VIRTUAL_ NOINLINING_ AGGRESSIVEINLINING_ NOOPTIMIZATION_ AGGRESSIVEOPTIMIZATION_ UNMANAGEDEXP_ BEFOREFIELDINIT_
+%token STRICT_ RETARGETABLE_ WINDOWSRUNTIME_ NOPLATFORM_
+%token METHOD_ FIELD_ PINNED_ MODREQ_ MODOPT_ SERIALIZABLE_ PROPERTY_ TYPE_
+%token ASSEMBLY_ FAMANDASSEM_ FAMORASSEM_ PRIVATESCOPE_ HIDEBYSIG_ NEWSLOT_ RTSPECIALNAME_ PINVOKEIMPL_
+%token _CTOR _CCTOR LITERAL_ NOTSERIALIZED_ INITONLY_ REQSECOBJ_
+ /* method implementation attributes: NATIVE_ and UNMANAGED_ listed above */
+%token CIL_ OPTIL_ MANAGED_ FORWARDREF_ PRESERVESIG_ RUNTIME_ INTERNALCALL_
+ /* PInvoke-specific keywords */
+%token _IMPORT NOMANGLE_ LASTERR_ WINAPI_ AS_ BESTFIT_ ON_ OFF_ CHARMAPERROR_
+
+ /* intruction tokens (actually instruction groupings) */
+%token <opcode> INSTR_NONE INSTR_VAR INSTR_I INSTR_I8 INSTR_R INSTR_BRTARGET INSTR_METHOD INSTR_FIELD
+%token <opcode> INSTR_TYPE INSTR_STRING INSTR_SIG INSTR_TOK
+%token <opcode> INSTR_SWITCH
+
+ /* assember directives */
+%token _CLASS _NAMESPACE _METHOD _FIELD _DATA _THIS _BASE _NESTER
+%token _EMITBYTE _TRY _MAXSTACK _LOCALS _ENTRYPOINT _ZEROINIT
+%token _EVENT _ADDON _REMOVEON _FIRE _OTHER
+%token _PROPERTY _SET _GET DEFAULT_
+%token _PERMISSION _PERMISSIONSET
+
+ /* security actions */
+%token REQUEST_ DEMAND_ ASSERT_ DENY_ PERMITONLY_ LINKCHECK_ INHERITCHECK_
+%token REQMIN_ REQOPT_ REQREFUSE_ PREJITGRANT_ PREJITDENY_ NONCASDEMAND_
+%token NONCASLINKDEMAND_ NONCASINHERITANCE_
+
+ /* extern debug info specifier (to be used by precompilers only) */
+%token _LINE P_LINE _LANGUAGE
+ /* custom value specifier */
+%token _CUSTOM
+ /* local vars zeroinit specifier */
+%token INIT_
+ /* class layout */
+%token _SIZE _PACK
+%token _VTABLE _VTFIXUP FROMUNMANAGED_ CALLMOSTDERIVED_ _VTENTRY RETAINAPPDOMAIN_
+ /* manifest */
+%token _FILE NOMETADATA_ _HASH _ASSEMBLY _PUBLICKEY _PUBLICKEYTOKEN ALGORITHM_ _VER _LOCALE EXTERN_
+%token _MRESOURCE
+%token _MODULE _EXPORT
+%token LEGACY_ LIBRARY_ X86_ AMD64_ ARM_ ARM64_
+ /* field marshaling */
+%token MARSHAL_ CUSTOM_ SYSSTRING_ FIXED_ VARIANT_ CURRENCY_ SYSCHAR_ DECIMAL_ DATE_ BSTR_ TBSTR_ LPSTR_
+%token LPWSTR_ LPTSTR_ OBJECTREF_ IUNKNOWN_ IDISPATCH_ STRUCT_ SAFEARRAY_ BYVALSTR_ LPVOID_ ANY_ ARRAY_ LPSTRUCT_
+%token IIDPARAM_
+ /* parameter keywords */
+%token IN_ OUT_ OPT_
+ /* .param directive */
+%token _PARAM
+ /* method implementations */
+%token _OVERRIDE WITH_
+ /* variant type specifics */
+%token NULL_ ERROR_ HRESULT_ CARRAY_ USERDEFINED_ RECORD_ FILETIME_ BLOB_ STREAM_ STORAGE_
+%token STREAMED_OBJECT_ STORED_OBJECT_ BLOB_OBJECT_ CF_ CLSID_ VECTOR_
+ /* header flags */
+%token _SUBSYSTEM _CORFLAGS ALIGNMENT_ _IMAGEBASE _STACKRESERVE
+
+ /* syntactic sugar */
+%token _TYPEDEF _TEMPLATE _TYPELIST _MSCORLIB
+
+ /* compilation control directives */
+%token P_DEFINE P_UNDEF P_IFDEF P_IFNDEF P_ELSE P_ENDIF P_INCLUDE
+
+ /* newly added tokens go here */
+%token CONSTRAINT_
+
+ /* nonTerminals */
+%type <string> dottedName id methodName atOpt slashedName
+%type <labels> labels
+%type <int32> callConv callKind int32 customHead customHeadWithOwner vtfixupAttr paramAttr ddItemCount variantType repeatOpt truefalse typarAttrib typarAttribs
+%type <int32> iidParamIndex genArity genArityNotEmpty
+%type <float64> float64
+%type <int64> int64
+%type <binstr> sigArgs0 sigArgs1 sigArg type bound bounds1 bytes hexbytes nativeType marshalBlob initOpt compQstring caValue
+%type <binstr> marshalClause
+%type <binstr> fieldInit serInit fieldSerInit
+%type <binstr> f32seq f64seq i8seq i16seq i32seq i64seq boolSeq sqstringSeq classSeq objSeq
+%type <binstr> simpleType
+%type <binstr> tyArgs0 tyArgs1 tyArgs2 typeList typeListNotEmpty tyBound
+%type <binstr> customBlobDescr serializType customBlobArgs customBlobNVPairs
+%type <binstr> secAttrBlob secAttrSetBlob
+%type <int32> fieldOrProp intOrWildcard
+%type <typarlist> typarsRest typars typarsClause
+%type <token> className typeSpec ownerType customType memberRef methodRef mdtoken
+%type <classAttr> classAttr
+%type <methAttr> methAttr
+%type <fieldAttr> fieldAttr
+%type <implAttr> implAttr
+%type <eventAttr> eventAttr
+%type <propAttr> propAttr
+%type <pinvAttr> pinvAttr
+%type <pair> nameValPairs nameValPair
+%type <secAct> secAction
+%type <secAct> psetHead
+%type <fileAttr> fileAttr
+%type <fileAttr> fileEntry
+%type <asmAttr> asmAttr
+%type <exptAttr> exptAttr
+%type <manresAttr> manresAttr
+%type <cad> customDescr customDescrWithOwner
+%type <instr> instr_none instr_var instr_i instr_i8 instr_r instr_brtarget instr_method instr_field
+%type <instr> instr_type instr_string instr_sig instr_tok instr_switch
+%type <instr> instr_r_head
+
+%start decls
+
+/**************************************************************************/
+%%
+
+decls : /* EMPTY */
+ | decls decl
+ ;
+/* Module-level declarations */
+decl : classHead '{' classDecls '}' { PASM->EndClass(); }
+ | nameSpaceHead '{' decls '}' { PASM->EndNameSpace(); }
+ | methodHead methodDecls '}' { if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); }
+ | fieldDecl
+ | dataDecl
+ | vtableDecl
+ | vtfixupDecl
+ | extSourceSpec
+ | fileDecl
+ | assemblyHead '{' assemblyDecls '}' { PASMM->EndAssembly(); }
+ | assemblyRefHead '{' assemblyRefDecls '}' { PASMM->EndAssembly(); }
+ | exptypeHead '{' exptypeDecls '}' { PASMM->EndComType(); }
+ | manifestResHead '{' manifestResDecls '}' { PASMM->EndManifestRes(); }
+ | moduleHead
+ | secDecl
+ | customAttrDecl
+ | _SUBSYSTEM int32 {
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22011) // Suppress PREFast warning about integer overflow/underflow
+#endif
+ PASM->m_dwSubsystem = $2;
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+ }
+ | _CORFLAGS int32 { PASM->m_dwComImageFlags = $2; }
+ | _FILE ALIGNMENT_ int32 { PASM->m_dwFileAlignment = $3;
+ if(($3 & ($3 - 1))||($3 < 0x200)||($3 > 0x10000))
+ PASM->report->error("Invalid file alignment, must be power of 2 from 0x200 to 0x10000\n");}
+ | _IMAGEBASE int64 { PASM->m_stBaseAddress = (ULONGLONG)(*($2)); delete $2;
+ if(PASM->m_stBaseAddress & 0xFFFF)
+ PASM->report->error("Invalid image base, must be 0x10000-aligned\n");}
+ | _STACKRESERVE int64 { PASM->m_stSizeOfStackReserve = (size_t)(*($2)); delete $2; }
+ | languageDecl
+ | typedefDecl
+ | compControl
+ | _TYPELIST '{' classNameSeq '}'
+ | _MSCORLIB { PASM->m_fIsMscorlib = TRUE; }
+ ;
+
+classNameSeq : /* EMPTY */
+ | className classNameSeq
+ ;
+
+compQstring : QSTRING { $$ = $1; }
+ | compQstring '+' QSTRING { $$ = $1; $$->append($3); delete $3; }
+ ;
+
+languageDecl : _LANGUAGE SQSTRING { LPCSTRToGuid($2,&(PASM->m_guidLang)); }
+ | _LANGUAGE SQSTRING ',' SQSTRING { LPCSTRToGuid($2,&(PASM->m_guidLang));
+ LPCSTRToGuid($4,&(PASM->m_guidLangVendor));}
+ | _LANGUAGE SQSTRING ',' SQSTRING ',' SQSTRING { LPCSTRToGuid($2,&(PASM->m_guidLang));
+ LPCSTRToGuid($4,&(PASM->m_guidLangVendor));
+ LPCSTRToGuid($4,&(PASM->m_guidDoc));}
+ ;
+/* Basic tokens */
+id : ID { $$ = $1; }
+ | SQSTRING { $$ = $1; }
+ ;
+
+dottedName : id { $$ = $1; }
+ | DOTTEDNAME { $$ = $1; }
+ | dottedName '.' dottedName { $$ = newStringWDel($1, '.', $3); }
+ ;
+
+int32 : INT32 { $$ = $1; }
+ ;
+
+int64 : INT64 { $$ = $1; }
+ | INT32 { $$ = neg ? new __int64($1) : new __int64((unsigned)$1); }
+ ;
+
+float64 : FLOAT64 { $$ = $1; }
+ | FLOAT32_ '(' int32 ')' { float f; *((__int32*) (&f)) = $3; $$ = new double(f); }
+ | FLOAT64_ '(' int64 ')' { $$ = (double*) $3; }
+ ;
+
+/* Aliasing of types, type specs, methods, fields and custom attributes */
+typedefDecl : _TYPEDEF type AS_ dottedName { PASM->AddTypeDef($2,$4); }
+ | _TYPEDEF className AS_ dottedName { PASM->AddTypeDef($2,$4); }
+ | _TYPEDEF memberRef AS_ dottedName { PASM->AddTypeDef($2,$4); }
+ | _TYPEDEF customDescr AS_ dottedName { $2->tkOwner = 0; PASM->AddTypeDef($2,$4); }
+ | _TYPEDEF customDescrWithOwner AS_ dottedName { PASM->AddTypeDef($2,$4); }
+ ;
+
+/* Compilation control directives are processed within yylex(),
+ displayed here just for grammar completeness */
+compControl : P_DEFINE dottedName { DefineVar($2, NULL); }
+ | P_DEFINE dottedName compQstring { DefineVar($2, $3); }
+ | P_UNDEF dottedName { UndefVar($2); }
+ | P_IFDEF dottedName { SkipToken = !IsVarDefined($2);
+ IfEndif++;
+ }
+ | P_IFNDEF dottedName { SkipToken = IsVarDefined($2);
+ IfEndif++;
+ }
+ | P_ELSE { if(IfEndif == 1) SkipToken = !SkipToken;}
+ | P_ENDIF { if(IfEndif == 0)
+ PASM->report->error("Unmatched #endif\n");
+ else IfEndif--;
+ }
+ | P_INCLUDE QSTRING { _ASSERTE(!"yylex should have dealt with this"); }
+ | ';' { }
+ ;
+
+/* Custom attribute declarations */
+customDescr : _CUSTOM customType { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, NULL); }
+ | _CUSTOM customType '=' compQstring { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, $4); }
+ | _CUSTOM customType '=' '{' customBlobDescr '}' { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, $5); }
+ | customHead bytes ')' { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $1, $2); }
+ ;
+
+customDescrWithOwner : _CUSTOM '(' ownerType ')' customType { $$ = new CustomDescr($3, $5, NULL); }
+ | _CUSTOM '(' ownerType ')' customType '=' compQstring { $$ = new CustomDescr($3, $5, $7); }
+ | _CUSTOM '(' ownerType ')' customType '=' '{' customBlobDescr '}'
+ { $$ = new CustomDescr($3, $5, $8); }
+ | customHeadWithOwner bytes ')' { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $1, $2); }
+ ;
+
+customHead : _CUSTOM customType '=' '(' { $$ = $2; bParsingByteArray = TRUE; }
+ ;
+
+customHeadWithOwner : _CUSTOM '(' ownerType ')' customType '=' '('
+ { PASM->m_pCustomDescrList = NULL;
+ PASM->m_tkCurrentCVOwner = $3;
+ $$ = $5; bParsingByteArray = TRUE; }
+ ;
+
+customType : methodRef { $$ = $1; }
+ ;
+
+ownerType : typeSpec { $$ = $1; }
+ | memberRef { $$ = $1; }
+ ;
+
+/* Verbal description of custom attribute initialization blob */
+customBlobDescr : customBlobArgs customBlobNVPairs { $$ = $1;
+ $$->appendInt16(nCustomBlobNVPairs);
+ $$->append($2);
+ nCustomBlobNVPairs = 0; }
+ ;
+
+customBlobArgs : /* EMPTY */ { $$ = new BinStr(); $$->appendInt16(VAL16(0x0001)); }
+ | customBlobArgs serInit { $$ = $1;
+ $$->appendFrom($2, (*($2->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); }
+ | customBlobArgs compControl { $$ = $1; }
+ ;
+
+customBlobNVPairs : /* EMPTY */ { $$ = new BinStr(); }
+ | customBlobNVPairs fieldOrProp serializType dottedName '=' serInit
+ { $$ = $1; $$->appendInt8($2);
+ $$->append($3);
+ AppendStringWithLength($$,$4);
+ $$->appendFrom($6, (*($6->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1);
+ nCustomBlobNVPairs++; }
+ | customBlobNVPairs compControl { $$ = $1; }
+ ;
+
+fieldOrProp : FIELD_ { $$ = SERIALIZATION_TYPE_FIELD; }
+ | PROPERTY_ { $$ = SERIALIZATION_TYPE_PROPERTY; }
+ ;
+
+customAttrDecl : customDescr { if($1->tkOwner && !$1->tkInterfacePair)
+ PASM->DefineCV($1);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH($1); }
+ | customDescrWithOwner { PASM->DefineCV($1); }
+ | TYPEDEF_CA { CustomDescr* pNew = new CustomDescr($1->m_pCA);
+ if(pNew->tkOwner == 0) pNew->tkOwner = PASM->m_tkCurrentCVOwner;
+ if(pNew->tkOwner)
+ PASM->DefineCV(pNew);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(pNew); }
+ ;
+
+serializType : simpleType { $$ = $1; }
+ | TYPE_ { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); }
+ | OBJECT_ { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TAGGED_OBJECT); }
+ | ENUM_ CLASS_ SQSTRING { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength($$,$3); }
+ | ENUM_ className { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength($$,PASM->ReflectionNotation($2)); }
+ | serializType '[' ']' { $$ = $1; $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ ;
+
+
+/* Module declaration */
+moduleHead : _MODULE { PASMM->SetModuleName(NULL); PASM->m_tkCurrentCVOwner=1; }
+ | _MODULE dottedName { PASMM->SetModuleName($2); PASM->m_tkCurrentCVOwner=1; }
+ | _MODULE EXTERN_ dottedName { BinStr* pbs = new BinStr();
+ unsigned L = (unsigned)strlen($3);
+ memcpy((char*)(pbs->getBuff(L)),$3,L);
+ PASM->EmitImport(pbs); delete pbs;}
+ ;
+
+/* VTable Fixup table declaration */
+vtfixupDecl : _VTFIXUP '[' int32 ']' vtfixupAttr AT_ id { /*PASM->SetDataSection(); PASM->EmitDataLabel($7);*/
+ PASM->m_VTFList.PUSH(new VTFEntry((USHORT)$3, (USHORT)$5, $7)); }
+ ;
+
+vtfixupAttr : /* EMPTY */ { $$ = 0; }
+ | vtfixupAttr INT32_ { $$ = $1 | COR_VTABLE_32BIT; }
+ | vtfixupAttr INT64_ { $$ = $1 | COR_VTABLE_64BIT; }
+ | vtfixupAttr FROMUNMANAGED_ { $$ = $1 | COR_VTABLE_FROM_UNMANAGED; }
+ | vtfixupAttr CALLMOSTDERIVED_ { $$ = $1 | COR_VTABLE_CALL_MOST_DERIVED; }
+ | vtfixupAttr RETAINAPPDOMAIN_ { $$ = $1 | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN; }
+ ;
+
+vtableDecl : vtableHead bytes ')' /* deprecated */ { PASM->m_pVTable = $2; }
+ ;
+
+vtableHead : _VTABLE '=' '(' /* deprecated */ { bParsingByteArray = TRUE; }
+ ;
+
+/* Namespace and class declaration */
+nameSpaceHead : _NAMESPACE dottedName { PASM->StartNameSpace($2); }
+ ;
+
+_class : _CLASS { newclass = TRUE; }
+ ;
+
+classHeadBegin : _class classAttr dottedName typarsClause { if($4) FixupConstraints();
+ PASM->StartClass($3, $2, $4);
+ TyParFixupList.RESET(false);
+ newclass = FALSE;
+ }
+ ;
+classHead : classHeadBegin extendsClause implClause { PASM->AddClass(); }
+ ;
+
+classAttr : /* EMPTY */ { $$ = (CorRegTypeAttr) 0; }
+ | classAttr PUBLIC_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdPublic); }
+ | classAttr PRIVATE_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNotPublic); }
+ | classAttr VALUE_ { $$ = (CorRegTypeAttr) ($1 | 0x80000000 | tdSealed); }
+ | classAttr ENUM_ { $$ = (CorRegTypeAttr) ($1 | 0x40000000); }
+ | classAttr INTERFACE_ { $$ = (CorRegTypeAttr) ($1 | tdInterface | tdAbstract); }
+ | classAttr SEALED_ { $$ = (CorRegTypeAttr) ($1 | tdSealed); }
+ | classAttr ABSTRACT_ { $$ = (CorRegTypeAttr) ($1 | tdAbstract); }
+ | classAttr AUTO_ { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdAutoLayout); }
+ | classAttr SEQUENTIAL_ { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdSequentialLayout); }
+ | classAttr EXPLICIT_ { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdExplicitLayout); }
+ | classAttr ANSI_ { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdAnsiClass); }
+ | classAttr UNICODE_ { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdUnicodeClass); }
+ | classAttr AUTOCHAR_ { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdAutoClass); }
+ | classAttr IMPORT_ { $$ = (CorRegTypeAttr) ($1 | tdImport); }
+ | classAttr SERIALIZABLE_ { $$ = (CorRegTypeAttr) ($1 | tdSerializable); }
+ | classAttr WINDOWSRUNTIME_ { $$ = (CorRegTypeAttr) ($1 | tdWindowsRuntime); }
+ | classAttr NESTED_ PUBLIC_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedPublic); }
+ | classAttr NESTED_ PRIVATE_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedPrivate); }
+ | classAttr NESTED_ FAMILY_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamily); }
+ | classAttr NESTED_ ASSEMBLY_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedAssembly); }
+ | classAttr NESTED_ FAMANDASSEM_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamANDAssem); }
+ | classAttr NESTED_ FAMORASSEM_ { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamORAssem); }
+ | classAttr BEFOREFIELDINIT_ { $$ = (CorRegTypeAttr) ($1 | tdBeforeFieldInit); }
+ | classAttr SPECIALNAME_ { $$ = (CorRegTypeAttr) ($1 | tdSpecialName); }
+ | classAttr RTSPECIALNAME_ { $$ = (CorRegTypeAttr) ($1); }
+ | classAttr FLAGS_ '(' int32 ')' { $$ = (CorRegTypeAttr) ($4); }
+ ;
+
+extendsClause : /* EMPTY */
+ | EXTENDS_ typeSpec { PASM->m_crExtends = $2; }
+ ;
+
+implClause : /* EMPTY */
+ | IMPLEMENTS_ implList
+ ;
+
+classDecls : /* EMPTY */
+ | classDecls classDecl
+ ;
+
+implList : implList ',' typeSpec { PASM->AddToImplList($3); }
+ | typeSpec { PASM->AddToImplList($1); }
+ ;
+
+/* Generic type parameters declaration */
+typeList : /* EMPTY */ { $$ = new BinStr(); }
+ | typeListNotEmpty { $$ = $1; }
+ ;
+
+typeListNotEmpty : typeSpec { $$ = new BinStr(); $$->appendInt32($1); }
+ | typeListNotEmpty ',' typeSpec { $$ = $1; $$->appendInt32($3); }
+ ;
+
+typarsClause : /* EMPTY */ { $$ = NULL; PASM->m_TyParList = NULL;}
+ | '<' typars '>' { $$ = $2; PASM->m_TyParList = $2;}
+ ;
+
+typarAttrib : '+' { $$ = gpCovariant; }
+ | '-' { $$ = gpContravariant; }
+ | CLASS_ { $$ = gpReferenceTypeConstraint; }
+ | VALUETYPE_ { $$ = gpNotNullableValueTypeConstraint; }
+ | _CTOR { $$ = gpDefaultConstructorConstraint; }
+ ;
+
+typarAttribs : /* EMPTY */ { $$ = 0; }
+ | typarAttrib typarAttribs { $$ = $1 | $2; }
+ ;
+
+typars : typarAttribs tyBound dottedName typarsRest {$$ = new TyParList($1, $2, $3, $4);}
+ | typarAttribs dottedName typarsRest {$$ = new TyParList($1, NULL, $2, $3);}
+ ;
+
+typarsRest : /* EMPTY */ { $$ = NULL; }
+ | ',' typars { $$ = $2; }
+ ;
+
+tyBound : '(' typeList ')' { $$ = $2; }
+ ;
+
+genArity : /* EMPTY */ { $$= 0; }
+ | genArityNotEmpty { $$ = $1; }
+ ;
+
+genArityNotEmpty : '<' '[' int32 ']' '>' { $$ = $3; }
+ ;
+
+/* Class body declarations */
+classDecl : methodHead methodDecls '}' { if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); }
+ | classHead '{' classDecls '}' { PASM->EndClass(); }
+ | eventHead '{' eventDecls '}' { PASM->EndEvent(); }
+ | propHead '{' propDecls '}' { PASM->EndProp(); }
+ | fieldDecl
+ | dataDecl
+ | secDecl
+ | extSourceSpec
+ | customAttrDecl
+ | _SIZE int32 { PASM->m_pCurClass->m_ulSize = $2; }
+ | _PACK int32 { PASM->m_pCurClass->m_ulPack = $2; }
+ | exportHead '{' exptypeDecls '}' { PASMM->EndComType(); }
+ | _OVERRIDE typeSpec DCOLON methodName WITH_ callConv type typeSpec DCOLON methodName '(' sigArgs0 ')'
+ { BinStr *sig1 = parser->MakeSig($6, $7, $12);
+ BinStr *sig2 = new BinStr(); sig2->append(sig1);
+ PASM->AddMethodImpl($2,$4,sig1,$8,$10,sig2);
+ PASM->ResetArgNameList();
+ }
+ | _OVERRIDE METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')' WITH_ METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')'
+ { PASM->AddMethodImpl($5,$7,
+ ($8==0 ? parser->MakeSig($3,$4,$10) :
+ parser->MakeSig($3| IMAGE_CEE_CS_CALLCONV_GENERIC,$4,$10,$8)),
+ $16,$18,
+ ($19==0 ? parser->MakeSig($14,$15,$21) :
+ parser->MakeSig($14| IMAGE_CEE_CS_CALLCONV_GENERIC,$15,$21,$19)));
+ PASM->ResetArgNameList();
+ }
+ | languageDecl
+ | compControl
+ | _PARAM TYPE_ '[' int32 ']' { if(($4 > 0) && ($4 <= (int)PASM->m_pCurClass->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[$4-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ }
+ | _PARAM TYPE_ dottedName { int n = PASM->m_pCurClass->FindTyPar($3);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",$3);
+ }
+ | _PARAM CONSTRAINT_ '[' int32 ']' ',' typeSpec { PASM->AddGenericParamConstraint($4, 0, $7); }
+ | _PARAM CONSTRAINT_ dottedName ',' typeSpec { PASM->AddGenericParamConstraint(0, $3, $5); }
+ | _INTERFACEIMPL TYPE_ typeSpec customDescr { $4->tkInterfacePair = $3;
+ if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH($4);
+ }
+ ;
+
+/* Field declaration */
+fieldDecl : _FIELD repeatOpt fieldAttr type dottedName atOpt initOpt
+ { $4->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ PASM->AddField($5, $4, $3, $6, $7, $2); }
+ ;
+
+fieldAttr : /* EMPTY */ { $$ = (CorFieldAttr) 0; }
+ | fieldAttr STATIC_ { $$ = (CorFieldAttr) ($1 | fdStatic); }
+ | fieldAttr PUBLIC_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPublic); }
+ | fieldAttr PRIVATE_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPrivate); }
+ | fieldAttr FAMILY_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamily); }
+ | fieldAttr INITONLY_ { $$ = (CorFieldAttr) ($1 | fdInitOnly); }
+ | fieldAttr RTSPECIALNAME_ { $$ = $1; } /*{ $$ = (CorFieldAttr) ($1 | fdRTSpecialName); }*/
+ | fieldAttr SPECIALNAME_ { $$ = (CorFieldAttr) ($1 | fdSpecialName); }
+ /* <STRIP>commented out because PInvoke for fields is not supported by EE
+ | fieldAttr PINVOKEIMPL_ '(' compQstring AS_ compQstring pinvAttr ')'
+ { $$ = (CorFieldAttr) ($1 | fdPinvokeImpl);
+ PASM->SetPinvoke($4,0,$6,$7); }
+ | fieldAttr PINVOKEIMPL_ '(' compQstring pinvAttr ')'
+ { $$ = (CorFieldAttr) ($1 | fdPinvokeImpl);
+ PASM->SetPinvoke($4,0,NULL,$5); }
+ | fieldAttr PINVOKEIMPL_ '(' pinvAttr ')'
+ { PASM->SetPinvoke(new BinStr(),0,NULL,$4);
+ $$ = (CorFieldAttr) ($1 | fdPinvokeImpl); }
+ </STRIP>*/
+ | fieldAttr MARSHAL_ '(' marshalBlob ')'
+ { PASM->m_pMarshal = $4; }
+ | fieldAttr ASSEMBLY_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdAssembly); }
+ | fieldAttr FAMANDASSEM_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamANDAssem); }
+ | fieldAttr FAMORASSEM_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamORAssem); }
+ | fieldAttr PRIVATESCOPE_ { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPrivateScope); }
+ | fieldAttr LITERAL_ { $$ = (CorFieldAttr) ($1 | fdLiteral); }
+ | fieldAttr NOTSERIALIZED_ { $$ = (CorFieldAttr) ($1 | fdNotSerialized); }
+ | fieldAttr FLAGS_ '(' int32 ')' { $$ = (CorFieldAttr) ($4); }
+ ;
+
+atOpt : /* EMPTY */ { $$ = 0; }
+ | AT_ id { $$ = $2; }
+ ;
+
+initOpt : /* EMPTY */ { $$ = NULL; }
+ | '=' fieldInit { $$ = $2; }
+ ;
+
+repeatOpt : /* EMPTY */ { $$ = 0xFFFFFFFF; }
+ | '[' int32 ']' { $$ = $2; }
+ ;
+
+/* Method referencing */
+methodRef : callConv type typeSpec DCOLON methodName tyArgs0 '(' sigArgs0 ')'
+ { PASM->ResetArgNameList();
+ if ($6 == NULL)
+ {
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ $$ = PASM->MakeMemberRef($3, $5, parser->MakeSig($1|iCallConv, $2, $8));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef($3, $5,
+ parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $8, corCountArgs($6)));
+ $$ = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, $6));
+ }
+ }
+ | callConv type typeSpec DCOLON methodName genArityNotEmpty '(' sigArgs0 ')'
+ { PASM->ResetArgNameList();
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ $$ = PASM->MakeMemberRef($3, $5,
+ parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $8, $6));
+ }
+ | callConv type methodName tyArgs0 '(' sigArgs0 ')'
+ { PASM->ResetArgNameList();
+ if ($4 == NULL)
+ {
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ $$ = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1|iCallConv, $2, $6));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $6, corCountArgs($4)));
+ $$ = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, $4));
+ }
+ }
+ | callConv type methodName genArityNotEmpty '(' sigArgs0 ')'
+ { PASM->ResetArgNameList();
+ if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ $$ = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $6, $4));
+ }
+ | mdtoken { $$ = $1; }
+ | TYPEDEF_M { $$ = $1->m_tkTypeSpec; }
+ | TYPEDEF_MR { $$ = $1->m_tkTypeSpec; }
+ ;
+
+callConv : INSTANCE_ callConv { $$ = ($2 | IMAGE_CEE_CS_CALLCONV_HASTHIS); }
+ | EXPLICIT_ callConv { $$ = ($2 | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS); }
+ | callKind { $$ = $1; }
+ | CALLCONV_ '(' int32 ')' { $$ = $3; }
+ ;
+
+callKind : /* EMPTY */ { $$ = IMAGE_CEE_CS_CALLCONV_DEFAULT; }
+ | DEFAULT_ { $$ = IMAGE_CEE_CS_CALLCONV_DEFAULT; }
+ | VARARG_ { $$ = IMAGE_CEE_CS_CALLCONV_VARARG; }
+ | UNMANAGED_ CDECL_ { $$ = IMAGE_CEE_CS_CALLCONV_C; }
+ | UNMANAGED_ STDCALL_ { $$ = IMAGE_CEE_CS_CALLCONV_STDCALL; }
+ | UNMANAGED_ THISCALL_ { $$ = IMAGE_CEE_CS_CALLCONV_THISCALL; }
+ | UNMANAGED_ FASTCALL_ { $$ = IMAGE_CEE_CS_CALLCONV_FASTCALL; }
+ | UNMANAGED_ { $$ = IMAGE_CEE_CS_CALLCONV_UNMANAGED; }
+ ;
+
+mdtoken : MDTOKEN_ '(' int32 ')' { $$ = $3; }
+ ;
+
+memberRef : methodSpec methodRef { $$ = $2;
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ PASM->SetMemberRefFixup($2,iOpcodeLen); }
+ | FIELD_ type typeSpec DCOLON dottedName
+ { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ $$ = PASM->MakeMemberRef($3, $5, $2);
+ PASM->SetMemberRefFixup($$,iOpcodeLen); }
+ | FIELD_ type dottedName
+ { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ $$ = PASM->MakeMemberRef(NULL, $3, $2);
+ PASM->SetMemberRefFixup($$,iOpcodeLen); }
+ | FIELD_ TYPEDEF_F { $$ = $2->m_tkTypeSpec;
+ PASM->SetMemberRefFixup($$,iOpcodeLen); }
+ | FIELD_ TYPEDEF_MR { $$ = $2->m_tkTypeSpec;
+ PASM->SetMemberRefFixup($$,iOpcodeLen); }
+ | mdtoken { $$ = $1;
+ PASM->SetMemberRefFixup($$,iOpcodeLen); }
+ ;
+
+/* Event declaration */
+eventHead : _EVENT eventAttr typeSpec dottedName { PASM->ResetEvent($4, $3, $2); }
+ | _EVENT eventAttr dottedName { PASM->ResetEvent($3, mdTypeRefNil, $2); }
+ ;
+
+
+eventAttr : /* EMPTY */ { $$ = (CorEventAttr) 0; }
+ | eventAttr RTSPECIALNAME_ { $$ = $1; }/*{ $$ = (CorEventAttr) ($1 | evRTSpecialName); }*/
+ | eventAttr SPECIALNAME_ { $$ = (CorEventAttr) ($1 | evSpecialName); }
+ ;
+
+eventDecls : /* EMPTY */
+ | eventDecls eventDecl
+ ;
+
+eventDecl : _ADDON methodRef { PASM->SetEventMethod(0, $2); }
+ | _REMOVEON methodRef { PASM->SetEventMethod(1, $2); }
+ | _FIRE methodRef { PASM->SetEventMethod(2, $2); }
+ | _OTHER methodRef { PASM->SetEventMethod(3, $2); }
+ | extSourceSpec
+ | customAttrDecl
+ | languageDecl
+ | compControl
+ ;
+
+/* Property declaration */
+propHead : _PROPERTY propAttr callConv type dottedName '(' sigArgs0 ')' initOpt
+ { PASM->ResetProp($5,
+ parser->MakeSig((IMAGE_CEE_CS_CALLCONV_PROPERTY |
+ ($3 & IMAGE_CEE_CS_CALLCONV_HASTHIS)),$4,$7), $2, $9);}
+ ;
+
+propAttr : /* EMPTY */ { $$ = (CorPropertyAttr) 0; }
+ | propAttr RTSPECIALNAME_ { $$ = $1; }/*{ $$ = (CorPropertyAttr) ($1 | prRTSpecialName); }*/
+ | propAttr SPECIALNAME_ { $$ = (CorPropertyAttr) ($1 | prSpecialName); }
+ ;
+
+propDecls : /* EMPTY */
+ | propDecls propDecl
+ ;
+
+
+propDecl : _SET methodRef { PASM->SetPropMethod(0, $2); }
+ | _GET methodRef { PASM->SetPropMethod(1, $2); }
+ | _OTHER methodRef { PASM->SetPropMethod(2, $2); }
+ | customAttrDecl
+ | extSourceSpec
+ | languageDecl
+ | compControl
+ ;
+
+/* Method declaration */
+methodHeadPart1 : _METHOD { PASM->ResetForNextMethod();
+ uMethodBeginLine = PASM->m_ulCurLine;
+ uMethodBeginColumn=PASM->m_ulCurColumn;
+ }
+ ;
+
+marshalClause : /* EMPTY */ { $$ = NULL; }
+ | MARSHAL_ '(' marshalBlob ')' { $$ = $3; }
+ ;
+
+marshalBlob : nativeType { $$ = $1; }
+ | marshalBlobHead hexbytes '}' { $$ = $2; }
+ ;
+
+marshalBlobHead : '{' { bParsingByteArray = TRUE; }
+ ;
+
+methodHead : methodHeadPart1 methAttr callConv paramAttr type marshalClause methodName typarsClause'(' sigArgs0 ')' implAttr '{'
+ { BinStr* sig;
+ if ($8 == NULL) sig = parser->MakeSig($3, $5, $10);
+ else {
+ FixupTyPars($5);
+ sig = parser->MakeSig($3 | IMAGE_CEE_CS_CALLCONV_GENERIC, $5, $10, $8->Count());
+ FixupConstraints();
+ }
+ PASM->StartMethod($7, sig, $2, $6, $4, $8);
+ TyParFixupList.RESET(false);
+ PASM->SetImplAttr((USHORT)$12);
+ PASM->m_pCurMethod->m_ulLines[0] = uMethodBeginLine;
+ PASM->m_pCurMethod->m_ulColumns[0]=uMethodBeginColumn;
+ }
+ ;
+
+methAttr : /* EMPTY */ { $$ = (CorMethodAttr) 0; }
+ | methAttr STATIC_ { $$ = (CorMethodAttr) ($1 | mdStatic); }
+ | methAttr PUBLIC_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPublic); }
+ | methAttr PRIVATE_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPrivate); }
+ | methAttr FAMILY_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamily); }
+ | methAttr FINAL_ { $$ = (CorMethodAttr) ($1 | mdFinal); }
+ | methAttr SPECIALNAME_ { $$ = (CorMethodAttr) ($1 | mdSpecialName); }
+ | methAttr VIRTUAL_ { $$ = (CorMethodAttr) ($1 | mdVirtual); }
+ | methAttr STRICT_ { $$ = (CorMethodAttr) ($1 | mdCheckAccessOnOverride); }
+ | methAttr ABSTRACT_ { $$ = (CorMethodAttr) ($1 | mdAbstract); }
+ | methAttr ASSEMBLY_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdAssem); }
+ | methAttr FAMANDASSEM_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamANDAssem); }
+ | methAttr FAMORASSEM_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamORAssem); }
+ | methAttr PRIVATESCOPE_ { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPrivateScope); }
+ | methAttr HIDEBYSIG_ { $$ = (CorMethodAttr) ($1 | mdHideBySig); }
+ | methAttr NEWSLOT_ { $$ = (CorMethodAttr) ($1 | mdNewSlot); }
+ | methAttr RTSPECIALNAME_ { $$ = $1; }/*{ $$ = (CorMethodAttr) ($1 | mdRTSpecialName); }*/
+ | methAttr UNMANAGEDEXP_ { $$ = (CorMethodAttr) ($1 | mdUnmanagedExport); }
+ | methAttr REQSECOBJ_ { $$ = (CorMethodAttr) ($1 | mdRequireSecObject); }
+ | methAttr FLAGS_ '(' int32 ')' { $$ = (CorMethodAttr) ($4); }
+ | methAttr PINVOKEIMPL_ '(' compQstring AS_ compQstring pinvAttr ')'
+ { PASM->SetPinvoke($4,0,$6,$7);
+ $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
+ | methAttr PINVOKEIMPL_ '(' compQstring pinvAttr ')'
+ { PASM->SetPinvoke($4,0,NULL,$5);
+ $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
+ | methAttr PINVOKEIMPL_ '(' pinvAttr ')'
+ { PASM->SetPinvoke(new BinStr(),0,NULL,$4);
+ $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
+ ;
+
+pinvAttr : /* EMPTY */ { $$ = (CorPinvokeMap) 0; }
+ | pinvAttr NOMANGLE_ { $$ = (CorPinvokeMap) ($1 | pmNoMangle); }
+ | pinvAttr ANSI_ { $$ = (CorPinvokeMap) ($1 | pmCharSetAnsi); }
+ | pinvAttr UNICODE_ { $$ = (CorPinvokeMap) ($1 | pmCharSetUnicode); }
+ | pinvAttr AUTOCHAR_ { $$ = (CorPinvokeMap) ($1 | pmCharSetAuto); }
+ | pinvAttr LASTERR_ { $$ = (CorPinvokeMap) ($1 | pmSupportsLastError); }
+ | pinvAttr WINAPI_ { $$ = (CorPinvokeMap) ($1 | pmCallConvWinapi); }
+ | pinvAttr CDECL_ { $$ = (CorPinvokeMap) ($1 | pmCallConvCdecl); }
+ | pinvAttr STDCALL_ { $$ = (CorPinvokeMap) ($1 | pmCallConvStdcall); }
+ | pinvAttr THISCALL_ { $$ = (CorPinvokeMap) ($1 | pmCallConvThiscall); }
+ | pinvAttr FASTCALL_ { $$ = (CorPinvokeMap) ($1 | pmCallConvFastcall); }
+ | pinvAttr BESTFIT_ ':' ON_ { $$ = (CorPinvokeMap) ($1 | pmBestFitEnabled); }
+ | pinvAttr BESTFIT_ ':' OFF_ { $$ = (CorPinvokeMap) ($1 | pmBestFitDisabled); }
+ | pinvAttr CHARMAPERROR_ ':' ON_ { $$ = (CorPinvokeMap) ($1 | pmThrowOnUnmappableCharEnabled); }
+ | pinvAttr CHARMAPERROR_ ':' OFF_ { $$ = (CorPinvokeMap) ($1 | pmThrowOnUnmappableCharDisabled); }
+ | pinvAttr FLAGS_ '(' int32 ')' { $$ = (CorPinvokeMap) ($4); }
+ ;
+
+methodName : _CTOR { $$ = newString(COR_CTOR_METHOD_NAME); }
+ | _CCTOR { $$ = newString(COR_CCTOR_METHOD_NAME); }
+ | dottedName { $$ = $1; }
+ ;
+
+paramAttr : /* EMPTY */ { $$ = 0; }
+ | paramAttr '[' IN_ ']' { $$ = $1 | pdIn; }
+ | paramAttr '[' OUT_ ']' { $$ = $1 | pdOut; }
+ | paramAttr '[' OPT_ ']' { $$ = $1 | pdOptional; }
+ | paramAttr '[' int32 ']' { $$ = $3 + 1; }
+ ;
+
+implAttr : /* EMPTY */ { $$ = (CorMethodImpl) (miIL | miManaged); }
+ | implAttr NATIVE_ { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miNative); }
+ | implAttr CIL_ { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miIL); }
+ | implAttr OPTIL_ { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miOPTIL); }
+ | implAttr MANAGED_ { $$ = (CorMethodImpl) (($1 & 0xFFFB) | miManaged); }
+ | implAttr UNMANAGED_ { $$ = (CorMethodImpl) (($1 & 0xFFFB) | miUnmanaged); }
+ | implAttr FORWARDREF_ { $$ = (CorMethodImpl) ($1 | miForwardRef); }
+ | implAttr PRESERVESIG_ { $$ = (CorMethodImpl) ($1 | miPreserveSig); }
+ | implAttr RUNTIME_ { $$ = (CorMethodImpl) ($1 | miRuntime); }
+ | implAttr INTERNALCALL_ { $$ = (CorMethodImpl) ($1 | miInternalCall); }
+ | implAttr SYNCHRONIZED_ { $$ = (CorMethodImpl) ($1 | miSynchronized); }
+ | implAttr NOINLINING_ { $$ = (CorMethodImpl) ($1 | miNoInlining); }
+ | implAttr AGGRESSIVEINLINING_ { $$ = (CorMethodImpl) ($1 | miAggressiveInlining); }
+ | implAttr NOOPTIMIZATION_ { $$ = (CorMethodImpl) ($1 | miNoOptimization); }
+ | implAttr AGGRESSIVEOPTIMIZATION_ { $$ = (CorMethodImpl) ($1 | miAggressiveOptimization); }
+ | implAttr FLAGS_ '(' int32 ')' { $$ = (CorMethodImpl) ($4); }
+ ;
+
+localsHead : _LOCALS { PASM->delArgNameList(PASM->m_firstArgName); PASM->m_firstArgName = NULL;PASM->m_lastArgName = NULL;
+ }
+ ;
+
+methodDecls : /* EMPTY */
+ | methodDecls methodDecl
+ ;
+
+methodDecl : _EMITBYTE int32 { PASM->EmitByte($2); }
+ | sehBlock { delete PASM->m_SEHD; PASM->m_SEHD = PASM->m_SEHDstack.POP(); }
+ | _MAXSTACK int32 { PASM->EmitMaxStack($2); }
+ | localsHead '(' sigArgs0 ')' { PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, $3));
+ }
+ | localsHead INIT_ '(' sigArgs0 ')' { PASM->EmitZeroInit();
+ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, $4));
+ }
+ | _ENTRYPOINT { PASM->EmitEntryPoint(); }
+ | _ZEROINIT { PASM->EmitZeroInit(); }
+ | dataDecl
+ | instr
+ | id ':' { PASM->AddLabel(PASM->m_CurPC,$1); /*PASM->EmitLabel($1);*/ }
+ | secDecl
+ | extSourceSpec
+ | languageDecl
+ | customAttrDecl
+ | compControl
+ | _EXPORT '[' int32 ']' { if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = $3;
+ PASM->m_pCurMethod->m_szExportAlias = NULL;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = $3 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ }
+ | _EXPORT '[' int32 ']' AS_ id { if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = $3;
+ PASM->m_pCurMethod->m_szExportAlias = $6;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = $3 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ }
+ | _VTENTRY int32 ':' int32 { PASM->m_pCurMethod->m_wVTEntry = (WORD)$2;
+ PASM->m_pCurMethod->m_wVTSlot = (WORD)$4; }
+ | _OVERRIDE typeSpec DCOLON methodName
+ { PASM->AddMethodImpl($2,$4,NULL,NULL,NULL,NULL); }
+
+ | _OVERRIDE METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')'
+ { PASM->AddMethodImpl($5,$7,
+ ($8==0 ? parser->MakeSig($3,$4,$10) :
+ parser->MakeSig($3| IMAGE_CEE_CS_CALLCONV_GENERIC,$4,$10,$8))
+ ,NULL,NULL,NULL);
+ PASM->ResetArgNameList();
+ }
+ | scopeBlock
+ | _PARAM TYPE_ '[' int32 ']' { if(($4 > 0) && ($4 <= (int)PASM->m_pCurMethod->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[$4-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ }
+ | _PARAM TYPE_ dottedName { int n = PASM->m_pCurMethod->FindTyPar($3);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",$3);
+ }
+ | _PARAM CONSTRAINT_ '[' int32 ']' ',' typeSpec { PASM->m_pCurMethod->AddGenericParamConstraint($4, 0, $7); }
+ | _PARAM CONSTRAINT_ dottedName ',' typeSpec { PASM->m_pCurMethod->AddGenericParamConstraint(0, $3, $5); }
+
+ | _PARAM '[' int32 ']' initOpt
+ { if( $3 ) {
+ ARG_NAME_LIST* pAN=PASM->findArg(PASM->m_pCurMethod->m_firstArgName, $3 - 1);
+ if(pAN)
+ {
+ PASM->m_pCustomDescrList = &(pAN->CustDList);
+ pAN->pValue = $5;
+ }
+ else
+ {
+ PASM->m_pCustomDescrList = NULL;
+ if($5) delete $5;
+ }
+ } else {
+ PASM->m_pCustomDescrList = &(PASM->m_pCurMethod->m_RetCustDList);
+ PASM->m_pCurMethod->m_pRetValue = $5;
+ }
+ PASM->m_tkCurrentCVOwner = 0;
+ }
+ ;
+
+scopeBlock : scopeOpen methodDecls '}' { PASM->m_pCurMethod->CloseScope(); }
+ ;
+
+scopeOpen : '{' { PASM->m_pCurMethod->OpenScope(); }
+ ;
+
+/* Structured exception handling directives */
+sehBlock : tryBlock sehClauses
+ ;
+
+sehClauses : sehClause sehClauses
+ | sehClause
+ ;
+
+tryBlock : tryHead scopeBlock { PASM->m_SEHD->tryTo = PASM->m_CurPC; }
+ | tryHead id TO_ id { PASM->SetTryLabels($2, $4); }
+ | tryHead int32 TO_ int32 { if(PASM->m_SEHD) {PASM->m_SEHD->tryFrom = $2;
+ PASM->m_SEHD->tryTo = $4;} }
+ ;
+
+tryHead : _TRY { PASM->NewSEHDescriptor();
+ PASM->m_SEHD->tryFrom = PASM->m_CurPC; }
+ ;
+
+
+sehClause : catchClause handlerBlock { PASM->EmitTry(); }
+ | filterClause handlerBlock { PASM->EmitTry(); }
+ | finallyClause handlerBlock { PASM->EmitTry(); }
+ | faultClause handlerBlock { PASM->EmitTry(); }
+ ;
+
+
+filterClause : filterHead scopeBlock { PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ | filterHead id { PASM->SetFilterLabel($2);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ | filterHead int32 { PASM->m_SEHD->sehFilter = $2;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ ;
+
+filterHead : FILTER_ { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FILTER;
+ PASM->m_SEHD->sehFilter = PASM->m_CurPC; }
+ ;
+
+catchClause : CATCH_ typeSpec { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_NONE;
+ PASM->SetCatchClass($2);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ ;
+
+finallyClause : FINALLY_ { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FINALLY;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ ;
+
+faultClause : FAULT_ { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FAULT;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
+ ;
+
+handlerBlock : scopeBlock { PASM->m_SEHD->sehHandlerTo = PASM->m_CurPC; }
+ | HANDLER_ id TO_ id { PASM->SetHandlerLabels($2, $4); }
+ | HANDLER_ int32 TO_ int32 { PASM->m_SEHD->sehHandler = $2;
+ PASM->m_SEHD->sehHandlerTo = $4; }
+ ;
+
+/* Data declaration */
+dataDecl : ddHead ddBody
+ ;
+
+ddHead : _DATA tls id '=' { PASM->EmitDataLabel($3); }
+ | _DATA tls
+ ;
+
+tls : /* EMPTY */ { PASM->SetDataSection(); }
+ | TLS_ { PASM->SetTLSSection(); }
+ | CIL_ { PASM->SetILSection(); }
+ ;
+
+ddBody : '{' ddItemList '}'
+ | ddItem
+ ;
+
+ddItemList : ddItem ',' ddItemList
+ | ddItem
+ ;
+
+ddItemCount : /* EMPTY */ { $$ = 1; }
+ | '[' int32 ']' { $$ = $2;
+ if($2 <= 0) { PASM->report->error("Illegal item count: %d\n",$2);
+ if(!PASM->OnErrGo) $$ = 1; }}
+ ;
+
+ddItem : CHAR_ '*' '(' compQstring ')' { PASM->EmitDataString($4); }
+ | '&' '(' id ')' { PASM->EmitDD($3); }
+ | bytearrayhead bytes ')' { PASM->EmitData($2->ptr(),$2->length()); }
+ | FLOAT32_ '(' float64 ')' ddItemCount
+ { float f = (float) (*$3); float* p = new (nothrow) float[$5];
+ if(p != NULL) {
+ for(int i=0; i < $5; i++) p[i] = f;
+ PASM->EmitData(p, sizeof(float)*$5); delete $3; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(float)*$5); }
+ | FLOAT64_ '(' float64 ')' ddItemCount
+ { double* p = new (nothrow) double[$5];
+ if(p != NULL) {
+ for(int i=0; i<$5; i++) p[i] = *($3);
+ PASM->EmitData(p, sizeof(double)*$5); delete $3; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(double)*$5); }
+ | INT64_ '(' int64 ')' ddItemCount
+ { __int64* p = new (nothrow) __int64[$5];
+ if(p != NULL) {
+ for(int i=0; i<$5; i++) p[i] = *($3);
+ PASM->EmitData(p, sizeof(__int64)*$5); delete $3; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int64)*$5); }
+ | INT32_ '(' int32 ')' ddItemCount
+ { __int32* p = new (nothrow) __int32[$5];
+ if(p != NULL) {
+ for(int i=0; i<$5; i++) p[i] = $3;
+ PASM->EmitData(p, sizeof(__int32)*$5); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int32)*$5); }
+ | INT16_ '(' int32 ')' ddItemCount
+ { __int16 i = (__int16) $3; FAIL_UNLESS(i == $3, ("Value %d too big\n", $3));
+ __int16* p = new (nothrow) __int16[$5];
+ if(p != NULL) {
+ for(int j=0; j<$5; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int16)*$5); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int16)*$5); }
+ | INT8_ '(' int32 ')' ddItemCount
+ { __int8 i = (__int8) $3; FAIL_UNLESS(i == $3, ("Value %d too big\n", $3));
+ __int8* p = new (nothrow) __int8[$5];
+ if(p != NULL) {
+ for(int j=0; j<$5; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int8)*$5); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int8)*$5); }
+ | FLOAT32_ ddItemCount { PASM->EmitData(NULL, sizeof(float)*$2); }
+ | FLOAT64_ ddItemCount { PASM->EmitData(NULL, sizeof(double)*$2); }
+ | INT64_ ddItemCount { PASM->EmitData(NULL, sizeof(__int64)*$2); }
+ | INT32_ ddItemCount { PASM->EmitData(NULL, sizeof(__int32)*$2); }
+ | INT16_ ddItemCount { PASM->EmitData(NULL, sizeof(__int16)*$2); }
+ | INT8_ ddItemCount { PASM->EmitData(NULL, sizeof(__int8)*$2); }
+ ;
+
+/* Default values declaration for fields, parameters and verbal form of CA blob description */
+fieldSerInit : FLOAT32_ '(' float64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4);
+ float f = (float)(*$3);
+ $$->appendInt32(*((__int32*)&f)); delete $3; }
+ | FLOAT64_ '(' float64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8);
+ $$->appendInt64((__int64 *)$3); delete $3; }
+ | FLOAT32_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4);
+ $$->appendInt32($3); }
+ | FLOAT64_ '(' int64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8);
+ $$->appendInt64((__int64 *)$3); delete $3; }
+ | INT64_ '(' int64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I8);
+ $$->appendInt64((__int64 *)$3); delete $3; }
+ | INT32_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I4);
+ $$->appendInt32($3); }
+ | INT16_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I2);
+ $$->appendInt16($3); }
+ | INT8_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I1);
+ $$->appendInt8($3); }
+ | UNSIGNED_ INT64_ '(' int64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8);
+ $$->appendInt64((__int64 *)$4); delete $4; }
+ | UNSIGNED_ INT32_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4);
+ $$->appendInt32($4); }
+ | UNSIGNED_ INT16_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2);
+ $$->appendInt16($4); }
+ | UNSIGNED_ INT8_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1);
+ $$->appendInt8($4); }
+ | UINT64_ '(' int64 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8);
+ $$->appendInt64((__int64 *)$3); delete $3; }
+ | UINT32_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4);
+ $$->appendInt32($3); }
+ | UINT16_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2);
+ $$->appendInt16($3); }
+ | UINT8_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1);
+ $$->appendInt8($3); }
+ | CHAR_ '(' int32 ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CHAR);
+ $$->appendInt16($3); }
+ | BOOL_ '(' truefalse ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_BOOLEAN);
+ $$->appendInt8($3);}
+ | bytearrayhead bytes ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING);
+ $$->append($2); delete $2;}
+ ;
+
+bytearrayhead : BYTEARRAY_ '(' { bParsingByteArray = TRUE; }
+ ;
+
+bytes : /* EMPTY */ { $$ = new BinStr(); }
+ | hexbytes { $$ = $1; }
+ ;
+
+hexbytes : HEXBYTE { __int8 i = (__int8) $1; $$ = new BinStr(); $$->appendInt8(i); }
+ | hexbytes HEXBYTE { __int8 i = (__int8) $2; $$ = $1; $$->appendInt8(i); }
+ ;
+
+/* Field/parameter initialization */
+fieldInit : fieldSerInit { $$ = $1; }
+ | compQstring { $$ = BinStrToUnicode($1,true); $$->insertInt8(ELEMENT_TYPE_STRING);}
+ | NULLREF_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CLASS);
+ $$->appendInt32(0); }
+ ;
+
+/* Values for verbal form of CA blob description */
+serInit : fieldSerInit { $$ = $1; }
+ | STRING_ '(' NULLREF_ ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); $$->appendInt8(0xFF); }
+ | STRING_ '(' SQSTRING ')' { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING);
+ AppendStringWithLength($$,$3); delete [] $3;}
+ | TYPE_ '(' CLASS_ SQSTRING ')' { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength($$,$4); delete [] $4;}
+ | TYPE_ '(' className ')' { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength($$,PASM->ReflectionNotation($3));}
+ | TYPE_ '(' NULLREF_ ')' { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); $$->appendInt8(0xFF); }
+ | OBJECT_ '(' serInit ')' { $$ = $3; $$->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);}
+ | FLOAT32_ '[' int32 ']' '(' f32seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_R4);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | FLOAT64_ '[' int32 ']' '(' f64seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_R8);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | INT64_ '[' int32 ']' '(' i64seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_I8);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | INT32_ '[' int32 ']' '(' i32seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_I4);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | INT16_ '[' int32 ']' '(' i16seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_I2);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | INT8_ '[' int32 ']' '(' i8seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_I1);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UINT64_ '[' int32 ']' '(' i64seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_U8);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UINT32_ '[' int32 ']' '(' i32seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_U4);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UINT16_ '[' int32 ']' '(' i16seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_U2);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UINT8_ '[' int32 ']' '(' i8seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_U1);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UNSIGNED_ INT64_ '[' int32 ']' '(' i64seq ')'
+ { $$ = $7; $$->insertInt32($4);
+ $$->insertInt8(ELEMENT_TYPE_U8);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UNSIGNED_ INT32_ '[' int32 ']' '(' i32seq ')'
+ { $$ = $7; $$->insertInt32($4);
+ $$->insertInt8(ELEMENT_TYPE_U4);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UNSIGNED_ INT16_ '[' int32 ']' '(' i16seq ')'
+ { $$ = $7; $$->insertInt32($4);
+ $$->insertInt8(ELEMENT_TYPE_U2);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | UNSIGNED_ INT8_ '[' int32 ']' '(' i8seq ')'
+ { $$ = $7; $$->insertInt32($4);
+ $$->insertInt8(ELEMENT_TYPE_U1);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | CHAR_ '[' int32 ']' '(' i16seq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_CHAR);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | BOOL_ '[' int32 ']' '(' boolSeq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_BOOLEAN);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | STRING_ '[' int32 ']' '(' sqstringSeq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(ELEMENT_TYPE_STRING);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | TYPE_ '[' int32 ']' '(' classSeq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(SERIALIZATION_TYPE_TYPE);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | OBJECT_ '[' int32 ']' '(' objSeq ')'
+ { $$ = $6; $$->insertInt32($3);
+ $$->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);
+ $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ ;
+
+
+f32seq : /* EMPTY */ { $$ = new BinStr(); }
+ | f32seq float64 { $$ = $1;
+ float f = (float) (*$2); $$->appendInt32(*((__int32*)&f)); delete $2; }
+ | f32seq int32 { $$ = $1;
+ $$->appendInt32($2); }
+ ;
+
+f64seq : /* EMPTY */ { $$ = new BinStr(); }
+ | f64seq float64 { $$ = $1;
+ $$->appendInt64((__int64 *)$2); delete $2; }
+ | f64seq int64 { $$ = $1;
+ $$->appendInt64((__int64 *)$2); delete $2; }
+ ;
+
+i64seq : /* EMPTY */ { $$ = new BinStr(); }
+ | i64seq int64 { $$ = $1;
+ $$->appendInt64((__int64 *)$2); delete $2; }
+ ;
+
+i32seq : /* EMPTY */ { $$ = new BinStr(); }
+ | i32seq int32 { $$ = $1; $$->appendInt32($2);}
+ ;
+
+i16seq : /* EMPTY */ { $$ = new BinStr(); }
+ | i16seq int32 { $$ = $1; $$->appendInt16($2);}
+ ;
+
+i8seq : /* EMPTY */ { $$ = new BinStr(); }
+ | i8seq int32 { $$ = $1; $$->appendInt8($2); }
+ ;
+
+boolSeq : /* EMPTY */ { $$ = new BinStr(); }
+ | boolSeq truefalse { $$ = $1;
+ $$->appendInt8($2);}
+ ;
+
+sqstringSeq : /* EMPTY */ { $$ = new BinStr(); }
+ | sqstringSeq NULLREF_ { $$ = $1; $$->appendInt8(0xFF); }
+ | sqstringSeq SQSTRING { $$ = $1;
+ AppendStringWithLength($$,$2); delete [] $2;}
+ ;
+
+classSeq : /* EMPTY */ { $$ = new BinStr(); }
+ | classSeq NULLREF_ { $$ = $1; $$->appendInt8(0xFF); }
+ | classSeq CLASS_ SQSTRING { $$ = $1;
+ AppendStringWithLength($$,$3); delete [] $3;}
+ | classSeq className { $$ = $1;
+ AppendStringWithLength($$,PASM->ReflectionNotation($2));}
+ ;
+
+objSeq : /* EMPTY */ { $$ = new BinStr(); }
+ | objSeq serInit { $$ = $1; $$->append($2); delete $2; }
+ ;
+
+/* IL instructions and associated definitions */
+methodSpec : METHOD_ { parser->m_ANSFirst.PUSH(PASM->m_firstArgName);
+ parser->m_ANSLast.PUSH(PASM->m_lastArgName);
+ PASM->m_firstArgName = NULL;
+ PASM->m_lastArgName = NULL; }
+ ;
+
+instr_none : INSTR_NONE { $$ = SetupInstr($1); }
+ ;
+
+instr_var : INSTR_VAR { $$ = SetupInstr($1); }
+ ;
+
+instr_i : INSTR_I { $$ = SetupInstr($1); }
+ ;
+
+instr_i8 : INSTR_I8 { $$ = SetupInstr($1); }
+ ;
+
+instr_r : INSTR_R { $$ = SetupInstr($1); }
+ ;
+
+instr_brtarget : INSTR_BRTARGET { $$ = SetupInstr($1); }
+ ;
+
+instr_method : INSTR_METHOD { $$ = SetupInstr($1);
+ if((!PASM->OnErrGo)&&
+ (($1 == CEE_NEWOBJ)||
+ ($1 == CEE_CALLVIRT)))
+ iCallConv = IMAGE_CEE_CS_CALLCONV_HASTHIS;
+ }
+ ;
+
+instr_field : INSTR_FIELD { $$ = SetupInstr($1); }
+ ;
+
+instr_type : INSTR_TYPE { $$ = SetupInstr($1); }
+ ;
+
+instr_string : INSTR_STRING { $$ = SetupInstr($1); }
+ ;
+
+instr_sig : INSTR_SIG { $$ = SetupInstr($1); }
+ ;
+
+instr_tok : INSTR_TOK { $$ = SetupInstr($1); iOpcodeLen = PASM->OpcodeLen($$); }
+ ;
+
+instr_switch : INSTR_SWITCH { $$ = SetupInstr($1); }
+ ;
+
+instr_r_head : instr_r '(' { $$ = $1; bParsingByteArray = TRUE; }
+ ;
+
+
+instr : instr_none { PASM->EmitOpcode($1); }
+ | instr_var int32 { PASM->EmitInstrVar($1, $2); }
+ | instr_var id { PASM->EmitInstrVarByName($1, $2); }
+ | instr_i int32 { PASM->EmitInstrI($1, $2); }
+ | instr_i8 int64 { PASM->EmitInstrI8($1, $2); }
+ | instr_r float64 { PASM->EmitInstrR($1, $2); delete ($2);}
+ | instr_r int64 { double f = (double) (*$2); PASM->EmitInstrR($1, &f); }
+ | instr_r_head bytes ')' { unsigned L = $2->length();
+ FAIL_UNLESS(L >= sizeof(float), ("%d hexbytes, must be at least %d\n",
+ L,sizeof(float)));
+ if(L < sizeof(float)) {YYERROR; }
+ else {
+ double f = (L >= sizeof(double)) ? *((double *)($2->ptr()))
+ : (double)(*(float *)($2->ptr()));
+ PASM->EmitInstrR($1,&f); }
+ delete $2; }
+ | instr_brtarget int32 { PASM->EmitInstrBrOffset($1, $2); }
+ | instr_brtarget id { PASM->EmitInstrBrTarget($1, $2); }
+ | instr_method methodRef
+ { PASM->SetMemberRefFixup($2,PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,$2);
+ PASM->m_tkCurrentCVOwner = $2;
+ PASM->m_pCustomDescrList = NULL;
+ iCallConv = 0;
+ }
+ | instr_field type typeSpec DCOLON dottedName
+ { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef($3, $5, $2);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_field type dottedName
+ { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef(mdTokenNil, $3, $2);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_field mdtoken { mdToken mr = $2;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_field TYPEDEF_F { mdToken mr = $2->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_field TYPEDEF_MR { mdToken mr = $2->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
+ PASM->EmitInstrI($1,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_type typeSpec { PASM->EmitInstrI($1, $2);
+ PASM->m_tkCurrentCVOwner = $2;
+ PASM->m_pCustomDescrList = NULL;
+ }
+ | instr_string compQstring { PASM->EmitInstrStringLiteral($1, $2,TRUE); }
+ | instr_string ANSI_ '(' compQstring ')'
+ { PASM->EmitInstrStringLiteral($1, $4,FALSE); }
+ | instr_string bytearrayhead bytes ')'
+ { PASM->EmitInstrStringLiteral($1, $3,FALSE,TRUE); }
+ | instr_sig callConv type '(' sigArgs0 ')'
+ { PASM->EmitInstrSig($1, parser->MakeSig($2, $3, $5));
+ PASM->ResetArgNameList();
+ }
+ | instr_tok ownerType /* ownerType ::= memberRef | typeSpec */
+ { PASM->EmitInstrI($1,$2);
+ PASM->m_tkCurrentCVOwner = $2;
+ PASM->m_pCustomDescrList = NULL;
+ iOpcodeLen = 0;
+ }
+ | instr_switch '(' labels ')' { PASM->EmitInstrSwitch($1, $3); }
+ ;
+
+labels : /* empty */ { $$ = 0; }
+ | id ',' labels { $$ = new Labels($1, $3, TRUE); }
+ | int32 ',' labels { $$ = new Labels((char *)(UINT_PTR)$1, $3, FALSE); }
+ | id { $$ = new Labels($1, NULL, TRUE); }
+ | int32 { $$ = new Labels((char *)(UINT_PTR)$1, NULL, FALSE); }
+ ;
+
+/* Signatures */
+tyArgs0 : /* EMPTY */ { $$ = NULL; }
+ | '<' tyArgs1 '>' { $$ = $2; }
+ ;
+
+tyArgs1 : /* EMPTY */ { $$ = NULL; }
+ | tyArgs2 { $$ = $1; }
+ ;
+
+tyArgs2 : type { $$ = $1; }
+ | tyArgs2 ',' type { $$ = $1; $$->append($3); delete $3; }
+ ;
+
+
+sigArgs0 : /* EMPTY */ { $$ = new BinStr(); }
+ | sigArgs1 { $$ = $1;}
+ ;
+
+sigArgs1 : sigArg { $$ = $1; }
+ | sigArgs1 ',' sigArg { $$ = $1; $$->append($3); delete $3; }
+ ;
+
+sigArg : ELIPSIS { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_SENTINEL); }
+ | paramAttr type marshalClause { $$ = new BinStr(); $$->append($2); PASM->addArgName(NULL, $2, $3, $1); }
+ | paramAttr type marshalClause id { $$ = new BinStr(); $$->append($2); PASM->addArgName($4, $2, $3, $1);}
+ ;
+
+/* Class referencing */
+className : '[' dottedName ']' slashedName { $$ = PASM->ResolveClassRef(PASM->GetAsmRef($2), $4, NULL); delete[] $2;}
+ | '[' mdtoken ']' slashedName { $$ = PASM->ResolveClassRef($2, $4, NULL); }
+ | '[' '*' ']' slashedName { $$ = PASM->ResolveClassRef(mdTokenNil, $4, NULL); }
+ | '[' _MODULE dottedName ']' slashedName { $$ = PASM->ResolveClassRef(PASM->GetModRef($3),$5, NULL); delete[] $3;}
+ | slashedName { $$ = PASM->ResolveClassRef(1,$1,NULL); }
+ | mdtoken { $$ = $1; }
+ | TYPEDEF_T { $$ = $1->m_tkTypeSpec; }
+ | _THIS { if(PASM->m_pCurClass != NULL) $$ = PASM->m_pCurClass->m_cl;
+ else { $$ = 0; PASM->report->error(".this outside class scope\n"); }
+ }
+ | _BASE { if(PASM->m_pCurClass != NULL) {
+ $$ = PASM->m_pCurClass->m_crExtends;
+ if(RidFromToken($$) == 0)
+ PASM->report->error(".base undefined\n");
+ } else { $$ = 0; PASM->report->error(".base outside class scope\n"); }
+ }
+ | _NESTER { if(PASM->m_pCurClass != NULL) {
+ if(PASM->m_pCurClass->m_pEncloser != NULL) $$ = PASM->m_pCurClass->m_pEncloser->m_cl;
+ else { $$ = 0; PASM->report->error(".nester undefined\n"); }
+ } else { $$ = 0; PASM->report->error(".nester outside class scope\n"); }
+ }
+ ;
+
+slashedName : dottedName { $$ = $1; }
+ | slashedName '/' dottedName { $$ = newStringWDel($1, NESTING_SEP, $3); }
+ ;
+
+typeSpec : className { $$ = $1;}
+ | '[' dottedName ']' { $$ = PASM->GetAsmRef($2); delete[] $2;}
+ | '[' _MODULE dottedName ']' { $$ = PASM->GetModRef($3); delete[] $3;}
+ | type { $$ = PASM->ResolveTypeSpec($1); }
+ ;
+
+/* Native types for marshaling signatures */
+nativeType : /* EMPTY */ { $$ = new BinStr(); }
+ | CUSTOM_ '(' compQstring ',' compQstring ',' compQstring ',' compQstring ')'
+ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt($$,$3->length()); $$->append($3);
+ corEmitInt($$,$5->length()); $$->append($5);
+ corEmitInt($$,$7->length()); $$->append($7);
+ corEmitInt($$,$9->length()); $$->append($9);
+ PASM->report->warn("Deprecated 4-string form of custom marshaler, first two strings ignored\n");}
+ | CUSTOM_ '(' compQstring ',' compQstring ')'
+ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt($$,0);
+ corEmitInt($$,0);
+ corEmitInt($$,$3->length()); $$->append($3);
+ corEmitInt($$,$5->length()); $$->append($5); }
+ | FIXED_ SYSSTRING_ '[' int32 ']' { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FIXEDSYSSTRING);
+ corEmitInt($$,$4); }
+ | FIXED_ ARRAY_ '[' int32 ']' nativeType
+ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FIXEDARRAY);
+ corEmitInt($$,$4); $$->append($6); }
+ | VARIANT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VARIANT);
+ PASM->report->warn("Deprecated native type 'variant'\n"); }
+ | CURRENCY_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CURRENCY); }
+ | SYSCHAR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SYSCHAR);
+ PASM->report->warn("Deprecated native type 'syschar'\n"); }
+ | VOID_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VOID);
+ PASM->report->warn("Deprecated native type 'void'\n"); }
+ | BOOL_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BOOLEAN); }
+ | INT8_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I1); }
+ | INT16_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I2); }
+ | INT32_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I4); }
+ | INT64_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I8); }
+ | FLOAT32_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_R4); }
+ | FLOAT64_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_R8); }
+ | ERROR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ERROR); }
+ | UNSIGNED_ INT8_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U1); }
+ | UNSIGNED_ INT16_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U2); }
+ | UNSIGNED_ INT32_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U4); }
+ | UNSIGNED_ INT64_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U8); }
+ | UINT8_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U1); }
+ | UINT16_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U2); }
+ | UINT32_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U4); }
+ | UINT64_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U8); }
+ | nativeType '*' { $$ = $1; $$->insertInt8(NATIVE_TYPE_PTR);
+ PASM->report->warn("Deprecated native type '*'\n"); }
+ | nativeType '[' ']' { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX);
+ $$->insertInt8(NATIVE_TYPE_ARRAY); }
+ | nativeType '[' int32 ']' { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX);
+ $$->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt($$,0);
+ corEmitInt($$,$3);
+ corEmitInt($$,0); }
+ | nativeType '[' int32 '+' int32 ']' { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX);
+ $$->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt($$,$5);
+ corEmitInt($$,$3);
+ corEmitInt($$,ntaSizeParamIndexSpecified); }
+ | nativeType '[' '+' int32 ']' { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX);
+ $$->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt($$,$4); }
+ | DECIMAL_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_DECIMAL);
+ PASM->report->warn("Deprecated native type 'decimal'\n"); }
+ | DATE_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_DATE);
+ PASM->report->warn("Deprecated native type 'date'\n"); }
+ | BSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BSTR); }
+ | LPSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPSTR); }
+ | LPWSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPWSTR); }
+ | LPTSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPTSTR); }
+ | OBJECTREF_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_OBJECTREF);
+ PASM->report->warn("Deprecated native type 'objectref'\n"); }
+ | IUNKNOWN_ iidParamIndex { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_IUNKNOWN);
+ if($2 != -1) corEmitInt($$,$2); }
+ | IDISPATCH_ iidParamIndex { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_IDISPATCH);
+ if($2 != -1) corEmitInt($$,$2); }
+ | STRUCT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_STRUCT); }
+ | INTERFACE_ iidParamIndex { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_INTF);
+ if($2 != -1) corEmitInt($$,$2); }
+ | SAFEARRAY_ variantType { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt($$,$2);
+ corEmitInt($$,0);}
+ | SAFEARRAY_ variantType ',' compQstring { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt($$,$2);
+ corEmitInt($$,$4->length()); $$->append($4); }
+
+ | INT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_INT); }
+ | UNSIGNED_ INT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_UINT); }
+ | UINT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_UINT); }
+ | NESTED_ STRUCT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_NESTEDSTRUCT);
+ PASM->report->warn("Deprecated native type 'nested struct'\n"); }
+ | BYVALSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BYVALSTR); }
+ | ANSI_ BSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ANSIBSTR); }
+ | TBSTR_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_TBSTR); }
+ | VARIANT_ BOOL_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VARIANTBOOL); }
+ | METHOD_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FUNC); }
+ | AS_ ANY_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ASANY); }
+ | LPSTRUCT_ { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPSTRUCT); }
+ | TYPEDEF_TS { $$ = new BinStr(); $$->append($1->m_pbsTypeSpec); }
+ ;
+
+iidParamIndex : /* EMPTY */ { $$ = -1; }
+ | '(' IIDPARAM_ '=' int32 ')' { $$ = $4; }
+ ;
+
+variantType : /* EMPTY */ { $$ = VT_EMPTY; }
+ | NULL_ { $$ = VT_NULL; }
+ | VARIANT_ { $$ = VT_VARIANT; }
+ | CURRENCY_ { $$ = VT_CY; }
+ | VOID_ { $$ = VT_VOID; }
+ | BOOL_ { $$ = VT_BOOL; }
+ | INT8_ { $$ = VT_I1; }
+ | INT16_ { $$ = VT_I2; }
+ | INT32_ { $$ = VT_I4; }
+ | INT64_ { $$ = VT_I8; }
+ | FLOAT32_ { $$ = VT_R4; }
+ | FLOAT64_ { $$ = VT_R8; }
+ | UNSIGNED_ INT8_ { $$ = VT_UI1; }
+ | UNSIGNED_ INT16_ { $$ = VT_UI2; }
+ | UNSIGNED_ INT32_ { $$ = VT_UI4; }
+ | UNSIGNED_ INT64_ { $$ = VT_UI8; }
+ | UINT8_ { $$ = VT_UI1; }
+ | UINT16_ { $$ = VT_UI2; }
+ | UINT32_ { $$ = VT_UI4; }
+ | UINT64_ { $$ = VT_UI8; }
+ | '*' { $$ = VT_PTR; }
+ | variantType '[' ']' { $$ = $1 | VT_ARRAY; }
+ | variantType VECTOR_ { $$ = $1 | VT_VECTOR; }
+ | variantType '&' { $$ = $1 | VT_BYREF; }
+ | DECIMAL_ { $$ = VT_DECIMAL; }
+ | DATE_ { $$ = VT_DATE; }
+ | BSTR_ { $$ = VT_BSTR; }
+ | LPSTR_ { $$ = VT_LPSTR; }
+ | LPWSTR_ { $$ = VT_LPWSTR; }
+ | IUNKNOWN_ { $$ = VT_UNKNOWN; }
+ | IDISPATCH_ { $$ = VT_DISPATCH; }
+ | SAFEARRAY_ { $$ = VT_SAFEARRAY; }
+ | INT_ { $$ = VT_INT; }
+ | UNSIGNED_ INT_ { $$ = VT_UINT; }
+ | UINT_ { $$ = VT_UINT; }
+ | ERROR_ { $$ = VT_ERROR; }
+ | HRESULT_ { $$ = VT_HRESULT; }
+ | CARRAY_ { $$ = VT_CARRAY; }
+ | USERDEFINED_ { $$ = VT_USERDEFINED; }
+ | RECORD_ { $$ = VT_RECORD; }
+ | FILETIME_ { $$ = VT_FILETIME; }
+ | BLOB_ { $$ = VT_BLOB; }
+ | STREAM_ { $$ = VT_STREAM; }
+ | STORAGE_ { $$ = VT_STORAGE; }
+ | STREAMED_OBJECT_ { $$ = VT_STREAMED_OBJECT; }
+ | STORED_OBJECT_ { $$ = VT_STORED_OBJECT; }
+ | BLOB_OBJECT_ { $$ = VT_BLOB_OBJECT; }
+ | CF_ { $$ = VT_CF; }
+ | CLSID_ { $$ = VT_CLSID; }
+ ;
+
+/* Managed types for signatures */
+type : CLASS_ className { if($2 == PASM->m_tkSysString)
+ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); }
+ else if($2 == PASM->m_tkSysObject)
+ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_OBJECT); }
+ else
+ $$ = parser->MakeTypeClass(ELEMENT_TYPE_CLASS, $2); }
+ | OBJECT_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_OBJECT); }
+ | VALUE_ CLASS_ className { $$ = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, $3); }
+ | VALUETYPE_ className { $$ = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, $2); }
+ | type '[' ']' { $$ = $1; $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
+ | type '[' bounds1 ']' { $$ = parser->MakeTypeArray(ELEMENT_TYPE_ARRAY, $1, $3); }
+ | type '&' { $$ = $1; $$->insertInt8(ELEMENT_TYPE_BYREF); }
+ | type '*' { $$ = $1; $$->insertInt8(ELEMENT_TYPE_PTR); }
+ | type PINNED_ { $$ = $1; $$->insertInt8(ELEMENT_TYPE_PINNED); }
+ | type MODREQ_ '(' typeSpec ')' { $$ = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_REQD, $4);
+ $$->append($1); }
+ | type MODOPT_ '(' typeSpec ')' { $$ = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_OPT, $4);
+ $$->append($1); }
+ | methodSpec callConv type '*' '(' sigArgs0 ')'
+ { $$ = parser->MakeSig($2, $3, $6);
+ $$->insertInt8(ELEMENT_TYPE_FNPTR);
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ }
+ | type '<' tyArgs1 '>' { if($3 == NULL) $$ = $1;
+ else {
+ $$ = new BinStr();
+ $$->appendInt8(ELEMENT_TYPE_GENERICINST);
+ $$->append($1);
+ corEmitInt($$, corCountArgs($3));
+ $$->append($3); delete $1; delete $3; }}
+ | '!' '!' int32 { //if(PASM->m_pCurMethod) {
+ // if(($3 < 0)||((DWORD)$3 >= PASM->m_pCurMethod->m_NumTyPars))
+ // PASM->report->error("Invalid method type parameter '%d'\n",$3);
+ $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_MVAR); corEmitInt($$, $3);
+ //} else PASM->report->error("Method type parameter '%d' outside method scope\n",$3);
+ }
+ | '!' int32 { //if(PASM->m_pCurClass) {
+ // if(($2 < 0)||((DWORD)$2 >= PASM->m_pCurClass->m_NumTyPars))
+ // PASM->report->error("Invalid type parameter '%d'\n",$2);
+ $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_VAR); corEmitInt($$, $2);
+ //} else PASM->report->error("Type parameter '%d' outside class scope\n",$2);
+ }
+ | '!' '!' dottedName { int eltype = ELEMENT_TYPE_MVAR;
+ int n=-1;
+ if(PASM->m_pCurMethod) n = PASM->m_pCurMethod->FindTyPar($3);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf($3);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH($3);
+ eltype = ELEMENT_TYPE_MVARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid method type parameter '%s'\n",$3);
+ n = 0x1FFFFFFF; }
+ $$ = new BinStr(); $$->appendInt8(eltype); corEmitInt($$,n);
+ }
+ | '!' dottedName { int eltype = ELEMENT_TYPE_VAR;
+ int n=-1;
+ if(PASM->m_pCurClass && !newclass) n = PASM->m_pCurClass->FindTyPar($2);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf($2);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH($2);
+ eltype = ELEMENT_TYPE_VARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid type parameter '%s'\n",$2);
+ n = 0x1FFFFFFF; }
+ $$ = new BinStr(); $$->appendInt8(eltype); corEmitInt($$,n);
+ }
+ | TYPEDREF_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_TYPEDBYREF); }
+ | VOID_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_VOID); }
+ | NATIVE_ INT_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I); }
+ | NATIVE_ UNSIGNED_ INT_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U); }
+ | NATIVE_ UINT_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U); }
+ | simpleType { $$ = $1; }
+ | ELIPSIS type { $$ = $2; $$->insertInt8(ELEMENT_TYPE_SENTINEL); }
+ ;
+
+simpleType : CHAR_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CHAR); }
+ | STRING_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); }
+ | BOOL_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_BOOLEAN); }
+ | INT8_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I1); }
+ | INT16_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I2); }
+ | INT32_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I4); }
+ | INT64_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I8); }
+ | FLOAT32_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4); }
+ | FLOAT64_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8); }
+ | UNSIGNED_ INT8_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); }
+ | UNSIGNED_ INT16_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); }
+ | UNSIGNED_ INT32_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); }
+ | UNSIGNED_ INT64_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); }
+ | UINT8_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); }
+ | UINT16_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); }
+ | UINT32_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); }
+ | UINT64_ { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); }
+ | TYPEDEF_TS { $$ = new BinStr(); $$->append($1->m_pbsTypeSpec); }
+ ;
+
+bounds1 : bound { $$ = $1; }
+ | bounds1 ',' bound { $$ = $1; $1->append($3); delete $3; }
+ ;
+
+bound : /* EMPTY */ { $$ = new BinStr(); $$->appendInt32(0x7FFFFFFF); $$->appendInt32(0x7FFFFFFF); }
+ | ELIPSIS { $$ = new BinStr(); $$->appendInt32(0x7FFFFFFF); $$->appendInt32(0x7FFFFFFF); }
+ | int32 { $$ = new BinStr(); $$->appendInt32(0); $$->appendInt32($1); }
+ | int32 ELIPSIS int32 { FAIL_UNLESS($1 <= $3, ("lower bound %d must be <= upper bound %d\n", $1, $3));
+ if ($1 > $3) { YYERROR; };
+ $$ = new BinStr(); $$->appendInt32($1); $$->appendInt32($3-$1+1); }
+ | int32 ELIPSIS { $$ = new BinStr(); $$->appendInt32($1); $$->appendInt32(0x7FFFFFFF); }
+ ;
+
+/* Security declarations */
+secDecl : _PERMISSION secAction typeSpec '(' nameValPairs ')'
+ { PASM->AddPermissionDecl($2, $3, $5); }
+ | _PERMISSION secAction typeSpec '=' '{' customBlobDescr '}'
+ { PASM->AddPermissionDecl($2, $3, $6); }
+ | _PERMISSION secAction typeSpec { PASM->AddPermissionDecl($2, $3, (NVPair *)NULL); }
+ | psetHead bytes ')' { PASM->AddPermissionSetDecl($1, $2); }
+ | _PERMISSIONSET secAction compQstring
+ { PASM->AddPermissionSetDecl($2,BinStrToUnicode($3,true));}
+ | _PERMISSIONSET secAction '=' '{' secAttrSetBlob '}'
+ { BinStr* ret = new BinStr();
+ ret->insertInt8('.');
+ corEmitInt(ret, nSecAttrBlobs);
+ ret->append($5);
+ PASM->AddPermissionSetDecl($2,ret);
+ nSecAttrBlobs = 0; }
+ ;
+
+secAttrSetBlob : /* EMPTY */ { $$ = new BinStr(); nSecAttrBlobs = 0;}
+ | secAttrBlob { $$ = $1; nSecAttrBlobs = 1; }
+ | secAttrBlob ',' secAttrSetBlob { $$ = $1; $$->append($3); nSecAttrBlobs++; }
+ ;
+
+secAttrBlob : typeSpec '=' '{' customBlobNVPairs '}'
+ { $$ = PASM->EncodeSecAttr(PASM->ReflectionNotation($1),$4,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; }
+ | CLASS_ SQSTRING '=' '{' customBlobNVPairs '}'
+ { $$ = PASM->EncodeSecAttr($2,$5,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; }
+ ;
+
+psetHead : _PERMISSIONSET secAction '=' '(' { $$ = $2; bParsingByteArray = TRUE; }
+ | _PERMISSIONSET secAction BYTEARRAY_ '('
+ { $$ = $2; bParsingByteArray = TRUE; }
+ ;
+
+nameValPairs : nameValPair { $$ = $1; }
+ | nameValPair ',' nameValPairs { $$ = $1->Concat($3); }
+ ;
+
+nameValPair : compQstring '=' caValue { $1->appendInt8(0); $$ = new NVPair($1, $3); }
+ ;
+
+truefalse : TRUE_ { $$ = 1; }
+ | FALSE_ { $$ = 0; }
+ ;
+
+caValue : truefalse { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_BOOLEAN);
+ $$->appendInt8($1); }
+ | int32 { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_I4);
+ $$->appendInt32($1); }
+ | INT32_ '(' int32 ')' { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_I4);
+ $$->appendInt32($3); }
+ | compQstring { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_STRING);
+ $$->append($1); delete $1;
+ $$->appendInt8(0); }
+ | className '(' INT8_ ':' int32 ')' { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation($1);
+ strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ $$->appendInt8(1);
+ $$->appendInt32($5); }
+ | className '(' INT16_ ':' int32 ')' { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation($1);
+ strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ $$->appendInt8(2);
+ $$->appendInt32($5); }
+ | className '(' INT32_ ':' int32 ')' { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation($1);
+ strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ $$->appendInt8(4);
+ $$->appendInt32($5); }
+ | className '(' int32 ')' { $$ = new BinStr();
+ $$->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation($1);
+ strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ $$->appendInt8(4);
+ $$->appendInt32($3); }
+ ;
+
+secAction : REQUEST_ { $$ = dclRequest; }
+ | DEMAND_ { $$ = dclDemand; }
+ | ASSERT_ { $$ = dclAssert; }
+ | DENY_ { $$ = dclDeny; }
+ | PERMITONLY_ { $$ = dclPermitOnly; }
+ | LINKCHECK_ { $$ = dclLinktimeCheck; }
+ | INHERITCHECK_ { $$ = dclInheritanceCheck; }
+ | REQMIN_ { $$ = dclRequestMinimum; }
+ | REQOPT_ { $$ = dclRequestOptional; }
+ | REQREFUSE_ { $$ = dclRequestRefuse; }
+ | PREJITGRANT_ { $$ = dclPrejitGrant; }
+ | PREJITDENY_ { $$ = dclPrejitDenied; }
+ | NONCASDEMAND_ { $$ = dclNonCasDemand; }
+ | NONCASLINKDEMAND_ { $$ = dclNonCasLinkDemand; }
+ | NONCASINHERITANCE_ { $$ = dclNonCasInheritance; }
+ ;
+
+/* External source declarations */
+esHead : _LINE { PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = FALSE; }
+ | P_LINE { PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = TRUE; }
+ ;
+
+extSourceSpec : esHead int32 SQSTRING { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName($3);}
+ | esHead int32 { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1); }
+ | esHead int32 ':' int32 SQSTRING { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol=$4; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName($5);}
+ | esHead int32 ':' int32 { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol=$4; PENV->nExtColEnd = static_cast<unsigned>(-1);}
+ | esHead int32 ':' int32 ',' int32 SQSTRING
+ { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol=$4; PENV->nExtColEnd = $6;
+ PASM->SetSourceFileName($7);}
+ | esHead int32 ':' int32 ',' int32
+ { PENV->nExtLine = PENV->nExtLineEnd = $2;
+ PENV->nExtCol=$4; PENV->nExtColEnd = $6; }
+ | esHead int32 ',' int32 ':' int32 SQSTRING
+ { PENV->nExtLine = $2; PENV->nExtLineEnd = $4;
+ PENV->nExtCol=$6; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName($7);}
+ | esHead int32 ',' int32 ':' int32
+ { PENV->nExtLine = $2; PENV->nExtLineEnd = $4;
+ PENV->nExtCol=$6; PENV->nExtColEnd = static_cast<unsigned>(-1); }
+ | esHead int32 ',' int32 ':' int32 ',' int32 SQSTRING
+ { PENV->nExtLine = $2; PENV->nExtLineEnd = $4;
+ PENV->nExtCol=$6; PENV->nExtColEnd = $8;
+ PASM->SetSourceFileName($9);}
+ | esHead int32 ',' int32 ':' int32 ',' int32
+ { PENV->nExtLine = $2; PENV->nExtLineEnd = $4;
+ PENV->nExtCol=$6; PENV->nExtColEnd = $8; }
+ | esHead int32 QSTRING { PENV->nExtLine = PENV->nExtLineEnd = $2 - 1;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName($3);}
+ ;
+
+/* Manifest declarations */
+fileDecl : _FILE fileAttr dottedName fileEntry hashHead bytes ')' fileEntry
+ { PASMM->AddFile($3, $2|$4|$8, $6); }
+ | _FILE fileAttr dottedName fileEntry { PASMM->AddFile($3, $2|$4, NULL); }
+ ;
+
+fileAttr : /* EMPTY */ { $$ = (CorFileFlags) 0; }
+ | fileAttr NOMETADATA_ { $$ = (CorFileFlags) ($1 | ffContainsNoMetaData); }
+ ;
+
+fileEntry : /* EMPTY */ { $$ = (CorFileFlags) 0; }
+ | _ENTRYPOINT { $$ = (CorFileFlags) 0x80000000; }
+ ;
+
+hashHead : _HASH '=' '(' { bParsingByteArray = TRUE; }
+ ;
+
+assemblyHead : _ASSEMBLY asmAttr dottedName { PASMM->StartAssembly($3, NULL, (DWORD)$2, FALSE); }
+ ;
+
+asmAttr : /* EMPTY */ { $$ = (CorAssemblyFlags) 0; }
+ | asmAttr RETARGETABLE_ { $$ = (CorAssemblyFlags) ($1 | afRetargetable); }
+ | asmAttr WINDOWSRUNTIME_ { $$ = (CorAssemblyFlags) ($1 | afContentType_WindowsRuntime); }
+ | asmAttr NOPLATFORM_ { $$ = (CorAssemblyFlags) ($1 | afPA_NoPlatform); }
+ | asmAttr LEGACY_ LIBRARY_ { $$ = $1; }
+ | asmAttr CIL_ { SET_PA($$,$1,afPA_MSIL); }
+ | asmAttr X86_ { SET_PA($$,$1,afPA_x86); }
+ | asmAttr AMD64_ { SET_PA($$,$1,afPA_AMD64); }
+ | asmAttr ARM_ { SET_PA($$,$1,afPA_ARM); }
+ | asmAttr ARM64_ { SET_PA($$,$1,afPA_ARM64); }
+ ;
+
+assemblyDecls : /* EMPTY */
+ | assemblyDecls assemblyDecl
+ ;
+
+assemblyDecl : _HASH ALGORITHM_ int32 { PASMM->SetAssemblyHashAlg($3); }
+ | secDecl
+ | asmOrRefDecl
+ ;
+
+intOrWildcard : int32 { $$ = $1; }
+ | '*' { $$ = 0xFFFF; }
+ ;
+
+asmOrRefDecl : publicKeyHead bytes ')' { PASMM->SetAssemblyPublicKey($2); }
+ | _VER intOrWildcard ':' intOrWildcard ':' intOrWildcard ':' intOrWildcard
+ { PASMM->SetAssemblyVer((USHORT)$2, (USHORT)$4, (USHORT)$6, (USHORT)$8); }
+ | _LOCALE compQstring { $2->appendInt8(0); PASMM->SetAssemblyLocale($2,TRUE); }
+ | localeHead bytes ')' { PASMM->SetAssemblyLocale($2,FALSE); }
+ | customAttrDecl
+ | compControl
+ ;
+
+publicKeyHead : _PUBLICKEY '=' '(' { bParsingByteArray = TRUE; }
+ ;
+
+publicKeyTokenHead : _PUBLICKEYTOKEN '=' '(' { bParsingByteArray = TRUE; }
+ ;
+
+localeHead : _LOCALE '=' '(' { bParsingByteArray = TRUE; }
+ ;
+
+assemblyRefHead : _ASSEMBLY EXTERN_ asmAttr dottedName
+ { PASMM->StartAssembly($4, NULL, $3, TRUE); }
+ | _ASSEMBLY EXTERN_ asmAttr dottedName AS_ dottedName
+ { PASMM->StartAssembly($4, $6, $3, TRUE); }
+ ;
+
+assemblyRefDecls : /* EMPTY */
+ | assemblyRefDecls assemblyRefDecl
+ ;
+
+assemblyRefDecl : hashHead bytes ')' { PASMM->SetAssemblyHashBlob($2); }
+ | asmOrRefDecl
+ | publicKeyTokenHead bytes ')' { PASMM->SetAssemblyPublicKeyToken($2); }
+ | AUTO_ { PASMM->SetAssemblyAutodetect(); }
+ ;
+
+exptypeHead : _CLASS EXTERN_ exptAttr dottedName { PASMM->StartComType($4, $3);}
+ ;
+
+exportHead : _EXPORT exptAttr dottedName /* deprecated */ { PASMM->StartComType($3, $2); }
+ ;
+
+exptAttr : /* EMPTY */ { $$ = (CorTypeAttr) 0; }
+ | exptAttr PRIVATE_ { $$ = (CorTypeAttr) ($1 | tdNotPublic); }
+ | exptAttr PUBLIC_ { $$ = (CorTypeAttr) ($1 | tdPublic); }
+ | exptAttr FORWARDER_ { $$ = (CorTypeAttr) ($1 | tdForwarder); }
+ | exptAttr NESTED_ PUBLIC_ { $$ = (CorTypeAttr) ($1 | tdNestedPublic); }
+ | exptAttr NESTED_ PRIVATE_ { $$ = (CorTypeAttr) ($1 | tdNestedPrivate); }
+ | exptAttr NESTED_ FAMILY_ { $$ = (CorTypeAttr) ($1 | tdNestedFamily); }
+ | exptAttr NESTED_ ASSEMBLY_ { $$ = (CorTypeAttr) ($1 | tdNestedAssembly); }
+ | exptAttr NESTED_ FAMANDASSEM_ { $$ = (CorTypeAttr) ($1 | tdNestedFamANDAssem); }
+ | exptAttr NESTED_ FAMORASSEM_ { $$ = (CorTypeAttr) ($1 | tdNestedFamORAssem); }
+ ;
+
+exptypeDecls : /* EMPTY */
+ | exptypeDecls exptypeDecl
+ ;
+
+exptypeDecl : _FILE dottedName { PASMM->SetComTypeFile($2); }
+ | _CLASS EXTERN_ slashedName { PASMM->SetComTypeComType($3); }
+ | _ASSEMBLY EXTERN_ dottedName { PASMM->SetComTypeAsmRef($3); }
+ | MDTOKEN_ '(' int32 ')' { if(!PASMM->SetComTypeImplementationTok($3))
+ PASM->report->error("Invalid implementation of exported type\n"); }
+ | _CLASS int32 { if(!PASMM->SetComTypeClassTok($2))
+ PASM->report->error("Invalid TypeDefID of exported type\n"); }
+ | customAttrDecl
+ | compControl
+ ;
+
+manifestResHead : _MRESOURCE manresAttr dottedName { PASMM->StartManifestRes($3, $3, $2); }
+ | _MRESOURCE manresAttr dottedName AS_ dottedName
+ { PASMM->StartManifestRes($3, $5, $2); }
+ ;
+
+manresAttr : /* EMPTY */ { $$ = (CorManifestResourceFlags) 0; }
+ | manresAttr PUBLIC_ { $$ = (CorManifestResourceFlags) ($1 | mrPublic); }
+ | manresAttr PRIVATE_ { $$ = (CorManifestResourceFlags) ($1 | mrPrivate); }
+ ;
+
+manifestResDecls : /* EMPTY */
+ | manifestResDecls manifestResDecl
+ ;
+
+manifestResDecl : _FILE dottedName AT_ int32 { PASMM->SetManifestResFile($2, (ULONG)$4); }
+ | _ASSEMBLY EXTERN_ dottedName { PASMM->SetManifestResAsmRef($3); }
+ | customAttrDecl
+ | compControl
+ ;
+
+%%
+
+#include "grammar_after.cpp"
diff --git a/src/coreclr/ilasm/asmtemplates.h b/src/coreclr/ilasm/asmtemplates.h
new file mode 100644
index 00000000000..0393c71a4f2
--- /dev/null
+++ b/src/coreclr/ilasm/asmtemplates.h
@@ -0,0 +1,795 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef ASMTEMPLATES_H
+#define ASMTEMPLATES_H
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22008) // "Suppress PREfast warnings about integer overflow"
+#endif
+
+inline ULONG GrowBuffer(ULONG startingSize)
+{
+ int toAdd = startingSize >> 1;
+ if (toAdd < 8)
+ toAdd = 8;
+ if (toAdd > 2048)
+ toAdd = 2048;
+ return startingSize + toAdd;
+}
+
+/*****************************************************************************/
+/* LIFO (stack) and FIFO (queue) templates (must precede #include "method.h")*/
+template <class T>
+class LIST_EL
+{
+public:
+ T* m_Ptr;
+ LIST_EL <T> *m_Next;
+ LIST_EL(T *item) {m_Next = NULL; m_Ptr = item; };
+};
+
+template <class T>
+class LIFO
+{
+public:
+ inline LIFO() { m_pHead = NULL; };
+ inline ~LIFO() {T *val; while((val = POP()) != NULL) delete val; };
+ void PUSH(T *item)
+ {
+ m_pTemp = new LIST_EL <T>(item);
+ m_pTemp->m_Next = m_pHead;
+ m_pHead = m_pTemp;
+ };
+ T* POP()
+ {
+ T* ret = NULL;
+ if((m_pTemp = m_pHead) != NULL)
+ {
+ m_pHead = m_pHead->m_Next;
+ ret = m_pTemp->m_Ptr;
+ delete m_pTemp;
+ }
+ return ret;
+ };
+private:
+ LIST_EL <T> *m_pHead;
+ LIST_EL <T> *m_pTemp;
+};
+
+
+template <class T>
+class FIFO
+{
+public:
+ FIFO() { m_Arr = NULL; m_ulArrLen = 0; m_ulCount = 0; m_ulOffset = 0; };
+ ~FIFO() {
+ if(m_Arr) {
+ for(ULONG i=0; i < m_ulCount; i++) {
+ if(m_Arr[i+m_ulOffset]) delete m_Arr[i+m_ulOffset];
+ }
+ delete [] m_Arr;
+ }
+ };
+ void RESET(bool DeleteElements = true) {
+ if(m_Arr) {
+ for(ULONG i=0; i < m_ulCount; i++) {
+ if(DeleteElements) delete m_Arr[i+m_ulOffset];
+ m_Arr[i+m_ulOffset] = NULL;
+ }
+ m_ulCount = 0;
+ m_ulOffset= 0;
+ }
+ };
+ void PUSH(T *item)
+ {
+ if(item)
+ {
+ if(m_ulCount+m_ulOffset >= m_ulArrLen)
+ {
+ if(m_ulOffset)
+ {
+ memcpy(m_Arr,&m_Arr[m_ulOffset],m_ulCount*sizeof(T*));
+ m_ulOffset = 0;
+ }
+ else
+ {
+ m_ulArrLen = GrowBuffer(m_ulArrLen);
+ T** tmp = new T*[m_ulArrLen];
+ if(tmp)
+ {
+ if(m_Arr)
+ {
+ memcpy(tmp,m_Arr,m_ulCount*sizeof(T*));
+ delete [] m_Arr;
+ }
+ m_Arr = tmp;
+ }
+ else fprintf(stderr,"\nOut of memory!\n");
+ }
+ }
+ m_Arr[m_ulOffset+m_ulCount] = item;
+ m_ulCount++;
+ }
+ };
+ ULONG COUNT() { return m_ulCount; };
+ T* POP()
+ {
+ T* ret = NULL;
+ if(m_ulCount)
+ {
+ ret = m_Arr[m_ulOffset++];
+ m_ulCount--;
+ }
+ return ret;
+ };
+ T* PEEK(ULONG idx) { return (idx < m_ulCount) ? m_Arr[m_ulOffset+idx] : NULL; };
+private:
+ T** m_Arr;
+ ULONG m_ulCount;
+ ULONG m_ulOffset;
+ ULONG m_ulArrLen;
+};
+
+
+template <class T> struct Indx256
+{
+ void* table[256];
+ Indx256() { memset(table,0,sizeof(table)); };
+ ~Indx256()
+ {
+ ClearAll(true);
+ for(int i = 1; i < 256; i++) delete ((Indx256*)(table[i]));
+ };
+ T** IndexString(BYTE* psz, T* pObj)
+ {
+ if(*psz == 0)
+ {
+ table[0] = (void*)pObj;
+ return (T**)table;
+ }
+ else
+ {
+ Indx256* pInd = (Indx256*)(table[*psz]);
+ if(pInd == NULL)
+ {
+ pInd = new Indx256;
+ if(pInd)
+ table[*psz] = pInd;
+ else
+ {
+ _ASSERTE(!"Out of memory in Indx256::IndexString!");
+ fprintf(stderr,"\nOut of memory in Indx256::IndexString!\n");
+ return NULL;
+ }
+ }
+ return pInd->IndexString(psz+1,pObj);
+ }
+ };
+ T* FindString(BYTE* psz)
+ {
+ if(*psz > 0)
+ {
+ Indx256* pInd = (Indx256*)(table[*psz]);
+ return (pInd == NULL) ? NULL : pInd->FindString(psz+1);
+ }
+ return (T*)(table[0]); // if i==0
+ };
+
+ void ClearAll(bool DeleteObj)
+ {
+ if(DeleteObj) delete (T*)(table[0]);
+ table[0] = NULL;
+ for(unsigned i = 1; i < 256; i++)
+ {
+ if(table[i])
+ {
+ Indx256* pInd = (Indx256*)(table[i]);
+ pInd->ClearAll(DeleteObj);
+ //delete pInd;
+ //table[i] = NULL;
+ }
+ }
+ };
+};
+
+//
+// Template intended for named objects, that expose function char* NameOf()
+//
+template <class T>
+class FIFO_INDEXED
+{
+public:
+ FIFO_INDEXED() { m_Arr = NULL; m_ulArrLen = 0; m_ulCount = 0; m_ulOffset = 0; };
+ ~FIFO_INDEXED() {
+ if(m_Arr)
+ {
+ RESET(true);
+ delete [] m_Arr;
+ }
+ };
+ void RESET(bool DeleteElements = true) {
+ if(m_Arr) {
+ unsigned i;
+ if(DeleteElements)
+ {
+ for(i=m_ulOffset; i < m_ulOffset+m_ulCount; i++)
+ {
+ T** ppT = m_Arr[i];
+ delete *ppT;
+ }
+ }
+ for(i=m_ulOffset; i < m_ulOffset+m_ulCount; i++)
+ {
+ *m_Arr[i] = NULL;
+ }
+ memset(&m_Arr[m_ulOffset],0,m_ulCount*sizeof(void*));
+ m_ulCount = 0;
+ m_ulOffset= 0;
+ }
+ };
+ void PUSH(T *item)
+ {
+ if(item)
+ {
+ T** itemaddr = m_Index.IndexString((BYTE*)(item->NameOf()),item);
+ if(m_ulCount+m_ulOffset >= m_ulArrLen)
+ {
+ if(m_ulOffset)
+ {
+ memcpy(m_Arr,&m_Arr[m_ulOffset],m_ulCount*sizeof(T*));
+ m_ulOffset = 0;
+ }
+ else
+ {
+ m_ulArrLen = GrowBuffer(m_ulArrLen);
+ T*** tmp = new T**[m_ulArrLen];
+ if(tmp)
+ {
+ if(m_Arr)
+ {
+ memcpy(tmp,m_Arr,m_ulCount*sizeof(T**));
+ delete [] m_Arr;
+ }
+ m_Arr = tmp;
+ }
+ else fprintf(stderr,"\nOut of memory!\n");
+ }
+ }
+ m_Arr[m_ulOffset+m_ulCount] = itemaddr;
+ m_ulCount++;
+ }
+ };
+ ULONG COUNT() { return m_ulCount; };
+ T* POP()
+ {
+ T* ret = NULL;
+ if(m_ulCount)
+ {
+ ret = *(m_Arr[m_ulOffset]);
+ *m_Arr[m_ulOffset] = NULL;
+ m_ulOffset++;
+ m_ulCount--;
+ }
+ return ret;
+ };
+ T* PEEK(ULONG idx) { return (idx < m_ulCount) ? *(m_Arr[m_ulOffset+idx]) : NULL; };
+ T* FIND(T* item) { return m_Index.FindString((BYTE*)(item->NameOf())); };
+private:
+ T*** m_Arr;
+ ULONG m_ulCount;
+ ULONG m_ulOffset;
+ ULONG m_ulArrLen;
+ Indx256<T> m_Index;
+};
+
+template <class T>
+class SORTEDARRAY
+{
+public:
+ SORTEDARRAY() { m_Arr = NULL; m_ulArrLen = 0; m_ulCount = 0; m_ulOffset = 0; };
+ ~SORTEDARRAY() {
+ if(m_Arr) {
+ for(ULONG i=0; i < m_ulCount; i++) {
+ if(m_Arr[i+m_ulOffset]) delete m_Arr[i+m_ulOffset];
+ }
+ delete [] m_Arr;
+ }
+ };
+ void RESET(bool DeleteElements = true) {
+ if(m_Arr) {
+ if(DeleteElements)
+ {
+ for(ULONG i=0; i < m_ulCount; i++) {
+ delete m_Arr[i+m_ulOffset];
+ }
+ }
+ memset(m_Arr,0,m_ulArrLen*sizeof(T*));
+ m_ulCount = 0;
+ m_ulOffset= 0;
+ }
+ };
+ void PUSH(T *item)
+ {
+ if(item)
+ {
+ if(m_ulCount+m_ulOffset >= m_ulArrLen)
+ {
+ if(m_ulOffset)
+ {
+ memcpy(m_Arr,&m_Arr[m_ulOffset],m_ulCount*sizeof(T*));
+ m_ulOffset = 0;
+ }
+ else
+ {
+ m_ulArrLen = GrowBuffer(m_ulArrLen);
+ T** tmp = new T*[m_ulArrLen];
+ if(tmp)
+ {
+ if(m_Arr)
+ {
+ memcpy(tmp,m_Arr,m_ulCount*sizeof(T*));
+ delete [] m_Arr;
+ }
+ m_Arr = tmp;
+ }
+ else fprintf(stderr,"\nOut of memory!\n");
+ }
+ }
+ if(m_ulCount)
+ {
+ // find 1st arr.element > item
+ T** low = &m_Arr[m_ulOffset];
+ T** high = &m_Arr[m_ulOffset+m_ulCount-1];
+ T** mid;
+
+ if(item->ComparedTo(*high) > 0) mid = high+1;
+ else if(item->ComparedTo(*low) < 0) mid = low;
+ else for(;;)
+ {
+ mid = &low[(high - low) >> 1];
+
+ int cmp = item->ComparedTo(*mid);
+
+ if (mid == low)
+ {
+ if(cmp > 0) mid++;
+ break;
+ }
+
+ if (cmp > 0) low = mid;
+ else high = mid;
+ }
+
+ /////////////////////////////////////////////
+ memmove(mid+1,mid,(BYTE*)&m_Arr[m_ulOffset+m_ulCount]-(BYTE*)mid);
+ *mid = item;
+ }
+ else m_Arr[m_ulOffset+m_ulCount] = item;
+ m_ulCount++;
+ }
+ };
+ ULONG COUNT() { return m_ulCount; };
+ T* POP()
+ {
+ T* ret = NULL;
+ if(m_ulCount)
+ {
+ ret = m_Arr[m_ulOffset++];
+ m_ulCount--;
+ }
+ return ret;
+ };
+ T* PEEK(ULONG idx) { return (idx < m_ulCount) ? m_Arr[m_ulOffset+idx] : NULL; };
+ T* FIND(T* item)
+ {
+ if(m_ulCount)
+ {
+ T** low = &m_Arr[m_ulOffset];
+ T** high = &m_Arr[m_ulOffset+m_ulCount-1];
+ T** mid;
+ if(item->ComparedTo(*high) == 0) return(*high);
+ for(;;)
+ {
+ mid = &low[(high - low) >> 1];
+ int cmp = item->ComparedTo(*mid);
+ if (cmp == 0) return(*mid);
+ if (mid == low) break;
+ if (cmp > 0) low = mid;
+ else high = mid;
+ }
+ }
+ return NULL;
+ };
+ /*
+ T* FIND(U item)
+ {
+ if(m_ulCount)
+ {
+ T** low = &m_Arr[m_ulOffset];
+ T** high = &m_Arr[m_ulOffset+m_ulCount-1];
+ T** mid;
+ if((*high)->Compare(item) == 0) return(*high);
+ for(;;)
+ {
+ mid = &low[(high - low) >> 1];
+ int cmp = (*mid)->Compare(item);
+ if (cmp == 0) return(*mid);
+ if (mid == low) break;
+ if (cmp > 0) low = mid;
+ else high = mid;
+ }
+ }
+ return NULL;
+ };
+ */
+ BOOL DEL(T* item)
+ {
+ if(m_ulCount)
+ {
+ T** low = &m_Arr[m_ulOffset];
+ T** high = &m_Arr[m_ulOffset+m_ulCount-1];
+ T** mid;
+ if(item->ComparedTo(*high) == 0)
+ {
+ delete (*high);
+ m_ulCount--;
+ return TRUE;
+ }
+ for(;;)
+ {
+ mid = &low[(high - low) >> 1];
+ int cmp = item->ComparedTo(*mid);
+ if (cmp == 0)
+ {
+ delete (*mid);
+ memcpy(mid,mid+1,(BYTE*)&m_Arr[m_ulOffset+m_ulCount]-(BYTE*)mid-1);
+ m_ulCount--;
+ return TRUE;
+ }
+ if (mid == low) break;
+ if (cmp > 0) low = mid;
+ else high = mid;
+ }
+ }
+ return FALSE;
+ };
+private:
+ T** m_Arr;
+ ULONG m_ulCount;
+ ULONG m_ulOffset;
+ ULONG m_ulArrLen;
+};
+
+template <class T> struct RBNODE
+{
+private:
+ DWORD dwRed;
+public:
+ DWORD dwInUse;
+ T* tVal;
+ RBNODE<T>* pLeft;
+ RBNODE<T>* pRight;
+ RBNODE<T>* pParent;
+ RBNODE()
+ {
+ pLeft = pRight = pParent = NULL;
+ tVal = NULL;
+ dwRed = dwInUse = 0;
+ };
+ RBNODE(T* pVal, DWORD dwColor)
+ {
+ pLeft = pRight = pParent = NULL;
+ tVal = pVal;
+ dwRed = dwColor;
+ dwInUse = 0;
+ };
+ bool IsRed() { return (dwRed != 0); };
+ void SetRed() { dwRed = 1; };
+ void SetBlack() { dwRed = 0; };
+};
+
+#define BUCKETCOUNT 512
+
+template <class T> class RBNODEBUCKET
+{
+private:
+ RBNODEBUCKET<T>* pNext;
+ RBNODE<T> bucket[BUCKETCOUNT];
+ unsigned alloc_count;
+
+public:
+ RBNODEBUCKET()
+ {
+ alloc_count = 0;
+ pNext = NULL;
+ };
+
+ ~RBNODEBUCKET() { if(pNext) delete pNext; };
+
+ bool CanAlloc() { return (alloc_count < BUCKETCOUNT); };
+
+ RBNODE<T>* AllocNode()
+ {
+ RBNODE<T>* pRet;
+ for(unsigned i = 0; i < BUCKETCOUNT; i++)
+ {
+ if(bucket[i].dwInUse == 0)
+ {
+ alloc_count++;
+ pRet = &bucket[i];
+ memset(pRet, 0, sizeof(RBNODE<T>));
+ pRet->dwInUse = 1;
+ return pRet;
+ }
+ }
+ _ASSERTE(!"AllocNode returns NULL");
+ return NULL;
+ };
+
+ bool FreeNode(RBNODE<T>* ptr)
+ {
+ size_t idx = ((size_t)ptr - (size_t)bucket)/sizeof(RBNODE<T>);
+ if(idx < BUCKETCOUNT)
+ {
+ bucket[idx].dwInUse = 0;
+ alloc_count--;
+ return true;
+ }
+ return false;
+ };
+
+ RBNODEBUCKET<T>* Next() { return pNext; };
+
+ void Append(RBNODEBUCKET<T>* ptr) { pNext = ptr; };
+};
+
+template <class T> class RBNODEPOOL
+{
+private:
+ RBNODEBUCKET<T> base;
+
+public:
+ RBNODEPOOL()
+ {
+ memset(&base,0,sizeof(RBNODEBUCKET<T>));
+ };
+
+ RBNODE<T>* AllocNode()
+ {
+ RBNODEBUCKET<T>* pBucket = &base;
+ RBNODEBUCKET<T>* pLastBucket = &base;
+ do
+ {
+ if(pBucket->CanAlloc())
+ {
+ return pBucket->AllocNode();
+ }
+ pLastBucket = pBucket;
+ pBucket = pBucket->Next();
+ }
+ while (pBucket != NULL);
+ pLastBucket->Append(new RBNODEBUCKET<T>);
+ return pLastBucket->Next()->AllocNode();
+ };
+
+ void FreeNode(RBNODE<T>* ptr)
+ {
+ RBNODEBUCKET<T>* pBucket = &base;
+ do
+ {
+ if(pBucket->FreeNode(ptr))
+ break;
+ pBucket = pBucket->Next();
+ }
+ while (pBucket != NULL);
+ };
+};
+
+template <class T> class RBTREE
+{
+private:
+ RBNODE<T>* pRoot;
+ RBNODE<T>* pNil;
+ RBNODEPOOL<T> NodePool;
+ void RotateLeft(RBNODE<T>* pX)
+ {
+ RBNODE<T>* pY;
+
+ pY = pX->pRight;
+ pX->pRight = pY->pLeft;
+
+ if(pY->pLeft != pNil)
+ pY->pLeft->pParent = pX;
+
+ pY->pParent = pX->pParent;
+
+ if(pX == pX->pParent->pLeft)
+ pX->pParent->pLeft = pY;
+ else
+ pX->pParent->pRight = pY;
+
+ pY->pLeft = pX;
+ pX->pParent = pY;
+ };
+
+ void RotateRight(RBNODE<T>* pX)
+ {
+ RBNODE<T>* pY;
+
+ pY = pX->pLeft;
+ pX->pLeft = pY->pRight;
+
+ if(pY->pRight != pNil)
+ pY->pRight->pParent = pX;
+
+ pY->pParent = pX->pParent;
+
+ if(pX == pX->pParent->pLeft)
+ pX->pParent->pLeft = pY;
+ else
+ pX->pParent->pRight = pY;
+
+ pY->pRight = pX;
+ pX->pParent = pY;
+
+ };
+
+ void InsertNode(RBNODE<T>* pZ)
+ {
+ RBNODE<T>* pX;
+ RBNODE<T>* pY;
+
+ pZ->pLeft = pZ->pRight = pNil;
+ pY = pRoot;
+ pX = pRoot->pLeft;
+
+ if(pX != pY)
+ {
+ while(pX != pNil)
+ {
+ pY = pX;
+ if(pX->tVal->ComparedTo(pZ->tVal) > 0)
+ pX = pX->pLeft;
+ else
+ pX = pX->pRight;
+ }
+ }
+ pZ->pParent = pY;
+ if((pY == pRoot) || (pY->tVal->ComparedTo(pZ->tVal) > 0))
+ pY->pLeft = pZ;
+ else
+ pY->pRight = pZ;
+ };
+
+ void InitSpecNode(RBNODE<T>* pNode)
+ {
+ pNode->pLeft = pNode->pRight = pNode->pParent = pNode;
+ };
+
+ void DeleteNode(RBNODE<T>* pNode, bool DeletePayload = true)
+ {
+ if((pNode != pNil)&&(pNode != pRoot))
+ {
+ DeleteNode(pNode->pLeft, DeletePayload);
+ DeleteNode(pNode->pRight, DeletePayload);
+ if(DeletePayload)
+ delete pNode->tVal;
+ NodePool.FreeNode(pNode);
+ }
+ };
+
+public:
+ RBTREE()
+ {
+ pRoot = NodePool.AllocNode();
+ InitSpecNode(pRoot);
+
+ pNil = NodePool.AllocNode();
+ InitSpecNode(pNil);
+ };
+
+ ~RBTREE()
+ {
+ //RESET(false);
+ //NodePool.FreeNode(pRoot);
+ //NodePool.FreeNode(pNil);
+ };
+
+ void RESET(bool DeletePayload = true)
+ {
+ DeleteNode(pRoot->pLeft, DeletePayload);
+ InitSpecNode(pRoot);
+ InitSpecNode(pNil);
+ };
+
+ void PUSH(T* pT)
+ {
+ RBNODE<T>* pX;
+ RBNODE<T>* pY;
+ RBNODE<T>* pNewNode = NodePool.AllocNode();
+
+ pNewNode->tVal = pT;
+ pNewNode->SetRed();
+
+ InsertNode(pNewNode);
+
+ for(pX = pNewNode; pX->pParent->IsRed();)
+ {
+ if(pX->pParent == pX->pParent->pLeft)
+ {
+ pY = pX->pParent->pRight;
+ if(pY->IsRed())
+ {
+ pX->pParent->SetBlack();
+ pY->SetBlack();
+ pX->pParent->pParent->SetRed();
+ pX = pX->pParent->pParent;
+ }
+ else
+ {
+ if(pX == pX->pParent->pRight)
+ {
+ pX = pX->pParent;
+ RotateLeft(pX);
+ }
+ pX->pParent->SetBlack();
+ pX->pParent->pParent->SetRed();
+ RotateRight(pX->pParent->pParent);
+ }
+ }
+ else // if(pX->pParent == pX->pParent->pRight)
+ {
+ pY = pX->pParent->pParent->pLeft;
+ if(pY->IsRed())
+ {
+ pX->pParent->SetBlack();
+ pY->SetBlack();
+ pX->pParent->pParent->SetRed();
+ pX = pX->pParent->pParent;
+ }
+ else
+ {
+ if(pX == pX->pParent->pLeft)
+ {
+ pX = pX->pParent;
+ RotateRight(pX);
+ }
+ pX->pParent->SetBlack();
+ pX->pParent->pParent->SetRed();
+ RotateLeft(pX->pParent->pParent);
+ }
+ }// end if(pX->pParent == pX->pParent->pLeft) -- else
+ } // end for(pX = pNewNode; pX->pParent->IsRed();)
+ pRoot->pLeft->SetBlack();
+ };
+
+ T* FIND(T* pT)
+ {
+ RBNODE<T>* pX = pRoot->pLeft;
+ if((pX != pNil) && (pX != pRoot))
+ {
+ int cmp = pX->tVal->ComparedTo(pT);
+ while(cmp != 0)
+ {
+ if(cmp > 0)
+ pX = pX->pLeft;
+ else
+ pX = pX->pRight;
+ if(pX == pNil)
+ return NULL;
+ cmp = pX->tVal->ComparedTo(pT);
+ }
+ return pX->tVal;
+ }
+ return NULL;
+ };
+};
+
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+#endif //ASMTEMPLATES_H
+
diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp
new file mode 100644
index 00000000000..bfe765c5499
--- /dev/null
+++ b/src/coreclr/ilasm/assem.cpp
@@ -0,0 +1,1641 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// File: assem.cpp
+//
+
+//
+// COM+ IL assembler
+//
+#include "ilasmpch.h"
+
+#define INITGUID
+
+#define DECLARE_DATA
+
+#include "assembler.h"
+
+void indexKeywords(Indx* indx); // defined in asmparse.y
+
+unsigned int g_uCodePage = CP_ACP;
+unsigned int g_uConsoleCP = CP_ACP;
+
+char g_szSourceFileName[MAX_FILENAME_LENGTH*3];
+
+WCHAR wzUniBuf[dwUniBuf]; // Unicode conversion global buffer
+
+Assembler::Assembler()
+{
+ m_pDisp = NULL;
+ m_pEmitter = NULL;
+ m_pImporter = NULL;
+
+ m_fCPlusPlus = FALSE;
+ m_fWindowsCE = FALSE;
+ char* pszFQN = new char[16];
+ strcpy_s(pszFQN,16,"<Module>");
+ m_pModuleClass = new Class(pszFQN);
+ m_lstClass.PUSH(m_pModuleClass);
+ m_hshClass.PUSH(m_pModuleClass);
+ m_pModuleClass->m_cl = mdTokenNil;
+ m_pModuleClass->m_bIsMaster = FALSE;
+
+ m_fStdMapping = FALSE;
+ m_fDisplayTraceOutput= FALSE;
+ m_fENCMode = FALSE;
+ m_fTolerateDupMethods = FALSE;
+
+ m_pCurOutputPos = NULL;
+
+ m_CurPC = 0; // PC offset in method
+ m_pCurMethod = NULL;
+ m_pCurClass = NULL;
+ m_pCurEvent = NULL;
+ m_pCurProp = NULL;
+
+ m_wzMetadataVersion = NULL;
+ m_wMSVmajor = 0xFFFF;
+ m_wMSVminor = 0xFFFF;
+
+ m_wSSVersionMajor = 4;
+ m_wSSVersionMinor = 0;
+ m_fAppContainer = FALSE;
+ m_fHighEntropyVA = FALSE;
+
+ m_pCeeFileGen = NULL;
+ m_pCeeFile = 0;
+
+ m_pManifest = NULL;
+
+ m_pCustomDescrList = NULL;
+
+ m_pGlobalDataSection = NULL;
+ m_pILSection = NULL;
+ m_pTLSSection = NULL;
+
+ m_fDidCoInitialise = FALSE;
+
+ m_fDLL = FALSE;
+ m_fEntryPointPresent = FALSE;
+ m_fHaveFieldsWithRvas = FALSE;
+ m_fFoldCode = FALSE;
+ m_dwMethodsFolded = 0;
+
+ m_szScopeName[0] = 0;
+ m_crExtends = mdTypeDefNil;
+
+ m_nImplList = 0;
+ m_TyParList = NULL;
+
+ m_SEHD = NULL;
+ m_firstArgName = NULL;
+ m_lastArgName = NULL;
+ m_szNamespace = new char[2];
+ m_szNamespace[0] = 0;
+ m_NSstack.PUSH(m_szNamespace);
+
+ m_szFullNS = new char[MAX_NAMESPACE_LENGTH];
+ memset(m_szFullNS,0,MAX_NAMESPACE_LENGTH);
+ m_ulFullNSLen = MAX_NAMESPACE_LENGTH;
+
+ m_State = STATE_OK;
+ m_fInitialisedMetaData = FALSE;
+ m_fAutoInheritFromObject = TRUE;
+
+ m_ulLastDebugLine = 0xFFFFFFFF;
+ m_ulLastDebugColumn = 0xFFFFFFFF;
+ m_ulLastDebugLineEnd = 0xFFFFFFFF;
+ m_ulLastDebugColumnEnd = 0xFFFFFFFF;
+ m_pSymWriter = NULL;
+ m_pSymDocument = NULL;
+ m_dwIncludeDebugInfo = 0;
+ m_fGeneratePDB = FALSE;
+ m_fIsMscorlib = FALSE;
+ m_fOptimize = FALSE;
+ m_tkSysObject = 0;
+ m_tkSysString = 0;
+ m_tkSysValue = 0;
+ m_tkSysEnum = 0;
+
+ m_pVTable = NULL;
+ m_pMarshal = NULL;
+ m_pPInvoke = NULL;
+
+ m_fReportProgress = TRUE;
+ m_tkCurrentCVOwner = 1; // module
+ m_pOutputBuffer = NULL;
+
+ m_dwSubsystem = (DWORD)-1;
+ m_dwComImageFlags = COMIMAGE_FLAGS_ILONLY;
+ m_dwFileAlignment = 0;
+ m_stBaseAddress = 0;
+ m_stSizeOfStackReserve = 0;
+ m_dwCeeFileFlags = ICEE_CREATE_FILE_PURE_IL;
+
+ g_szSourceFileName[0] = 0;
+
+ m_guidLang = CorSym_LanguageType_ILAssembly;
+ m_guidLangVendor = CorSym_LanguageVendor_Microsoft;
+ m_guidDoc = CorSym_DocumentType_Text;
+ for(int i=0; i<INSTR_POOL_SIZE; i++) m_Instr[i].opcode = -1;
+ m_wzResourceFile = NULL;
+ m_wzKeySourceName = NULL;
+ OnErrGo = false;
+ bClock = NULL;
+
+ m_pbsMD = NULL;
+
+ m_pOutputBuffer = new BYTE[OUTPUT_BUFFER_SIZE];
+
+ m_pCurOutputPos = m_pOutputBuffer;
+ m_pEndOutputPos = m_pOutputBuffer + OUTPUT_BUFFER_SIZE;
+
+ m_crImplList = new mdTypeRef[MAX_INTERFACES_IMPLEMENTED];
+ m_nImplListSize = MAX_INTERFACES_IMPLEMENTED;
+
+ m_pManifest = new AsmMan((void*)this);
+
+ dummyClass = new Class(NULL);
+ indexKeywords(&indxKeywords);
+
+ m_pdbFormat = CLASSIC;
+ m_pPortablePdbWriter = NULL;
+}
+
+
+Assembler::~Assembler()
+{
+ if(m_pbsMD) delete m_pbsMD;
+
+ if(m_pMarshal) delete m_pMarshal;
+ if(m_pManifest) delete m_pManifest;
+ if(m_pPInvoke) delete m_pPInvoke;
+
+ if(m_pVTable) delete m_pVTable;
+
+ m_lstGlobalLabel.RESET(true);
+ m_lstGlobalFixup.RESET(true);
+ m_hshClass.RESET(false);
+ m_lstClass.RESET(true);
+ while((m_ClassStack.POP()));
+ while(m_CustomDescrListStack.POP());
+ m_pCurClass = NULL;
+ dummyClass->m_szFQN = NULL;
+ delete dummyClass;
+
+ if (m_pOutputBuffer) delete [] m_pOutputBuffer;
+ if (m_crImplList) delete [] m_crImplList;
+ if (m_TyParList) delete m_TyParList;
+
+ if (m_pCeeFileGen != NULL) {
+ if (m_pCeeFile)
+ m_pCeeFileGen->DestroyCeeFile(&m_pCeeFile);
+
+ DestroyICeeFileGen(&m_pCeeFileGen);
+
+ m_pCeeFileGen = NULL;
+ }
+
+ while((m_szNamespace = m_NSstack.POP())) ;
+ delete [] m_szFullNS;
+
+ m_DocWriterList.RESET(true);
+
+ m_MethodBodyList.RESET(true);
+
+ m_TypeDefDList.RESET(true);
+
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+ if (m_pImporter != NULL)
+ {
+ m_pImporter->Release();
+ m_pImporter = NULL;
+ }
+ if (m_pEmitter != NULL)
+ {
+ m_pEmitter->Release();
+ m_pEmitter = NULL;
+ }
+ if (m_pPortablePdbWriter != NULL)
+ {
+ delete m_pPortablePdbWriter;
+ m_pPortablePdbWriter = NULL;
+ }
+ if (m_pDisp != NULL)
+ {
+ m_pDisp->Release();
+ m_pDisp = NULL;
+ }
+}
+
+
+BOOL Assembler::Init(BOOL generatePdb, PdbFormat pdbFormat)
+{
+ if (m_pCeeFileGen != NULL) {
+ if (m_pCeeFile)
+ m_pCeeFileGen->DestroyCeeFile(&m_pCeeFile);
+
+ DestroyICeeFileGen(&m_pCeeFileGen);
+
+ m_pCeeFileGen = NULL;
+ }
+
+ if (FAILED(CreateICeeFileGen(&m_pCeeFileGen))) return FALSE;
+
+ if (FAILED(m_pCeeFileGen->CreateCeeFileEx(&m_pCeeFile,(ULONG)m_dwCeeFileFlags))) return FALSE;
+
+ if (FAILED(m_pCeeFileGen->GetSectionCreate(m_pCeeFile, ".il", sdReadOnly, &m_pILSection))) return FALSE;
+ if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".sdata", sdReadWrite, &m_pGlobalDataSection))) return FALSE;
+ if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".tls", sdReadWrite, &m_pTLSSection))) return FALSE;
+
+ m_fGeneratePDB = generatePdb;
+ m_pdbFormat = pdbFormat;
+
+ return TRUE;
+}
+
+void Assembler::SetDLL(BOOL IsDll)
+{
+ HRESULT OK;
+ OK = m_pCeeFileGen->SetDllSwitch(m_pCeeFile, IsDll);
+ _ASSERTE(SUCCEEDED(OK));
+
+ m_fDLL = IsDll;
+}
+
+void Assembler::SetOBJ(BOOL IsObj)
+{
+ HRESULT OK;
+ OK = m_pCeeFileGen->SetObjSwitch(m_pCeeFile, IsObj);
+ _ASSERTE(SUCCEEDED(OK));
+
+ m_fOBJ = IsObj;
+}
+
+
+void Assembler::ResetArgNameList()
+{
+ if(m_firstArgName) delArgNameList(m_firstArgName);
+ m_firstArgName = NULL;
+ m_lastArgName = NULL;
+}
+
+void Assembler::ResetForNextMethod()
+{
+
+ ResetArgNameList();
+
+ m_CurPC = 0;
+ m_pCurOutputPos = m_pOutputBuffer;
+ m_State = STATE_OK;
+ m_pCurMethod = NULL;
+}
+
+void Assembler::ResetLineNumbers()
+{
+ // reset line number information
+ m_ulLastDebugLine = 0xFFFFFFFF;
+ m_ulLastDebugColumn = 0xFFFFFFFF;
+ m_ulLastDebugLineEnd = 0xFFFFFFFF;
+ m_ulLastDebugColumnEnd = 0xFFFFFFFF;
+}
+
+BOOL Assembler::AddMethod(Method *pMethod)
+{
+ BOOL fIsInterface=FALSE, fIsImport=FALSE;
+ ULONG PEFileOffset=0;
+
+ _ASSERTE(m_pCeeFileGen != NULL);
+ if (pMethod == NULL)
+ {
+ report->error("pMethod == NULL");
+ return FALSE;
+ }
+ if(pMethod->m_pClass != NULL)
+ {
+ fIsInterface = IsTdInterface(pMethod->m_pClass->m_Attr);
+ fIsImport = IsTdImport(pMethod->m_pClass->m_Attr);
+ }
+ if(m_CurPC)
+ {
+ char sz[1024];
+ sz[0] = 0;
+ if(fIsImport) strcat_s(sz,1024," imported");
+ if(IsMdAbstract(pMethod->m_Attr)) strcat_s(sz,1024," abstract");
+ if(IsMdPinvokeImpl(pMethod->m_Attr)) strcat_s(sz,1024," pinvoke");
+ if(!IsMiIL(pMethod->m_wImplAttr)) strcat_s(sz,1024," non-IL");
+ if(IsMiRuntime(pMethod->m_wImplAttr)) strcat_s(sz,1024," runtime-supplied");
+ if(IsMiInternalCall(pMethod->m_wImplAttr)) strcat_s(sz,1024," an internal call");
+ if(strlen(sz))
+ {
+ report->error("Method cannot have body if it is%s\n",sz);
+ }
+ }
+ else // method has no body
+ {
+ if(fIsImport || IsMdAbstract(pMethod->m_Attr) || IsMdPinvokeImpl(pMethod->m_Attr)
+ || IsMiRuntime(pMethod->m_wImplAttr) || IsMiInternalCall(pMethod->m_wImplAttr)) return TRUE;
+ if(OnErrGo)
+ {
+ report->error("Method has no body\n");
+ return TRUE;
+ }
+ else
+ {
+ report->warn("Method has no body, 'ret' emitted\n");
+ Instr* pIns = GetInstr();
+ if(pIns)
+ {
+ memset(pIns,0,sizeof(Instr));
+ pIns->opcode = CEE_RET;
+ EmitOpcode(pIns);
+ }
+ }
+ }
+
+ if(pMethod->m_Locals.COUNT()) pMethod->m_LocalsSig=0x11000001; // placeholder, the real token 2b defined in EmitMethod
+
+ COR_ILMETHOD_FAT fatHeader;
+ fatHeader.SetFlags(pMethod->m_Flags);
+ fatHeader.SetMaxStack(pMethod->m_MaxStack);
+ fatHeader.SetLocalVarSigTok(pMethod->m_LocalsSig);
+ fatHeader.SetCodeSize(m_CurPC);
+ bool moreSections = (pMethod->m_dwNumExceptions != 0);
+
+ // if max stack is specified <8, force fat header, otherwise (with tiny header) it will default to 8
+ if((fatHeader.GetMaxStack() < 8)&&(fatHeader.GetLocalVarSigTok()==0)&&(fatHeader.GetCodeSize()<64)&&(!moreSections))
+ fatHeader.SetFlags(fatHeader.GetFlags() | CorILMethod_InitLocals); //forces fat header but does nothing else, since LocalVarSigTok==0
+
+ unsigned codeSize = m_CurPC;
+ unsigned codeSizeAligned = codeSize;
+ if (moreSections)
+ codeSizeAligned = (codeSizeAligned + 3) & ~3; // to insure EH section aligned
+
+ unsigned headerSize = COR_ILMETHOD::Size(&fatHeader, moreSections);
+ unsigned ehSize = COR_ILMETHOD_SECT_EH::Size(pMethod->m_dwNumExceptions, pMethod->m_ExceptionList);
+ unsigned totalSize = headerSize + codeSizeAligned + ehSize;
+
+ BYTE* outBuff;
+ BYTE* endbuf;
+ BinStr* pbsBody;
+ if((pbsBody = new BinStr())==NULL) return FALSE;
+ if((outBuff = pbsBody->getBuff(totalSize))==NULL) return FALSE;
+ endbuf = &outBuff[totalSize];
+
+ // Emit the header
+ outBuff += COR_ILMETHOD::Emit(headerSize, &fatHeader, moreSections, outBuff);
+
+ pMethod->m_pCode = outBuff;
+ pMethod->m_headerOffset= PEFileOffset;
+ pMethod->m_methodOffset= PEFileOffset + headerSize;
+ pMethod->m_CodeSize = codeSize;
+
+ // Emit the code
+ if (codeSizeAligned)
+ {
+ memset(outBuff,0,codeSizeAligned);
+ memcpy(outBuff, m_pOutputBuffer, codeSize);
+ outBuff += codeSizeAligned;
+ }
+
+ if(pMethod->m_dwNumExceptions)
+ {
+ // Validate the eh
+ COR_ILMETHOD_SECT_EH_CLAUSE_FAT* pEx;
+ DWORD TryEnd,HandlerEnd, dwEx, dwEf;
+ for(dwEx = 0, pEx = pMethod->m_ExceptionList; dwEx < pMethod->m_dwNumExceptions; dwEx++, pEx++)
+ {
+ if(pEx->GetTryOffset() > m_CurPC) // i.e., pMethod->m_CodeSize
+ {
+ report->error("Invalid SEH clause #%d: Try block starts beyond code size\n",dwEx+1);
+ }
+ TryEnd = pEx->GetTryOffset()+pEx->GetTryLength();
+ if(TryEnd > m_CurPC)
+ {
+ report->error("Invalid SEH clause #%d: Try block ends beyond code size\n",dwEx+1);
+ }
+ if(pEx->GetHandlerOffset() > m_CurPC)
+ {
+ report->error("Invalid SEH clause #%d: Handler block starts beyond code size\n",dwEx+1);
+ }
+ HandlerEnd = pEx->GetHandlerOffset()+pEx->GetHandlerLength();
+ if(HandlerEnd > m_CurPC)
+ {
+ report->error("Invalid SEH clause #%d: Handler block ends beyond code size\n",dwEx+1);
+ }
+ if(pEx->Flags & COR_ILEXCEPTION_CLAUSE_FILTER)
+ {
+ if(!((pEx->GetFilterOffset() >= TryEnd)||(pEx->GetTryOffset() >= HandlerEnd)))
+ {
+ report->error("Invalid SEH clause #%d: Try and Filter/Handler blocks overlap\n",dwEx+1);
+ }
+ for(dwEf = 0; dwEf < pMethod->m_dwNumEndfilters; dwEf++)
+ {
+ if(pMethod->m_EndfilterOffsetList[dwEf] == pEx->GetHandlerOffset()) break;
+ }
+ if(dwEf >= pMethod->m_dwNumEndfilters)
+ {
+ report->error("Invalid SEH clause #%d: Filter block separated from Handler, or not ending with endfilter\n",dwEx+1);
+ }
+ }
+ else
+ if(!((pEx->GetHandlerOffset() >= TryEnd)||(pEx->GetTryOffset() >= HandlerEnd)))
+ {
+ report->error("Invalid SEH clause #%d: Try and Handler blocks overlap\n",dwEx+1);
+ }
+
+ }
+ // Emit the eh
+ outBuff += COR_ILMETHOD_SECT_EH::Emit(ehSize, pMethod->m_dwNumExceptions,
+ pMethod->m_ExceptionList, false, outBuff);
+ }
+ _ASSERTE(outBuff == endbuf);
+
+ pMethod->m_pbsBody = pbsBody;
+
+ LocalMemberRefFixup* pMRF;
+ while((pMRF = pMethod->m_LocalMemberRefFixupList.POP()))
+ {
+ pMRF->offset += (size_t)(pMethod->m_pCode);
+ m_LocalMemberRefFixupList.PUSH(pMRF); // transfer MRF to assembler's list
+ }
+
+ if(m_fReportProgress)
+ {
+ if (pMethod->IsGlobalMethod())
+ report->msg("Assembled global method %s\n", pMethod->m_szName);
+ else report->msg("Assembled method %s::%s\n", pMethod->m_pClass->m_szFQN,
+ pMethod->m_szName);
+ }
+ return TRUE;
+}
+
+
+BOOL Assembler::EmitMethodBody(Method* pMethod, BinStr* pbsOut)
+{
+ HRESULT hr = S_OK;
+
+ if(pMethod)
+ {
+ BinStr* pbsBody = pMethod->m_pbsBody;
+ unsigned totalSize;
+ if(pbsBody && (totalSize = pbsBody->length()))
+ {
+ unsigned headerSize = pMethod->m_methodOffset-pMethod->m_headerOffset;
+ MethodBody* pMB = NULL;
+ // ----------emit locals signature-------------------
+ unsigned uLocals;
+ if((uLocals = pMethod->m_Locals.COUNT()))
+ {
+ VarDescr* pVD;
+ BinStr* pbsSig = new BinStr();
+ unsigned cnt;
+ DWORD cSig;
+ const COR_SIGNATURE* mySig;
+
+ pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
+ cnt = CorSigCompressData(uLocals,pbsSig->getBuff(5));
+ pbsSig->remove(5-cnt);
+ for(cnt = 0; (pVD = pMethod->m_Locals.PEEK(cnt)); cnt++)
+ {
+ if(pVD->pbsSig) pbsSig->append(pVD->pbsSig);
+ else
+ {
+ report->error("Undefined type of local var slot %d in method %s\n",cnt,pMethod->m_szName);
+ pbsSig->appendInt8(ELEMENT_TYPE_I4);
+ }
+ }
+
+ cSig = pbsSig->length();
+ mySig = (const COR_SIGNATURE *)(pbsSig->ptr());
+
+ if (cSig > 1) // non-empty signature
+ {
+ hr = m_pEmitter->GetTokenFromSig(mySig, cSig, &pMethod->m_LocalsSig);
+ _ASSERTE(SUCCEEDED(hr));
+ }
+ delete pbsSig;
+ COR_ILMETHOD_FAT* pFH; // Fat header guaranteed, because there are local vars
+ pFH = (COR_ILMETHOD_FAT*)(pMethod->m_pbsBody->ptr());
+ pFH->SetLocalVarSigTok(pMethod->m_LocalsSig);
+ }
+ //--------------------------------------------------------------------------------
+ if(m_fGeneratePDB)
+ {
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->OpenMethod(pMethod->m_Tok);
+ ULONG N = pMethod->m_LinePCList.COUNT();
+ if(pMethod->m_fEntryPoint) m_pSymWriter->SetUserEntryPoint(pMethod->m_Tok);
+ if(N)
+ {
+ LinePC *pLPC;
+ ULONG32 *offsets=new ULONG32[N], *lines = new ULONG32[N], *columns = new ULONG32[N];
+ ULONG32 *endlines=new ULONG32[N], *endcolumns=new ULONG32[N];
+ if(offsets && lines && columns && endlines && endcolumns)
+ {
+ DocWriter* pDW;
+ unsigned j=0;
+ while((pDW = m_DocWriterList.PEEK(j++)))
+ {
+ if((m_pSymDocument = pDW->pWriter))
+ {
+ int i, n;
+ for(i=0, n=0; (pLPC = pMethod->m_LinePCList.PEEK(i)); i++)
+ {
+ if(pLPC->pWriter == m_pSymDocument)
+ {
+ offsets[n] = pLPC->PC;
+ lines[n] = pLPC->Line;
+ columns[n] = pLPC->Column;
+ endlines[n] = pLPC->LineEnd;
+ endcolumns[n] = pLPC->ColumnEnd;
+ n++;
+ }
+ }
+ if(n) m_pSymWriter->DefineSequencePoints(m_pSymDocument,n,
+ offsets,lines,columns,endlines,endcolumns);
+ } // end if(pSymDocument)
+ } // end while(pDW = next doc.writer)
+ pMethod->m_LinePCList.RESET(true);
+ }
+ else report->error("\nOutOfMemory!\n");
+ delete [] offsets;
+ delete [] lines;
+ delete [] columns;
+ delete [] endlines;
+ delete [] endcolumns;
+ }//enf if(N)
+ HRESULT hrr;
+ if(pMethod->m_ulLines[1])
+ hrr = m_pSymWriter->SetMethodSourceRange(m_pSymDocument,pMethod->m_ulLines[0], pMethod->m_ulColumns[0],
+ m_pSymDocument,pMethod->m_ulLines[1], pMethod->m_ulColumns[1]);
+ EmitScope(&(pMethod->m_MainScope)); // recursively emits all nested scopes
+
+ m_pSymWriter->CloseMethod();
+ }
+ else if (IsPortablePdb())
+ {
+ if (FAILED(m_pPortablePdbWriter->DefineSequencePoints(pMethod)))
+ return FALSE;
+ if (FAILED(m_pPortablePdbWriter->DefineLocalScope(pMethod)))
+ return FALSE;
+ }
+ } // end if(fIncludeDebugInfo)
+ //-----------------------------------------------------
+
+ if(m_fFoldCode)
+ {
+ for(int k=0; (pMB = m_MethodBodyList.PEEK(k)) != NULL; k++)
+ {
+ if((pMB->pbsBody->length() == totalSize)
+ && (memcmp(pMB->pbsBody->ptr(), pbsBody->ptr(),totalSize)==0))
+ break;
+ }
+ if(pMB)
+ {
+ pMethod->m_headerOffset= pMB->RVA;
+ pMethod->m_methodOffset= pMB->RVA + headerSize;
+ pMethod->m_pCode = pMB->pCode;
+ delete pbsBody;
+ pMethod->m_pbsBody = NULL;
+ m_dwMethodsFolded++;
+ }
+ }
+ if(pMB == NULL)
+ {
+ BYTE* outBuff;
+ unsigned align = (headerSize == 1)? 1 : 4;
+ ULONG PEFileOffset, methodRVA;
+ if(m_fENCMode)
+ {
+ if(pbsOut)
+ {
+ PEFileOffset = pbsOut->length();
+ align--;
+ while(PEFileOffset & align)
+ {
+ pbsOut->appendInt8(0);
+ PEFileOffset++;
+ }
+ pbsOut->append(pbsBody);
+ outBuff = (BYTE*)(pbsOut->ptr()) + (pbsOut->length() - pbsBody->length());
+ }
+ else return FALSE;
+
+ }
+ else
+ {
+ if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, totalSize,
+ align, (void **) &outBuff))) return FALSE;
+ memcpy(outBuff,pbsBody->ptr(),totalSize);
+ // The offset where we start, (not where the alignment bytes start!
+ if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset)))
+ return FALSE;
+ PEFileOffset -= totalSize;
+ }
+
+ pMethod->m_pCode = outBuff + headerSize;
+ pMethod->m_headerOffset= PEFileOffset;
+ pMethod->m_methodOffset= PEFileOffset + headerSize;
+ DoDeferredILFixups(pMethod);
+
+ if(m_fENCMode) methodRVA = PEFileOffset;
+ else m_pCeeFileGen->GetMethodRVA(m_pCeeFile, PEFileOffset,&methodRVA);
+
+ pMethod->m_headerOffset= methodRVA;
+ pMethod->m_methodOffset= methodRVA + headerSize;
+ if(m_fFoldCode)
+ {
+ if((pMB = new MethodBody)==NULL) return FALSE;
+ pMB->pbsBody = pbsBody;
+ pMB->RVA = methodRVA;
+ pMB->pCode = pMethod->m_pCode;
+ m_MethodBodyList.PUSH(pMB);
+ }
+ //else
+ // delete pbsBody;
+ //pMethod->m_pbsBody = NULL;
+ }
+ m_pEmitter->SetRVA(pMethod->m_Tok,pMethod->m_headerOffset);
+ }
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+ImportDescriptor* Assembler::EmitImport(BinStr* DllName)
+{
+ int i = 0, l = 0;
+ ImportDescriptor* pID;
+ char* sz=NULL;
+
+ if(DllName) l = DllName->length(); // No zero terminator here!
+ if(l)
+ {
+ sz = (char*)DllName->ptr();
+ while((pID=m_ImportList.PEEK(i++)))
+ {
+ if((pID->dwDllName== (DWORD) l)&& !memcmp(pID->szDllName,sz,l)) return pID;
+ }
+ }
+ else
+ {
+ while((pID=m_ImportList.PEEK(i++)))
+ {
+ if(pID->dwDllName==0) return pID;
+ }
+ }
+ if((pID = new ImportDescriptor(sz,l)))
+ {
+ m_ImportList.PUSH(pID);
+ pID->mrDll = TokenFromRid(m_ImportList.COUNT(),mdtModuleRef);
+ return pID;
+ }
+ else report->error("Failed to allocate import descriptor\n");
+ return NULL;
+}
+
+void Assembler::EmitImports()
+{
+ WCHAR* wzDllName=&wzUniBuf[0];
+ ImportDescriptor* pID;
+ int i;
+ mdToken tk;
+ for(i=0; (pID = m_ImportList.PEEK(i)); i++)
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pID->szDllName,-1,wzDllName,dwUniBuf-1);
+ if(FAILED(m_pEmitter->DefineModuleRef( // S_OK or error.
+ wzDllName, // [IN] DLL name
+ &tk))) // [OUT] returned
+ report->error("Failed to define module ref '%s'\n",pID->szDllName);
+ else
+ _ASSERTE(tk == pID->mrDll);
+ }
+}
+
+HRESULT Assembler::EmitPinvokeMap(mdToken tk, PInvokeDescriptor* pDescr)
+{
+ WCHAR* wzAlias=&wzUniBuf[0];
+
+ if(pDescr->szAlias) WszMultiByteToWideChar(g_uCodePage,0,pDescr->szAlias,-1,wzAlias,dwUniBuf-1);
+
+ return m_pEmitter->DefinePinvokeMap( // Return code.
+ tk, // [IN] FieldDef, MethodDef or MethodImpl.
+ pDescr->dwAttrs, // [IN] Flags used for mapping.
+ (LPCWSTR)wzAlias, // [IN] Import name.
+ pDescr->mrDll); // [IN] ModuleRef token for the target DLL.
+}
+
+void Assembler::EmitScope(Scope* pSCroot)
+{
+ static ULONG32 scopeID;
+ static ARG_NAME_LIST *pVarList;
+ int i;
+ WCHAR* wzVarName=&wzUniBuf[0];
+ char* szPhonyName=(char*)&wzUniBuf[dwUniBuf >> 1];
+ Scope* pSC = pSCroot;
+ if(pSC && m_pSymWriter)
+ {
+ if(SUCCEEDED(m_pSymWriter->OpenScope(pSC->dwStart,&scopeID)))
+ {
+ if(pSC->pLocals)
+ {
+ for(pVarList = pSC->pLocals; pVarList; pVarList = pVarList->pNext)
+ {
+ if(pVarList->pSig)
+ {
+ if((pVarList->szName)&&(*(pVarList->szName))) strcpy_s(szPhonyName,dwUniBuf >> 1,pVarList->szName);
+ else sprintf_s(szPhonyName,(dwUniBuf >> 1),"V_%d",pVarList->dwAttr);
+
+ WszMultiByteToWideChar(g_uCodePage,0,szPhonyName,-1,wzVarName,dwUniBuf >> 1);
+
+ m_pSymWriter->DefineLocalVariable(wzVarName,0,pVarList->pSig->length(),
+ (BYTE*)pVarList->pSig->ptr(),ADDR_IL_OFFSET,pVarList->dwAttr,0,0,0,0);
+ }
+ else
+ {
+ report->error("Local Var '%s' has no signature\n",pVarList->szName);
+ }
+ }
+ }
+ for(i = 0; (pSC = pSCroot->SubScope.PEEK(i)); i++) EmitScope(pSC);
+ m_pSymWriter->CloseScope(pSCroot->dwEnd);
+ }
+ }
+}
+
+BOOL Assembler::EmitMethod(Method *pMethod)
+{
+// Emit the metadata for a method definition
+ BOOL fSuccess = FALSE;
+ WCHAR* wzMemberName=&wzUniBuf[0];
+ BOOL fIsInterface;
+ DWORD cSig;
+ ULONG methodRVA = 0;
+ mdMethodDef MethodToken;
+ mdTypeDef ClassToken = mdTypeDefNil;
+ char *pszMethodName;
+ COR_SIGNATURE *mySig;
+
+ _ASSERTE((m_pCeeFileGen != NULL) && (pMethod != NULL));
+ fIsInterface = ((pMethod->m_pClass != NULL) && IsTdInterface(pMethod->m_pClass->m_Attr));
+
+
+ pszMethodName = pMethod->m_szName;
+ mySig = pMethod->m_pMethodSig;
+ cSig = pMethod->m_dwMethodCSig;
+
+ // If this is an instance method, make certain the signature says so
+
+ if (!(pMethod->m_Attr & mdStatic))
+ *mySig |= IMAGE_CEE_CS_CALLCONV_HASTHIS;
+
+ ClassToken = (pMethod->IsGlobalMethod())? mdTokenNil
+ : pMethod->m_pClass->m_cl;
+ // Convert name to UNICODE
+ WszMultiByteToWideChar(g_uCodePage,0,pszMethodName,-1,wzMemberName,dwUniBuf-1);
+
+ if(IsMdPrivateScope(pMethod->m_Attr))
+ {
+ WCHAR* p = wcsstr(wzMemberName,W("$PST06"));
+ if(p) *p = 0;
+ }
+
+ if (FAILED(m_pEmitter->DefineMethod(ClassToken, // parent class
+ wzMemberName, // member name
+ pMethod->m_Attr & ~mdReservedMask, // member attributes
+ mySig, // member signature
+ cSig,
+ methodRVA, // RVA
+ pMethod->m_wImplAttr, // implflags
+ &MethodToken)))
+ {
+ report->error("Failed to define method '%s'\n",pszMethodName);
+ goto exit;
+ }
+ pMethod->m_Tok = MethodToken;
+ //--------------------------------------------------------------------------------
+ // the only way to set mdRequireSecObject:
+ if(pMethod->m_Attr & mdRequireSecObject)
+ {
+ mdToken tkPseudoClass;
+ if(FAILED(m_pEmitter->DefineTypeRefByName(1, COR_REQUIRES_SECOBJ_ATTRIBUTE, &tkPseudoClass)))
+ report->error("Unable to define type reference '%s'\n", COR_REQUIRES_SECOBJ_ATTRIBUTE_ANSI);
+ else
+ {
+ mdToken tkPseudoCtor;
+ BYTE bSig[3] = {IMAGE_CEE_CS_CALLCONV_HASTHIS,0,ELEMENT_TYPE_VOID};
+ if(FAILED(m_pEmitter->DefineMemberRef(tkPseudoClass, W(".ctor"), (PCCOR_SIGNATURE)bSig, 3, &tkPseudoCtor)))
+ report->error("Unable to define member reference '%s::.ctor'\n", COR_REQUIRES_SECOBJ_ATTRIBUTE_ANSI);
+ else DefineCV(new CustomDescr(MethodToken,tkPseudoCtor,NULL));
+ }
+ }
+
+ if (pMethod->m_NumTyPars)
+ {
+ ULONG i;
+ mdToken tkNil = mdTokenNil;
+ mdGenericParam tkGP = mdTokenNil;
+ for(i = 0; i < pMethod->m_NumTyPars; i++)
+ {
+ if (FAILED(m_pEmitter->DefineGenericParam(MethodToken, i, pMethod->m_TyPars[i].Attrs(), pMethod->m_TyPars[i].Name(), 0, &tkNil, &tkGP)))
+ {
+ report->error("Unable to define generic param: %s'\n", pMethod->m_TyPars[i].Name());
+ }
+ else
+ {
+ pMethod->m_TyPars[i].Token(tkGP);
+ EmitCustomAttributes(tkGP, pMethod->m_TyPars[i].CAList());
+ }
+ }
+ EmitGenericParamConstraints(pMethod->m_NumTyPars, pMethod->m_TyPars, pMethod->m_Tok, &(pMethod->m_GPCList));
+ }
+ //--------------------------------------------------------------------------------
+ EmitSecurityInfo(MethodToken,
+ pMethod->m_pPermissions,
+ pMethod->m_pPermissionSets);
+ //--------------------------------------------------------------------------------
+ if (pMethod->m_fEntryPoint)
+ {
+ if(fIsInterface) report->error("Entrypoint in Interface: Method '%s'\n",pszMethodName);
+
+ if (FAILED(m_pCeeFileGen->SetEntryPoint(m_pCeeFile, MethodToken)))
+ {
+ report->error("Failed to set entry point for method '%s'\n",pszMethodName);
+ goto exit;
+ }
+
+ }
+ //--------------------------------------------------------------------------------
+ if(IsMdPinvokeImpl(pMethod->m_Attr))
+ {
+ if(pMethod->m_pPInvoke)
+ {
+ HRESULT hr;
+ if(pMethod->m_pPInvoke->szAlias == NULL) pMethod->m_pPInvoke->szAlias = pszMethodName;
+ hr = EmitPinvokeMap(MethodToken,pMethod->m_pPInvoke);
+ if(pMethod->m_pPInvoke->szAlias == pszMethodName) pMethod->m_pPInvoke->szAlias = NULL;
+
+ if(FAILED(hr))
+ {
+ report->error("Failed to set PInvoke map for method '%s'\n",pszMethodName);
+ goto exit;
+ }
+ }
+ }
+
+ { // add parameters to metadata
+ void const *pValue=NULL;
+ ULONG cbValue;
+ DWORD dwCPlusTypeFlag=0;
+ mdParamDef pdef;
+ WCHAR* wzParName=&wzUniBuf[0];
+ char* szPhonyName=(char*)&wzUniBuf[dwUniBuf >> 1];
+ if(pMethod->m_dwRetAttr || pMethod->m_pRetMarshal || pMethod->m_RetCustDList.COUNT())
+ {
+ if(pMethod->m_pRetValue)
+ {
+ dwCPlusTypeFlag= (DWORD)*(pMethod->m_pRetValue->ptr());
+ pValue = (void const *)(pMethod->m_pRetValue->ptr()+1);
+ cbValue = pMethod->m_pRetValue->length()-1;
+ if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) cbValue /= sizeof(WCHAR);
+ }
+ else
+ {
+ pValue = NULL;
+ cbValue = (ULONG)-1;
+ dwCPlusTypeFlag=0;
+ }
+ m_pEmitter->DefineParam(MethodToken,0,NULL,pMethod->m_dwRetAttr,dwCPlusTypeFlag,pValue,cbValue,&pdef);
+
+ if(pMethod->m_pRetMarshal)
+ {
+ if(FAILED(m_pEmitter->SetFieldMarshal (
+ pdef, // [IN] given a fieldDef or paramDef token
+ (PCCOR_SIGNATURE)(pMethod->m_pRetMarshal->ptr()), // [IN] native type specification
+ pMethod->m_pRetMarshal->length()))) // [IN] count of bytes of pvNativeType
+ report->error("Failed to set param marshaling for return\n");
+
+ }
+ EmitCustomAttributes(pdef, &(pMethod->m_RetCustDList));
+ }
+ for(ARG_NAME_LIST *pAN=pMethod->m_firstArgName; pAN; pAN = pAN->pNext)
+ {
+ if(pAN->nNum >= 65535)
+ {
+ report->error("Method '%s': Param.sequence number (%d) exceeds 65535, unable to define parameter\n",pszMethodName,pAN->nNum+1);
+ continue;
+ }
+ if(pAN->dwName) strcpy_s(szPhonyName,dwUniBuf >> 1,pAN->szName);
+ else sprintf_s(szPhonyName,(dwUniBuf >> 1),"A_%d",pAN->nNum);
+
+ WszMultiByteToWideChar(g_uCodePage,0,szPhonyName,-1,wzParName,dwUniBuf >> 1);
+
+ if(pAN->pValue)
+ {
+ dwCPlusTypeFlag= (DWORD)*(pAN->pValue->ptr());
+ pValue = (void const *)(pAN->pValue->ptr()+1);
+ cbValue = pAN->pValue->length()-1;
+ if(dwCPlusTypeFlag == ELEMENT_TYPE_STRING) cbValue /= sizeof(WCHAR);
+ }
+ else
+ {
+ pValue = NULL;
+ cbValue = (ULONG)-1;
+ dwCPlusTypeFlag=0;
+ }
+ m_pEmitter->DefineParam(MethodToken,pAN->nNum+1,wzParName,pAN->dwAttr,dwCPlusTypeFlag,pValue,cbValue,&pdef);
+ if(pAN->pMarshal)
+ {
+ if(FAILED(m_pEmitter->SetFieldMarshal (
+ pdef, // [IN] given a fieldDef or paramDef token
+ (PCCOR_SIGNATURE)(pAN->pMarshal->ptr()), // [IN] native type specification
+ pAN->pMarshal->length()))) // [IN] count of bytes of pvNativeType
+ report->error("Failed to set param marshaling for '%s'\n",pAN->szName);
+ }
+ EmitCustomAttributes(pdef, &(pAN->CustDList));
+ }
+ }
+ fSuccess = TRUE;
+ //--------------------------------------------------------------------------------
+ // Update method implementations for this method
+ {
+ MethodImplDescriptor* pMID;
+ int i;
+ for(i=0;(pMID = pMethod->m_MethodImplDList.PEEK(i));i++)
+ {
+ pMID->m_tkImplementingMethod = MethodToken;
+ // don't delete it here, it's still in the general list
+ }
+ }
+ //--------------------------------------------------------------------------------
+ EmitCustomAttributes(MethodToken, &(pMethod->m_CustomDescrList));
+exit:
+ if (fSuccess == FALSE) m_State = STATE_FAIL;
+ return fSuccess;
+}
+
+BOOL Assembler::EmitMethodImpls()
+{
+ MethodImplDescriptor* pMID;
+ BOOL ret = TRUE;
+ int i;
+ for(i=0; (pMID = m_MethodImplDList.PEEK(i)); i++)
+ {
+ if(m_fENCMode && (!pMID->m_fNew)) continue;
+ pMID->m_tkImplementingMethod = ResolveLocalMemberRef(pMID->m_tkImplementingMethod);
+ pMID->m_tkImplementedMethod = ResolveLocalMemberRef(pMID->m_tkImplementedMethod);
+ if(FAILED(m_pEmitter->DefineMethodImpl( pMID->m_tkDefiningClass,
+ pMID->m_tkImplementingMethod,
+ pMID->m_tkImplementedMethod)))
+ {
+ report->error("Failed to define Method Implementation");
+ ret = FALSE;
+ }
+ pMID->m_fNew = FALSE;
+ }// end while
+ return ret;
+}
+
+mdToken Assembler::ResolveLocalMemberRef(mdToken tok)
+{
+ if(TypeFromToken(tok) == 0x99000000)
+ {
+ tok = RidFromToken(tok);
+ if(tok) tok = m_LocalMethodRefDList.PEEK(tok-1)->m_tkResolved;
+ }
+ else if(TypeFromToken(tok) == 0x98000000)
+ {
+ tok = RidFromToken(tok);
+ if(tok) tok = m_LocalFieldRefDList.PEEK(tok-1)->m_tkResolved;
+ }
+ return tok;
+}
+
+BOOL Assembler::EmitEvent(EventDescriptor* pED)
+{
+ mdMethodDef mdAddOn=mdMethodDefNil,
+ mdRemoveOn=mdMethodDefNil,
+ mdFire=mdMethodDefNil,
+ *mdOthers;
+ int nOthers;
+ WCHAR* wzMemberName=&wzUniBuf[0];
+
+ if(!pED) return FALSE;
+
+ WszMultiByteToWideChar(g_uCodePage,0,pED->m_szName,-1,wzMemberName,dwUniBuf-1);
+
+ mdAddOn = ResolveLocalMemberRef(pED->m_tkAddOn);
+ if(TypeFromToken(mdAddOn) != mdtMethodDef)
+ {
+ report->error("Invalid Add method of event '%s'\n",pED->m_szName);
+ return FALSE;
+ }
+ mdRemoveOn = ResolveLocalMemberRef(pED->m_tkRemoveOn);
+ if(TypeFromToken(mdRemoveOn) != mdtMethodDef)
+ {
+ report->error("Invalid Remove method of event '%s'\n",pED->m_szName);
+ return FALSE;
+ }
+ mdFire = ResolveLocalMemberRef(pED->m_tkFire);
+ if((RidFromToken(mdFire)!=0)&&(TypeFromToken(mdFire) != mdtMethodDef))
+ {
+ report->error("Invalid Fire method of event '%s'\n",pED->m_szName);
+ return FALSE;
+ }
+
+ nOthers = pED->m_tklOthers.COUNT();
+ mdOthers = new mdMethodDef[nOthers+1];
+ if(mdOthers == NULL)
+ {
+ report->error("Failed to allocate Others array for event descriptor\n");
+ nOthers = 0;
+ }
+ for(int j=0; j < nOthers; j++)
+ {
+ mdOthers[j] = ResolveLocalMemberRef((mdToken)(UINT_PTR)(pED->m_tklOthers.PEEK(j))); // @WARNING: casting down from 'mdToken*' to 'mdToken'
+ }
+ mdOthers[nOthers] = mdMethodDefNil; // like null-terminator
+
+ if(FAILED(m_pEmitter->DefineEvent( pED->m_tdClass,
+ wzMemberName,
+ pED->m_dwAttr,
+ pED->m_tkEventType,
+ mdAddOn,
+ mdRemoveOn,
+ mdFire,
+ mdOthers,
+ &(pED->m_edEventTok))))
+ {
+ report->error("Failed to define event '%s'.\n",pED->m_szName);
+ delete [] mdOthers;
+ return FALSE;
+ }
+ EmitCustomAttributes(pED->m_edEventTok, &(pED->m_CustomDescrList));
+ return TRUE;
+}
+
+BOOL Assembler::EmitProp(PropDescriptor* pPD)
+{
+ mdMethodDef mdSet, mdGet, *mdOthers;
+ int nOthers;
+ WCHAR* wzMemberName=&wzUniBuf[0];
+
+ if(!pPD) return FALSE;
+
+ WszMultiByteToWideChar(g_uCodePage,0,pPD->m_szName,-1,wzMemberName,dwUniBuf-1);
+
+ mdSet = ResolveLocalMemberRef(pPD->m_tkSet);
+ if((RidFromToken(mdSet)!=0)&&(TypeFromToken(mdSet) != mdtMethodDef))
+ {
+ report->error("Invalid Set method of property '%s'\n",pPD->m_szName);
+ return FALSE;
+ }
+ mdGet = ResolveLocalMemberRef(pPD->m_tkGet);
+ if((RidFromToken(mdGet)!=0)&&(TypeFromToken(mdGet) != mdtMethodDef))
+ {
+ report->error("Invalid Get method of property '%s'\n",pPD->m_szName);
+ return FALSE;
+ }
+
+ nOthers = pPD->m_tklOthers.COUNT();
+ mdOthers = new mdMethodDef[nOthers+1];
+ if(mdOthers == NULL)
+ {
+ report->error("Failed to allocate Others array for prop descriptor\n");
+ nOthers = 0;
+ }
+ for(int j=0; j < nOthers; j++)
+ {
+ mdOthers[j] = ResolveLocalMemberRef((mdToken)(UINT_PTR)(pPD->m_tklOthers.PEEK(j))); // @WARNING: casting down from 'mdToken*' to 'mdToken'
+
+ if((RidFromToken(mdOthers[j])!=0)&&(TypeFromToken(mdOthers[j]) != mdtMethodDef))
+ {
+ report->error("Invalid Other method of property '%s'\n",pPD->m_szName);
+ delete [] mdOthers;
+ return FALSE;
+ }
+
+ }
+ mdOthers[nOthers] = mdMethodDefNil; // like null-terminator
+
+ if(FAILED(m_pEmitter->DefineProperty( pPD->m_tdClass,
+ wzMemberName,
+ pPD->m_dwAttr,
+ pPD->m_pSig,
+ pPD->m_dwCSig,
+ pPD->m_dwCPlusTypeFlag,
+ pPD->m_pValue,
+ pPD->m_cbValue,
+ mdSet,
+ mdGet,
+ mdOthers,
+ &(pPD->m_pdPropTok))))
+ {
+ report->error("Failed to define property '%s'.\n",pPD->m_szName);
+ delete [] mdOthers;
+ return FALSE;
+ }
+ EmitCustomAttributes(pPD->m_pdPropTok, &(pPD->m_CustomDescrList));
+ return TRUE;
+}
+
+Class *Assembler::FindCreateClass(__in __nullterminated const char *pszFQN)
+{
+ Class *pSearch = NULL;
+
+ if(pszFQN)
+ {
+ dummyClass->m_szFQN = pszFQN;
+ dummyClass->m_Hash = hash((BYTE*)pszFQN, (unsigned)strlen(pszFQN), 10);
+ pSearch = m_hshClass.FIND(dummyClass);
+ dummyClass->m_szFQN = NULL;
+ dummyClass->m_Hash = 0;
+
+ if(!pSearch)
+ {
+ char* pch;
+ DWORD dwFQN = (DWORD)strlen(pszFQN);
+
+ Class *pEncloser = NULL;
+ char* pszNewFQN = new char[dwFQN+1];
+ strcpy_s(pszNewFQN,dwFQN+1,pszFQN);
+ if((pch = strrchr(pszNewFQN, NESTING_SEP)) != NULL)
+ {
+ *pch = 0;
+ pEncloser = FindCreateClass(pszNewFQN);
+ *pch = NESTING_SEP;
+ }
+ pSearch = new Class(pszNewFQN);
+ if (pSearch == NULL)
+ report->error("Failed to create class '%s'\n",pszNewFQN);
+ else
+ {
+ pSearch->m_pEncloser = pEncloser;
+ m_lstClass.PUSH(pSearch);
+ pSearch->m_cl = mdtTypeDef | m_lstClass.COUNT();
+ m_hshClass.PUSH(pSearch);
+ }
+ }
+ }
+
+ return pSearch;
+}
+
+
+BOOL Assembler::EmitClass(Class *pClass)
+{
+ LPCUTF8 szFullName;
+ WCHAR* wzFullName=&wzUniBuf[0];
+ HRESULT hr = E_FAIL;
+ GUID guid;
+ size_t L;
+ mdToken tok;
+
+ if(pClass == NULL) return FALSE;
+
+ hr = CoCreateGuid(&guid);
+ if (FAILED(hr))
+ {
+ printf("Unable to create GUID\n");
+ m_State = STATE_FAIL;
+ return FALSE;
+ }
+
+ if(pClass->m_pEncloser)
+ szFullName = strrchr(pClass->m_szFQN,NESTING_SEP) + 1;
+ else
+ szFullName = pClass->m_szFQN;
+
+ WszMultiByteToWideChar(g_uCodePage,0,szFullName,-1,wzFullName,dwUniBuf);
+
+ L = wcslen(wzFullName);
+ if((L==0)||(wzFullName[L-1]==L'.')) // Missing class name!
+ {
+ wcscat_s(wzFullName,dwUniBuf,W("$UNNAMED_TYPE$"));
+ }
+
+ pClass->m_Attr = CheckClassFlagsIfNested(pClass->m_pEncloser, pClass->m_Attr);
+
+ if (pClass->m_pEncloser)
+ {
+ hr = m_pEmitter->DefineNestedType( wzFullName,
+ pClass->m_Attr, // attributes
+ pClass->m_crExtends, // CR extends class
+ pClass->m_crImplements,// implements
+ pClass->m_pEncloser->m_cl, // Enclosing class.
+ &tok);
+ }
+ else
+ {
+ hr = m_pEmitter->DefineTypeDef( wzFullName,
+ pClass->m_Attr, // attributes
+ pClass->m_crExtends, // CR extends class
+ pClass->m_crImplements,// implements
+ &tok);
+ }
+ _ASSERTE(tok == pClass->m_cl);
+ if (FAILED(hr)) goto exit;
+ if (pClass->m_NumTyPars)
+ {
+ ULONG i;
+ mdToken tkNil = mdTokenNil;
+ mdGenericParam tkGP = mdTokenNil;
+ for(i = 0; i < pClass->m_NumTyPars; i++)
+ {
+ if (FAILED(m_pEmitter->DefineGenericParam(pClass->m_cl, i, pClass->m_TyPars[i].Attrs(), pClass->m_TyPars[i].Name(), 0, &tkNil, &tkGP)))
+ {
+ report->error("Unable to define generic param: %s'\n", pClass->m_TyPars[i].Name());
+ }
+ else
+ {
+ pClass->m_TyPars[i].Token(tkGP);
+ EmitCustomAttributes(tkGP, pClass->m_TyPars[i].CAList());
+ }
+ }
+ EmitGenericParamConstraints(pClass->m_NumTyPars, pClass->m_TyPars, pClass->m_cl, &(pClass->m_GPCList));
+ }
+
+ EmitCustomAttributes(pClass->m_cl, &(pClass->m_CustDList));
+ hr = S_OK;
+
+exit:
+ return SUCCEEDED(hr);
+}
+
+BOOL Assembler::DoGlobalFixups()
+{
+ GlobalFixup *pSearch;
+
+ for (int i=0; (pSearch = m_lstGlobalFixup.PEEK(i)); i++)
+ {
+ GlobalLabel * pLabel = FindGlobalLabel(pSearch->m_szLabel);
+ if (pLabel == NULL)
+ {
+ report->error("Unable to find forward reference global label '%s'\n",
+ pSearch->m_szLabel);
+
+ m_State = STATE_FAIL;
+ return FALSE;
+ }
+ //BYTE * pReference = pSearch->m_pReference;
+ //DWORD GlobalOffset = pLabel->m_GlobalOffset;
+ //memcpy(pReference,&GlobalOffset,4);
+ SET_UNALIGNED_VAL32(pSearch->m_pReference,pLabel->m_GlobalOffset);
+ }
+
+ return TRUE;
+}
+
+state_t Assembler::AddGlobalLabel(__in __nullterminated char *pszName, HCEESECTION section)
+{
+ if (FindGlobalLabel(pszName) != NULL)
+ {
+ report->error("Duplicate global label '%s'\n", pszName);
+ m_State = STATE_FAIL;
+ return m_State;
+ }
+
+ ULONG GlobalOffset;
+
+ HRESULT hr;
+ hr = m_pCeeFileGen->GetSectionDataLen(section, &GlobalOffset);
+ _ASSERTE(SUCCEEDED(hr));
+
+ GlobalLabel *pNew = new GlobalLabel(pszName, GlobalOffset, section);
+ if (pNew == 0)
+ {
+ report->error("Failed to allocate global label '%s'\n",pszName);
+ m_State = STATE_FAIL;
+ return m_State;
+ }
+
+ m_lstGlobalLabel.PUSH(pNew);
+ return m_State;
+}
+
+void Assembler::AddLabel(DWORD CurPC, __in __nullterminated char *pszName)
+{
+ if (m_pCurMethod->FindLabel(pszName) != NULL)
+ {
+ report->error("Duplicate label: '%s'\n", pszName);
+
+ m_State = STATE_FAIL;
+ }
+ else
+ {
+ Label *pNew = new Label(pszName, CurPC);
+
+ if (pNew != NULL)
+ //m_pCurMethod->m_lstLabel.PUSH(pNew);
+ m_lstLabel.PUSH(pNew);
+ else
+ {
+ report->error("Failed to allocate label '%s'\n",pszName);
+ m_State = STATE_FAIL;
+ }
+ }
+}
+
+void Assembler::DoDeferredILFixups(Method* pMethod)
+{ // Now that we know where in the file the code bytes will wind up,
+ // we can update the RVAs and offsets.
+ ILFixup *pSearch;
+ HRESULT hr;
+ GlobalFixup *Fix = NULL;
+ int i;
+ for (i=0;(pSearch = pMethod->m_lstILFixup.PEEK(i));i++)
+ {
+ switch(pSearch->m_Kind)
+ {
+ case ilGlobal:
+ Fix = pSearch->m_Fixup;
+ _ASSERTE(Fix != NULL);
+ Fix->m_pReference = pMethod->m_pCode+pSearch->m_OffsetInMethod;
+ break;
+
+ case ilToken:
+ hr = m_pCeeFileGen->AddSectionReloc(m_pILSection,
+ pSearch->m_OffsetInMethod+pMethod->m_methodOffset,
+ m_pILSection,
+ srRelocMapToken);
+ _ASSERTE(SUCCEEDED(hr));
+ break;
+
+ case ilRVA:
+ hr = m_pCeeFileGen->AddSectionReloc(m_pILSection,
+ pSearch->m_OffsetInMethod+pMethod->m_methodOffset,
+ m_pGlobalDataSection,
+ srRelocAbsolute);
+ _ASSERTE(SUCCEEDED(hr));
+ break;
+
+ default:
+ ;
+ }
+ }
+}
+/**************************************************************************/
+BOOL Assembler::DoFixups(Method* pMethod)
+{
+ Fixup *pSearch;
+
+ for (int i=0; (pSearch = pMethod->m_lstFixup.PEEK(i)); i++)
+ {
+ Label * pLabel = pMethod->FindLabel(pSearch->m_szLabel);
+ long offset;
+
+ if (pLabel == NULL)
+ {
+ report->error("Unable to find forward reference label '%s' called from PC=%d\n",
+ pSearch->m_szLabel, pSearch->m_RelativeToPC);
+
+ //m_State = STATE_FAIL;
+ return FALSE;
+ }
+
+ offset = pLabel->m_PC - pSearch->m_RelativeToPC;
+
+ if (pSearch->m_FixupSize == 1)
+ {
+ if (offset > 127 || offset < -128)
+ {
+ report->error("Offset of forward reference label '%s' called from PC=%d is too large for 1 byte pcrel\n",
+ pLabel->m_szName, pSearch->m_RelativeToPC);
+
+ //m_State = STATE_FAIL;
+ return FALSE;
+ }
+
+ *pSearch->m_pBytes = (BYTE) offset;
+ }
+ else if (pSearch->m_FixupSize == 4)
+ {
+ SET_UNALIGNED_VAL32(pSearch->m_pBytes,offset);
+ }
+ }
+
+ return TRUE;
+}
+
+
+OPCODE Assembler::DecodeOpcode(const BYTE *pCode, DWORD *pdwLen)
+{
+ OPCODE opcode;
+
+ *pdwLen = 1;
+ opcode = OPCODE(pCode[0]);
+ switch(opcode) {
+ case CEE_PREFIX1:
+ opcode = OPCODE(pCode[1] + 256);
+ if (opcode < 0 || opcode >= CEE_COUNT)
+ return CEE_COUNT;
+ *pdwLen = 2;
+ break;
+
+ case CEE_PREFIXREF:
+ case CEE_PREFIX2:
+ case CEE_PREFIX3:
+ case CEE_PREFIX4:
+ case CEE_PREFIX5:
+ case CEE_PREFIX6:
+ case CEE_PREFIX7:
+ return CEE_COUNT;
+ default:
+ break;
+ }
+ return opcode;
+}
+
+char* Assembler::ReflectionNotation(mdToken tk)
+{
+ char *sz = (char*)&wzUniBuf[dwUniBuf>>1], *pc;
+ *sz=0;
+ switch(TypeFromToken(tk))
+ {
+ case mdtTypeDef:
+ {
+ Class *pClass = m_lstClass.PEEK(RidFromToken(tk)-1);
+ if(pClass)
+ {
+ strcpy_s(sz,dwUniBuf>>1,pClass->m_szFQN);
+ pc = sz;
+ while((pc = strchr(pc,NESTING_SEP)) != NULL)
+ {
+ *pc = '+';
+ pc++;
+ }
+ }
+ }
+ break;
+
+ case mdtTypeRef:
+ {
+ ULONG N;
+ mdToken tkResScope;
+ if(SUCCEEDED(m_pImporter->GetTypeRefProps(tk,&tkResScope,wzUniBuf,dwUniBuf>>1,&N)))
+ {
+ WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,sz,dwUniBuf>>1,NULL,NULL);
+ if(TypeFromToken(tkResScope)==mdtAssemblyRef)
+ {
+ AsmManAssembly *pAsmRef = m_pManifest->m_AsmRefLst.PEEK(RidFromToken(tkResScope)-1);
+ if(pAsmRef)
+ {
+ pc = &sz[strlen(sz)];
+ pc+=sprintf_s(pc,(dwUniBuf >> 1),", %s, Version=%d.%d.%d.%d, Culture=",pAsmRef->szName,
+ pAsmRef->usVerMajor,pAsmRef->usVerMinor,pAsmRef->usBuild,pAsmRef->usRevision);
+ ULONG L=0;
+ if(pAsmRef->pLocale && (L=pAsmRef->pLocale->length()))
+ {
+ memcpy(wzUniBuf,pAsmRef->pLocale->ptr(),L);
+ wzUniBuf[L>>1] = 0;
+ WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,pc,dwUniBuf>>1,NULL,NULL);
+ }
+ else pc+=sprintf_s(pc,(dwUniBuf >> 1),"neutral");
+ pc = &sz[strlen(sz)];
+ if(pAsmRef->pPublicKeyToken && (L=pAsmRef->pPublicKeyToken->length()))
+ {
+ pc+=sprintf_s(pc,(dwUniBuf >> 1),", Publickeytoken=");
+ BYTE* pb = (BYTE*)(pAsmRef->pPublicKeyToken->ptr());
+ for(N=0; N<L; N++,pb++) pc+=sprintf_s(pc,(dwUniBuf >> 1),"%2.2x",*pb);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return sz;
+}
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bits set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= b; a -= c; a ^= (c >> 13); \
+ b -= c; b -= a; b ^= (a << 8); \
+ c -= a; c -= b; c ^= (b >> 13); \
+ a -= b; a -= c; a ^= (c >> 12); \
+ b -= c; b -= a; b ^= (a << 16); \
+ c -= a; c -= b; c ^= (b >> 5); \
+ a -= b; a -= c; a ^= (c >> 3); \
+ b -= c; b -= a; b ^= (a << 10); \
+ c -= a; c -= b; c ^= (b >> 15); \
+}
+
+/*
+--------------------------------------------------------------------
+hash() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 6*len+35 instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+unsigned hash(
+ __in_ecount(length) const BYTE *k, /* the key */
+ unsigned length, /* the length of the key */
+ unsigned initval) /* the previous hash, or an arbitrary value */
+{
+ register unsigned a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = initval; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 12)
+ {
+ a += (k[0] + ((unsigned)k[1] << 8) + ((unsigned)k[2] << 16) + ((unsigned)k[3] << 24));
+ b += (k[4] + ((unsigned)k[5] << 8) + ((unsigned)k[6] << 16) + ((unsigned)k[7] << 24));
+ c += (k[8] + ((unsigned)k[9] << 8) + ((unsigned)k[10] << 16) + ((unsigned)k[11] << 24));
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) /* all the case statements fall through */
+ {
+ case 11: c+=((unsigned)k[10] << 24);
+ FALLTHROUGH;
+ case 10: c+=((unsigned)k[9] << 16);
+ FALLTHROUGH;
+ case 9 : c+=((unsigned)k[8] << 8);
+ FALLTHROUGH;
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((unsigned)k[7] << 24);
+ FALLTHROUGH;
+ case 7 : b+=((unsigned)k[6] << 16);
+ FALLTHROUGH;
+ case 6 : b+=((unsigned)k[5] << 8);
+ FALLTHROUGH;
+ case 5 : b+=k[4];
+ FALLTHROUGH;
+ case 4 : a+=((unsigned)k[3] << 24);
+ FALLTHROUGH;
+ case 3 : a+=((unsigned)k[2] << 16);
+ FALLTHROUGH;
+ case 2 : a+=((unsigned)k[1] << 8);
+ FALLTHROUGH;
+ case 1 : a+=k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
+
diff --git a/src/coreclr/ilasm/assembler.cpp b/src/coreclr/ilasm/assembler.cpp
new file mode 100644
index 00000000000..b9bc13fbaa4
--- /dev/null
+++ b/src/coreclr/ilasm/assembler.cpp
@@ -0,0 +1,2792 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// File: assembler.cpp
+//
+
+//
+
+#include "ilasmpch.h"
+
+#include "assembler.h"
+#include "binstr.h"
+#include "nvpair.h"
+
+#define FAIL_UNLESS(x, y) if (!(x)) { report->error y; return; }
+
+/**************************************************************************/
+void Assembler::StartNameSpace(__in __nullterminated char* name)
+{
+ m_NSstack.PUSH(m_szNamespace);
+ m_szNamespace = name;
+ unsigned L = (unsigned)strlen(m_szFullNS);
+ unsigned l = (unsigned)strlen(name);
+ if(L+l+1 >= m_ulFullNSLen)
+ {
+ char* pch = new char[((L+l)/MAX_NAMESPACE_LENGTH + 1)*MAX_NAMESPACE_LENGTH];
+ if(pch)
+ {
+ memcpy(pch,m_szFullNS,L+1);
+ delete [] m_szFullNS;
+ m_szFullNS = pch;
+ m_ulFullNSLen = ((L+l)/MAX_NAMESPACE_LENGTH + 1)*MAX_NAMESPACE_LENGTH;
+ }
+ else report->error("Failed to reallocate the NameSpace buffer\n");
+ }
+ if(L) m_szFullNS[L] = NAMESPACE_SEPARATOR_CHAR;
+ else L = 0xFFFFFFFF;
+ memcpy(&m_szFullNS[L+1],m_szNamespace, l+1);
+}
+
+/**************************************************************************/
+void Assembler::EndNameSpace()
+{
+ char *p = &m_szFullNS[strlen(m_szFullNS)-strlen(m_szNamespace)];
+ if(p > m_szFullNS) p--;
+ *p = 0;
+ delete [] m_szNamespace;
+ if((m_szNamespace = m_NSstack.POP())==NULL)
+ {
+ m_szNamespace = new char[2];
+ m_szNamespace[0] = 0;
+ }
+}
+
+/**************************************************************************/
+void Assembler::ClearImplList(void)
+{
+ while(m_nImplList) m_crImplList[--m_nImplList] = mdTypeRefNil;
+}
+/**************************************************************************/
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22008) // "Suppress PREfast warnings about integer overflow"
+#endif
+void Assembler::AddToImplList(mdToken tk)
+{
+ if(m_nImplList+1 >= m_nImplListSize)
+ {
+ mdToken *ptr = new mdToken[m_nImplListSize + MAX_INTERFACES_IMPLEMENTED];
+ if(ptr == NULL)
+ {
+ report->error("Failed to reallocate Impl List from %d to %d bytes\n",
+ m_nImplListSize*sizeof(mdToken),
+ (m_nImplListSize+MAX_INTERFACES_IMPLEMENTED)*sizeof(mdToken));
+ return;
+ }
+ memcpy(ptr,m_crImplList,m_nImplList*sizeof(mdToken));
+ delete m_crImplList;
+ m_crImplList = ptr;
+ m_nImplListSize += MAX_INTERFACES_IMPLEMENTED;
+ }
+ m_crImplList[m_nImplList++] = tk;
+ m_crImplList[m_nImplList] = mdTypeRefNil;
+}
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+void Assembler::ClearBoundList(void)
+{
+ m_TyParList = NULL;
+}
+/**************************************************************************/
+mdToken Assembler::ResolveClassRef(mdToken tkResScope, __in __nullterminated const char *pszFullClassName, Class** ppClass)
+{
+ Class *pClass = NULL;
+ mdToken tkRet = mdTokenNil;
+ mdToken *ptkSpecial = NULL;
+
+ if(pszFullClassName == NULL) return mdTokenNil;
+
+ switch(strlen(pszFullClassName))
+ {
+ case 11:
+ if(strcmp(pszFullClassName,"System.Enum")==0) ptkSpecial = &m_tkSysEnum;
+ break;
+ case 13:
+ if(strcmp(pszFullClassName,"System.Object")==0) ptkSpecial = &m_tkSysObject;
+ else if(strcmp(pszFullClassName,"System.String")==0) ptkSpecial = &m_tkSysString;
+ break;
+ case 16:
+ if(strcmp(pszFullClassName,"System.ValueType")==0) ptkSpecial = &m_tkSysValue;
+ break;
+ }
+ if(ptkSpecial) // special token
+ {
+ if(*ptkSpecial) // already resolved
+ {
+ tkRet = *ptkSpecial;
+ if(ppClass)
+ {
+ if(TypeFromToken(tkRet)==mdtTypeDef)
+ *ppClass = m_lstClass.PEEK(RidFromToken(tkRet)-1);
+ else *ppClass = NULL;
+ }
+ return tkRet;
+ }
+ else // needs to be resolved
+ if(!m_fIsMscorlib) tkResScope = GetBaseAsmRef();
+ }
+ if(tkResScope == 1)
+ {
+ if((pClass = FindCreateClass(pszFullClassName)) != NULL) tkRet = pClass->m_cl;
+ }
+ else
+ {
+ tkRet = MakeTypeRef(tkResScope, pszFullClassName);
+ pClass = NULL;
+ }
+ if(ppClass) *ppClass = pClass;
+ if(ptkSpecial) *ptkSpecial = tkRet;
+ return tkRet;
+}
+
+class TypeSpecContainer
+{
+private:
+ // Contain a BinStr
+ unsigned __int8 *ptr_;
+ unsigned len_;
+ // Hash the BinStr, just for speed of lookup
+ unsigned hash_;
+ // The value we're looking for
+ mdToken token_;
+public:
+ // Constructor for a 'lookup' object
+ TypeSpecContainer(BinStr *typeSpec) :
+ ptr_(typeSpec->ptr()),
+ len_(typeSpec->length()),
+ hash_(typeSpec->length()),
+ token_(mdTokenNil)
+ {
+ for (unsigned i = 0; i < len_; i++)
+ hash_ = (hash_ * 257) ^ ((i + 1) * (ptr_[i] ^ 0xA5));
+ }
+ // Constructor for a 'permanent' object
+ // Don't bother re-hashing, since we will always have already constructed the lookup object
+ TypeSpecContainer(const TypeSpecContainer &t, mdToken tk) :
+ ptr_(new unsigned __int8[t.len_]),
+ len_(t.len_),
+ hash_(t.hash_),
+ token_(tk)
+ {
+ _ASSERT(tk != mdTokenNil);
+ _ASSERT(t.token_ == mdTokenNil);
+ memcpy(ptr_, t.ptr_, len_);
+ }
+ ~TypeSpecContainer()
+ {
+ if (token_ != mdTokenNil)
+ // delete any memory for a 'permanent' object
+ delete[] ptr_;
+ }
+ // this is the operator for a RBTREE
+ int ComparedTo(TypeSpecContainer *t) const
+ {
+ // If they don't hash the same, just diff the hashes
+ if (hash_ != t->hash_)
+ return hash_ - t->hash_;
+ if (len_ != t->len_)
+ return len_ - t->len_;
+ return memcmp(ptr_, t->ptr_, len_);
+ }
+ // The only public data we need
+ mdToken Token() const { return token_; }
+};
+
+static RBTREE<TypeSpecContainer> typeSpecCache;
+
+extern FIFO<char> TyParFixupList;
+
+/**************************************************************************/
+mdToken Assembler::ResolveTypeSpec(BinStr* typeSpec)
+{
+ mdToken tk;
+
+ // It is safe to use the cache only if there are no pending fixups
+ if (TyParFixupList.COUNT() != 0)
+ {
+ if (FAILED(m_pEmitter->GetTokenFromTypeSpec(typeSpec->ptr(), typeSpec->length(), &tk)))
+ return mdTokenNil;
+ return tk;
+ }
+
+ TypeSpecContainer tsc(typeSpec);
+
+ // GetTokenFromTypeSpec is a linear search through an unsorted list
+ // Instead of doing that all the time, look this thing up in a cache
+ TypeSpecContainer *res = typeSpecCache.FIND(&tsc);
+ if (res != NULL)
+ {
+#ifdef _DEBUG
+ // Verify that the cache is in sync with the master copy in metadata
+ PCOR_SIGNATURE pSig;
+ ULONG cSig;
+ m_pImporter->GetTypeSpecFromToken(res->Token(),(PCCOR_SIGNATURE*)&pSig,&cSig);
+ _ASSERTE(typeSpec->length() == cSig);
+ _ASSERTE(memcmp(typeSpec->ptr(), pSig, cSig) == 0);
+#endif
+
+ return res->Token();
+ }
+
+ if (FAILED(m_pEmitter->GetTokenFromTypeSpec(typeSpec->ptr(), typeSpec->length(), &tk)))
+ return mdTokenNil;
+
+ typeSpecCache.PUSH(new TypeSpecContainer(tsc, tk));
+ return tk;
+}
+
+/**************************************************************************/
+mdToken Assembler::GetAsmRef(__in __nullterminated const char* szName)
+{
+ mdToken tkResScope = 0;
+ if(strcmp(szName,"*")==0) tkResScope = mdTokenNil;
+ else
+ {
+ tkResScope = m_pManifest->GetAsmRefTokByName(szName);
+ if(RidFromToken(tkResScope)==0)
+ {
+ // emit the AssemblyRef
+ // if it's not self, try to get attributes with Autodetect
+ unsigned L = (unsigned)strlen(szName)+1;
+ char *sz = new char[L];
+ if(sz)
+ {
+ memcpy(sz,szName,L);
+ AsmManAssembly *pAsmRef = m_pManifest->m_pCurAsmRef;
+ m_pManifest->StartAssembly(sz,NULL,0,TRUE);
+ if(RidFromToken(m_pManifest->GetAsmTokByName(szName))==0)
+ {
+ report->warn("Reference to undeclared extern assembly '%s'. Attempting autodetect\n",szName);
+ m_pManifest->SetAssemblyAutodetect();
+ }
+ m_pManifest->EndAssembly();
+ tkResScope = m_pManifest->GetAsmRefTokByName(szName);
+ m_pManifest->m_pCurAsmRef = pAsmRef;
+ }
+ else
+ report->error("\nOut of memory!\n");
+ }
+ }
+ return tkResScope;
+}
+
+mdToken Assembler::GetBaseAsmRef()
+{
+ // First we check for "System.Private.CoreLib" as the base or System assembly
+ //
+ AsmManAssembly* coreLibAsm = m_pManifest->GetAsmRefByAsmName("System.Private.CoreLib");
+ if(coreLibAsm != NULL)
+ {
+ return GetAsmRef(coreLibAsm->szAlias ? coreLibAsm->szAlias : coreLibAsm->szName);
+ }
+
+ AsmManAssembly* sysRuntime = m_pManifest->GetAsmRefByAsmName("System.Runtime");
+ if(sysRuntime != NULL)
+ {
+ return GetAsmRef(sysRuntime->szAlias ? sysRuntime->szAlias : sysRuntime->szName);
+ }
+
+ AsmManAssembly* mscorlibAsm = m_pManifest->GetAsmRefByAsmName("mscorlib");
+ if(mscorlibAsm != NULL)
+ {
+ return GetAsmRef(mscorlibAsm->szAlias ? mscorlibAsm->szAlias : mscorlibAsm->szName);
+ }
+
+ AsmManAssembly* netstandardAsm = m_pManifest->GetAsmRefByAsmName("netstandard");
+ if (netstandardAsm != NULL)
+ {
+ return GetAsmRef(netstandardAsm->szAlias ? netstandardAsm->szAlias : netstandardAsm->szName);
+ }
+
+ return GetAsmRef("mscorlib");
+}
+
+mdToken Assembler::GetInterfaceImpl(mdToken tsClass, mdToken tsInterface)
+{
+ mdToken result = mdTokenNil;
+ HCORENUM iiEnum = 0;
+ ULONG actualInterfaces;
+ mdInterfaceImpl impls;
+
+ while (SUCCEEDED(m_pImporter->EnumInterfaceImpls(&iiEnum, tsClass, &impls, 1, &actualInterfaces)))
+ {
+ if (actualInterfaces == 1)
+ {
+ mdToken classToken, interfaceToken;
+ if (FAILED(m_pImporter->GetInterfaceImplProps(impls, &classToken, &interfaceToken)))
+ break;
+ if (classToken == tsClass && interfaceToken == tsInterface)
+ {
+ result = impls;
+ break;
+ }
+ }
+ }
+ m_pImporter->CloseEnum(iiEnum);
+ return result;
+}
+
+/**************************************************************************/
+mdToken Assembler::GetModRef(__in __nullterminated char* szName)
+{
+ mdToken tkResScope = 0;
+ if(!strcmp(szName,m_szScopeName))
+ tkResScope = 1; // scope is "this module"
+ else
+ {
+ ImportDescriptor* pID;
+ int i = 0;
+ tkResScope = mdModuleRefNil;
+ DWORD L = (DWORD)strlen(szName);
+ while((pID=m_ImportList.PEEK(i++)))
+ {
+ if(pID->dwDllName != L) continue;
+ if((L > 0) && (strcmp(pID->szDllName,szName)!=0)) continue;
+ tkResScope = pID->mrDll;
+ break;
+ }
+ if(RidFromToken(tkResScope)==0)
+ report->error("Undefined module ref '%s'\n",szName);
+ }
+ return tkResScope;
+}
+/**************************************************************************/
+mdToken Assembler::MakeTypeRef(mdToken tkResScope, LPCUTF8 pszFullClassName)
+{
+ mdToken tkRet = mdTokenNil;
+ if(pszFullClassName && *pszFullClassName)
+ {
+ LPCUTF8 pc;
+ if((pc = strrchr(pszFullClassName,NESTING_SEP))) // scope: enclosing class
+ {
+ LPUTF8 szScopeName;
+ DWORD L = (DWORD)(pc-pszFullClassName);
+ if((szScopeName = new char[L+1]) != NULL)
+ {
+ memcpy(szScopeName,pszFullClassName,L);
+ szScopeName[L] = 0;
+ tkResScope = MakeTypeRef(tkResScope,szScopeName);
+ delete [] szScopeName;
+ }
+ else
+ report->error("\nOut of memory!\n");
+ pc++;
+ }
+ else pc = pszFullClassName;
+ if(*pc)
+ {
+ // convert name to widechar
+ WszMultiByteToWideChar(g_uCodePage,0,pc,-1,wzUniBuf,dwUniBuf);
+ if(FAILED(m_pEmitter->DefineTypeRefByName(tkResScope, wzUniBuf, &tkRet))) tkRet = mdTokenNil;
+ }
+ }
+ return tkRet;
+}
+/**************************************************************************/
+
+DWORD Assembler::CheckClassFlagsIfNested(Class* pEncloser, DWORD attr)
+{
+ DWORD wasAttr = attr;
+ if(pEncloser && (!IsTdNested(attr)))
+ {
+ if(OnErrGo)
+ report->error("Nested class has non-nested visibility (0x%08X)\n",attr);
+ else
+ {
+ attr &= ~tdVisibilityMask;
+ attr |= (IsTdPublic(wasAttr) ? tdNestedPublic : tdNestedPrivate);
+ report->warn("Nested class has non-nested visibility (0x%08X), changed to nested (0x%08X)\n",wasAttr,attr);
+ }
+ }
+ else if((pEncloser==NULL) && IsTdNested(attr))
+ {
+ if(OnErrGo)
+ report->error("Non-nested class has nested visibility (0x%08X)\n",attr);
+ else
+ {
+ attr &= ~tdVisibilityMask;
+ attr |= (IsTdNestedPublic(wasAttr) ? tdPublic : tdNotPublic);
+ report->warn("Non-nested class has nested visibility (0x%08X), changed to non-nested (0x%08X)\n",wasAttr,attr);
+ }
+ }
+ return attr;
+}
+
+/**************************************************************************/
+
+void Assembler::StartClass(__in __nullterminated char* name, DWORD attr, TyParList *typars)
+{
+ Class *pEnclosingClass = m_pCurClass;
+ char *szFQN;
+ ULONG LL;
+
+ m_TyParList = typars;
+
+ if (m_pCurMethod != NULL)
+ {
+ report->error("Class cannot be declared within a method scope\n");
+ }
+ if(pEnclosingClass)
+ {
+ LL = pEnclosingClass->m_dwFQN+(ULONG)strlen(name)+2;
+ if((szFQN = new char[LL]))
+ sprintf_s(szFQN,LL,"%s%c%s",pEnclosingClass->m_szFQN,NESTING_SEP,name);
+ else
+ report->error("\nOut of memory!\n");
+ }
+ else
+ {
+ unsigned L = (unsigned)strlen(m_szFullNS);
+ unsigned LLL = (unsigned)strlen(name);
+ LL = L + LLL + (L ? 2 : 1);
+ if((szFQN = new char[LL]))
+ {
+ if(L) sprintf_s(szFQN,LL,"%s.%s",m_szFullNS,name);
+ else memcpy(szFQN,name,LL);
+ if(LL > MAX_CLASSNAME_LENGTH)
+ {
+ report->error("Full class name too long (%d characters, %d allowed).\n",LL-1,MAX_CLASSNAME_LENGTH-1);
+ }
+ }
+ else
+ report->error("\nOut of memory!\n");
+ }
+ if(szFQN == NULL) return;
+
+ mdToken tkThis;
+ if(m_fIsMscorlib)
+ tkThis = ResolveClassRef(1,szFQN,&m_pCurClass); // boils down to FindCreateClass(szFQN)
+ else
+ {
+ m_pCurClass = FindCreateClass(szFQN);
+ tkThis = m_pCurClass->m_cl;
+ }
+ if(m_pCurClass->m_bIsMaster)
+ {
+ m_pCurClass->m_Attr = CheckClassFlagsIfNested(pEnclosingClass, attr);
+
+ if (m_TyParList)
+ {
+ m_pCurClass->m_NumTyPars = m_TyParList->ToArray(&(m_pCurClass->m_TyPars));
+ delete m_TyParList;
+ m_TyParList = NULL;
+ RecordTypeConstraints(&m_pCurClass->m_GPCList, m_pCurClass->m_NumTyPars, m_pCurClass->m_TyPars);
+ }
+ else m_pCurClass->m_NumTyPars = 0;
+ m_pCurClass->m_pEncloser = pEnclosingClass;
+ } // end if(old class) else
+ m_tkCurrentCVOwner = 0;
+ m_CustomDescrListStack.PUSH(m_pCustomDescrList);
+ m_pCustomDescrList = &(m_pCurClass->m_CustDList);
+
+ m_ClassStack.PUSH(pEnclosingClass);
+ ClearBoundList();
+}
+
+/**************************************************************************/
+
+void Assembler::AddClass()
+{
+ mdTypeRef crExtends = mdTypeRefNil;
+ BOOL bIsEnum = FALSE;
+ BOOL bIsValueType = FALSE;
+
+ if(m_pCurClass->m_bIsMaster)
+ {
+ DWORD attr = m_pCurClass->m_Attr;
+ if(!IsNilToken(m_crExtends))
+ {
+ // has a superclass
+ if(IsTdInterface(attr)) report->error("Base class in interface\n");
+ bIsValueType = (m_crExtends == m_tkSysValue)&&(m_pCurClass->m_cl != m_tkSysEnum);
+ bIsEnum = (m_crExtends == m_tkSysEnum);
+ crExtends = m_crExtends;
+ }
+ else
+ {
+ bIsEnum = ((attr & 0x40000000) != 0);
+ bIsValueType = ((attr & 0x80000000) != 0);
+ }
+ attr &= 0x3FFFFFFF;
+ if (m_fAutoInheritFromObject && (crExtends == mdTypeRefNil) && (!IsTdInterface(attr)))
+ {
+ mdToken tkMscorlib = m_fIsMscorlib ? 1 : GetBaseAsmRef();
+ crExtends = bIsEnum ?
+ ResolveClassRef(tkMscorlib,"System.Enum",NULL)
+ :( bIsValueType ?
+ ResolveClassRef(tkMscorlib,"System.ValueType",NULL)
+ : ResolveClassRef(tkMscorlib, "System.Object",NULL));
+ }
+ m_pCurClass->m_Attr = attr;
+ m_pCurClass->m_crExtends = (m_pCurClass->m_cl == m_tkSysObject)? mdTypeRefNil : crExtends;
+
+ if ((m_pCurClass->m_dwNumInterfaces = m_nImplList) != NULL)
+ {
+ if(bIsEnum) report->error("Enum implementing interface(s)\n");
+ if((m_pCurClass->m_crImplements = new mdTypeRef[m_nImplList+1]) != NULL)
+ memcpy(m_pCurClass->m_crImplements, m_crImplList, (m_nImplList+1)*sizeof(mdTypeRef));
+ else
+ {
+ report->error("Failed to allocate Impl List for class '%s'\n", m_pCurClass->m_szFQN);
+ m_pCurClass->m_dwNumInterfaces = 0;
+ }
+ }
+ else m_pCurClass->m_crImplements = NULL;
+ if(bIsValueType)
+ {
+ if(!IsTdSealed(attr))
+ {
+ if(OnErrGo) report->error("Non-sealed value class\n");
+ else
+ {
+ report->warn("Non-sealed value class, made sealed\n");
+ m_pCurClass->m_Attr |= tdSealed;
+ }
+ }
+ }
+ m_pCurClass->m_bIsMaster = FALSE;
+ } // end if(old class) else
+ ClearImplList();
+ m_crExtends = mdTypeRefNil;
+}
+
+/**************************************************************************/
+void Assembler::EndClass()
+{
+ m_pCurClass = m_ClassStack.POP();
+ m_tkCurrentCVOwner = 0;
+ m_pCustomDescrList = m_CustomDescrListStack.POP();
+}
+
+/**************************************************************************/
+void Assembler::SetPinvoke(BinStr* DllName, int Ordinal, BinStr* Alias, int Attrs)
+{
+ if(m_pPInvoke) delete m_pPInvoke;
+ if(DllName->length())
+ {
+ if((m_pPInvoke = new PInvokeDescriptor))
+ {
+ unsigned l;
+ ImportDescriptor* pID;
+ if((pID = EmitImport(DllName)))
+ {
+ m_pPInvoke->mrDll = pID->mrDll;
+ m_pPInvoke->szAlias = NULL;
+ if(Alias)
+ {
+ l = Alias->length();
+ if((m_pPInvoke->szAlias = new char[l+1]))
+ {
+ memcpy(m_pPInvoke->szAlias,Alias->ptr(),l);
+ m_pPInvoke->szAlias[l] = 0;
+ }
+ else report->error("\nOut of memory!\n");
+ }
+ m_pPInvoke->dwAttrs = (DWORD)Attrs;
+ }
+ else
+ {
+ delete m_pPInvoke;
+ m_pPInvoke = NULL;
+ report->error("PInvoke refers to undefined imported DLL\n");
+ }
+ }
+ else
+ report->error("Failed to allocate PInvokeDescriptor\n");
+ }
+ else
+ {
+ m_pPInvoke = NULL; // No DLL name, it's "local" (IJW) PInvoke
+ report->error("Local (embedded native) PInvoke method, the resulting PE file is unusable\n");
+ }
+ if(DllName) delete DllName;
+ if(Alias) delete Alias;
+}
+
+/**************************************************************************/
+void Assembler::StartMethod(__in __nullterminated char* name, BinStr* sig, CorMethodAttr flags, BinStr* retMarshal, DWORD retAttr, TyParList *typars)
+{
+ if (m_pCurMethod != NULL)
+ {
+ report->error("Cannot declare a method '%s' within another method\n",name);
+ }
+ if (!m_fInitialisedMetaData)
+ {
+ if (FAILED(InitMetaData())) // impl. see WRITER.CPP
+ {
+ _ASSERTE(0);
+ }
+ }
+ size_t namelen = strlen(name);
+ if(namelen >= MAX_CLASSNAME_LENGTH)
+ {
+ char c = name[MAX_CLASSNAME_LENGTH-1];
+ name[MAX_CLASSNAME_LENGTH-1] = 0;
+ report->error("Method '%s...' -- name too long (%d characters).\n",name,namelen);
+ name[MAX_CLASSNAME_LENGTH-1] = c;
+ }
+ if (!(flags & mdStatic))
+ *(sig->ptr()) |= IMAGE_CEE_CS_CALLCONV_HASTHIS;
+ else if(*(sig->ptr()) & (IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS))
+ {
+ if(OnErrGo) report->error("Method '%s' -- both static and instance\n", name);
+ else
+ {
+ report->warn("Method '%s' -- both static and instance, set to static\n", name);
+ *(sig->ptr()) &= ~(IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS);
+ }
+ }
+
+ if(!IsMdPrivateScope(flags))
+ {
+ Method* pMethod;
+ Class* pClass = (m_pCurClass ? m_pCurClass : m_pModuleClass);
+ DWORD L = (DWORD)strlen(name);
+ for(int j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if( (pMethod->m_dwName == L) &&
+ (!strcmp(pMethod->m_szName,name)) &&
+ (pMethod->m_dwMethodCSig == sig->length()) &&
+ (!memcmp(pMethod->m_pMethodSig,sig->ptr(),sig->length()))
+ &&(!IsMdPrivateScope(pMethod->m_Attr)))
+ {
+ if(m_fTolerateDupMethods)
+ {
+ // reset for new body
+ pMethod->m_lstFixup.RESET(true);
+ //pMethod->m_lstLabel.RESET(true);
+ m_lstLabel.RESET(true);
+ pMethod->m_Locals.RESET(true);
+ delArgNameList(pMethod->m_firstArgName);
+ delArgNameList(pMethod->m_firstVarName);
+ pMethod->m_pCurrScope = &(pMethod->m_MainScope);
+ pMethod->m_pCurrScope->Reset();
+ pMethod->m_firstArgName = getArgNameList();
+ pMethod->m_dwNumExceptions = 0;
+ pMethod->m_dwNumEndfilters = 0;
+ if(pMethod->m_pRetMarshal) delete pMethod->m_pRetMarshal;
+ if(pMethod->m_pRetValue) delete pMethod->m_pRetValue;
+
+ pMethod->m_MethodImplDList.RESET(false); // ptrs in m_MethodImplDList are dups of those in Assembler
+
+ pMethod->m_CustomDescrList.RESET(true);
+
+ if(pMethod->m_fEntryPoint)
+ {
+ pMethod->m_fEntryPoint = FALSE;
+ m_fEntryPointPresent = FALSE;
+ }
+
+ if(pMethod->m_pbsBody)
+ {
+ // no need to remove relevant MemberRef Fixups from the Assembler list:
+ // their m_fNew flag is set to FALSE anyway.
+ // Just get rid of old method body
+ delete pMethod->m_pbsBody;
+ pMethod->m_pbsBody = NULL;
+ }
+
+ pMethod->m_fNewBody = TRUE;
+ m_pCurMethod = pMethod;
+ }
+ else
+ report->error("Duplicate method declaration\n");
+ break;
+ }
+ }
+ }
+ if(m_pCurMethod == NULL)
+ {
+ if(m_pCurClass)
+ { // instance method
+ if(IsMdAbstract(flags) && !IsTdAbstract(m_pCurClass->m_Attr))
+ {
+ report->error("Abstract method '%s' in non-abstract class '%s'\n",name,m_pCurClass->m_szFQN);
+ }
+ if(m_pCurClass->m_crExtends == m_tkSysEnum) report->error("Method in enum\n");
+
+ if(!strcmp(name,COR_CTOR_METHOD_NAME))
+ {
+ flags = (CorMethodAttr)(flags | mdSpecialName);
+ if(IsTdInterface(m_pCurClass->m_Attr)) report->error("Instance constructor in interface\n");
+ }
+ m_pCurMethod = new Method(this, m_pCurClass, name, sig, flags);
+ }
+ else
+ {
+ if(IsMdAbstract(flags))
+ {
+ if(OnErrGo) report->error("Global method '%s' can't be abstract\n",name);
+ else
+ {
+ report->warn("Global method '%s' can't be abstract, flag removed\n",name);
+ flags = (CorMethodAttr)(((int) flags) &~mdAbstract);
+ }
+ }
+ if(!IsMdStatic(flags))
+ {
+ if(OnErrGo) report->error("Non-static global method '%s'\n",name);
+ else
+ {
+ report->warn("Non-static global method '%s', made static\n",name);
+ flags = (CorMethodAttr)(flags | mdStatic);
+ *((BYTE*)(sig->ptr())) &= ~(IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS);
+ }
+ }
+ m_pCurMethod = new Method(this, m_pCurClass, name, sig, flags);
+ if (m_pCurMethod)
+ {
+ m_pCurMethod->SetIsGlobalMethod();
+ if (m_fInitialisedMetaData == FALSE) InitMetaData();
+ }
+ }
+ if(m_pCurMethod)
+ {
+ if(!OnErrGo)
+ {
+ if(m_pCurMethod->m_firstArgName)
+ {
+ for(ARG_NAME_LIST *pAN=m_pCurMethod->m_firstArgName; pAN; pAN = pAN->pNext)
+ {
+ if(pAN->dwName)
+ {
+ int k = m_pCurMethod->findArgNum(pAN->pNext,pAN->szName,pAN->dwName);
+ if(k >= 0)
+ report->warn("Duplicate param name '%s' in method '%s'\n",pAN->szName,name);
+ }
+ }
+ }
+ }
+ m_pCurMethod->m_pRetMarshal = retMarshal;
+ m_pCurMethod->m_dwRetAttr = retAttr;
+ m_tkCurrentCVOwner = 0;
+ m_CustomDescrListStack.PUSH(m_pCustomDescrList);
+ m_pCustomDescrList = &(m_pCurMethod->m_CustomDescrList);
+ m_pCurMethod->m_MainScope.dwStart = m_CurPC;
+ if (typars)
+ {
+ m_pCurMethod->m_NumTyPars = typars->ToArray(&(m_pCurMethod->m_TyPars));
+ delete typars;
+ m_TyParList = NULL;
+ RecordTypeConstraints(&m_pCurMethod->m_GPCList, m_pCurMethod->m_NumTyPars, m_pCurMethod->m_TyPars);
+ }
+ else m_pCurMethod->m_NumTyPars = 0;
+ }
+ else report->error("Failed to allocate Method class\n");
+ } // end if new method
+}
+
+/**************************************************************************/
+void Assembler::EndMethod()
+{
+
+ if(m_pCurMethod->m_pCurrScope != &(m_pCurMethod->m_MainScope))
+ {
+ report->error("Invalid lexical scope structure in method %s\n",m_pCurMethod->m_szName);
+ }
+ m_pCurMethod->m_pCurrScope->dwEnd = m_CurPC;
+ if (DoFixups(m_pCurMethod)) AddMethod(m_pCurMethod); //AddMethod - see ASSEM.CPP
+ else
+ {
+ report->error("Method '%s' compilation failed.\n",m_pCurMethod->m_szName);
+ }
+ //m_pCurMethod->m_lstLabel.RESET(true);
+ m_lstLabel.RESET(true);
+ m_tkCurrentCVOwner = 0;
+ m_pCustomDescrList = m_CustomDescrListStack.POP();
+ ResetForNextMethod(); // see ASSEM.CPP
+}
+/**************************************************************************/
+/* rvaLabel is the optional label that indicates this field points at a particular RVA */
+void Assembler::AddField(__inout_z __inout char* name, BinStr* sig, CorFieldAttr flags, __in __nullterminated char* rvaLabel, BinStr* pVal, ULONG ulOffset)
+{
+ FieldDescriptor* pFD;
+ ULONG i,n;
+ mdToken tkParent = mdTokenNil;
+ Class* pClass;
+
+ if (m_pCurMethod)
+ report->error("Field cannot be declared within a method\n");
+
+ if(strlen(name) >= MAX_CLASSNAME_LENGTH)
+ {
+ char c = name[MAX_CLASSNAME_LENGTH-1];
+ name[MAX_CLASSNAME_LENGTH-1] = 0;
+ report->error("Field '%s...' -- name too long (%d characters).\n",name,strlen(name));
+ name[MAX_CLASSNAME_LENGTH-1] = c;
+ }
+
+ if(sig && (sig->length() >= 2))
+ {
+ if(sig->ptr()[1] == ELEMENT_TYPE_VOID)
+ report->error("Illegal use of type 'void'\n");
+ }
+
+ if (m_pCurClass)
+ {
+ tkParent = m_pCurClass->m_cl;
+
+ if(IsTdInterface(m_pCurClass->m_Attr))
+ {
+ if(!IsFdStatic(flags))
+ {
+ report->warn("Instance field in interface (CLS violation)\n");
+ if(!IsFdPublic(flags)) report->error("Non-public instance field in interface\n");
+ }
+ }
+ }
+ else
+ {
+ if(ulOffset != 0xFFFFFFFF)
+ {
+ report->warn("Offset in global field '%s' is ignored\n",name);
+ ulOffset = 0xFFFFFFFF;
+ }
+ if(!IsFdStatic(flags))
+ {
+ if(OnErrGo) report->error("Non-static global field\n");
+ else
+ {
+ report->warn("Non-static global field, made static\n");
+ flags = (CorFieldAttr)(flags | fdStatic);
+ }
+ }
+ }
+ pClass = (m_pCurClass ? m_pCurClass : m_pModuleClass);
+ n = pClass->m_FieldDList.COUNT();
+ DWORD L = (DWORD)strlen(name);
+ for(i = 0; i < n; i++)
+ {
+ pFD = pClass->m_FieldDList.PEEK(i);
+ if((pFD->m_tdClass == tkParent)&&(L==pFD->m_dwName)&&(!strcmp(pFD->m_szName,name))
+ &&(pFD->m_pbsSig->length() == sig->length())
+ &&(memcmp(pFD->m_pbsSig->ptr(),sig->ptr(),sig->length())==0))
+ {
+ report->error("Duplicate field declaration: '%s'\n",name);
+ break;
+ }
+ }
+ if (rvaLabel && !IsFdStatic(flags))
+ report->error("Only static fields can have 'at' clauses\n");
+
+ if(i >= n)
+ {
+ if((pFD = new FieldDescriptor))
+ {
+ pFD->m_tdClass = tkParent;
+ pFD->m_szName = name;
+ pFD->m_dwName = L;
+ pFD->m_fdFieldTok = mdTokenNil;
+ if((pFD->m_ulOffset = ulOffset) != 0xFFFFFFFF) pClass->m_dwNumFieldsWithOffset++;
+ pFD->m_rvaLabel = rvaLabel;
+ pFD->m_pbsSig = sig;
+ pFD->m_pClass = pClass;
+ pFD->m_pbsValue = pVal;
+ pFD->m_pbsMarshal = m_pMarshal;
+ pFD->m_pPInvoke = m_pPInvoke;
+ pFD->m_dwAttr = flags;
+
+ m_tkCurrentCVOwner = 0;
+ m_pCustomDescrList = &(pFD->m_CustomDescrList);
+
+ pClass->m_FieldDList.PUSH(pFD);
+ pClass->m_fNewMembers = TRUE;
+ }
+ else
+ report->error("Failed to allocate Field Descriptor\n");
+ }
+ else
+ {
+ if(pVal) delete pVal;
+ if(m_pPInvoke) delete m_pPInvoke;
+ if(m_pMarshal) delete m_pMarshal;
+ delete name;
+ }
+ m_pPInvoke = NULL;
+ m_pMarshal = NULL;
+}
+
+BOOL Assembler::EmitField(FieldDescriptor* pFD)
+{
+ WCHAR* wzFieldName=&wzUniBuf[0];
+ HRESULT hr;
+ DWORD cSig;
+ COR_SIGNATURE* mySig;
+ mdFieldDef mb;
+ BYTE ValType = ELEMENT_TYPE_VOID;
+ void * pValue = NULL;
+ unsigned lVal = 0;
+ BOOL ret = TRUE;
+
+ cSig = pFD->m_pbsSig->length();
+ mySig = (COR_SIGNATURE*)(pFD->m_pbsSig->ptr());
+
+ WszMultiByteToWideChar(g_uCodePage,0,pFD->m_szName,-1,wzFieldName,dwUniBuf); //int)cFieldNameLength);
+ if(IsFdPrivateScope(pFD->m_dwAttr))
+ {
+ WCHAR* p = wcsstr(wzFieldName,W("$PST04"));
+ if(p) *p = 0;
+ }
+
+ if(pFD->m_pbsValue && pFD->m_pbsValue->length())
+ {
+ ValType = *(pFD->m_pbsValue->ptr());
+ lVal = pFD->m_pbsValue->length() - 1; // 1 is type byte
+ pValue = (void*)(pFD->m_pbsValue->ptr() + 1);
+ if(ValType == ELEMENT_TYPE_STRING)
+ {
+ //while(lVal % sizeof(WCHAR)) { pFD->m_pbsValue->appendInt8(0); lVal++; }
+ lVal /= sizeof(WCHAR);
+
+#if defined(ALIGN_ACCESS) || BIGENDIAN
+ void* pValueTemp = _alloca(lVal * sizeof(WCHAR));
+ memcpy(pValueTemp, pValue, lVal * sizeof(WCHAR));
+ pValue = pValueTemp;
+
+ SwapStringLength((WCHAR*)pValue, lVal);
+#endif
+ }
+ }
+
+ hr = m_pEmitter->DefineField(
+ pFD->m_tdClass,
+ wzFieldName,
+ pFD->m_dwAttr,
+ mySig,
+ cSig,
+ ValType,
+ pValue,
+ lVal,
+ &mb
+ );
+ if (FAILED(hr))
+ {
+ report->error("Failed to define field '%s' (HRESULT=0x%08X)\n",pFD->m_szName,hr);
+ ret = FALSE;
+ }
+ else
+ {
+ //--------------------------------------------------------------------------------
+ if(IsFdPinvokeImpl(pFD->m_dwAttr)&&(pFD->m_pPInvoke))
+ {
+ if(pFD->m_pPInvoke->szAlias == NULL) pFD->m_pPInvoke->szAlias = pFD->m_szName;
+ if(FAILED(EmitPinvokeMap(mb,pFD->m_pPInvoke)))
+ {
+ report->error("Failed to define PInvoke map of .field '%s'\n",pFD->m_szName);
+ ret = FALSE;
+ }
+ }
+ //--------------------------------------------------------------------------
+ if(pFD->m_pbsMarshal)
+ {
+ if(FAILED(hr = m_pEmitter->SetFieldMarshal (
+ mb, // [IN] given a fieldDef or paramDef token
+ (PCCOR_SIGNATURE)(pFD->m_pbsMarshal->ptr()), // [IN] native type specification
+ pFD->m_pbsMarshal->length()))) // [IN] count of bytes of pvNativeType
+ {
+ report->error("Failed to set field marshaling for '%s' (HRESULT=0x%08X)\n",pFD->m_szName,hr);
+ ret = FALSE;
+ }
+ }
+ //--------------------------------------------------------------------------------
+ // Set the the RVA to a dummy value. later it will be fixed
+ // up to be something correct, but if we don't emit something
+ // the size of the meta-data will not be correct
+ if (pFD->m_rvaLabel)
+ {
+ m_fHaveFieldsWithRvas = TRUE;
+ hr = m_pEmitter->SetFieldRVA(mb, 0xCCCCCCCC);
+ if (FAILED(hr))
+ {
+ report->error("Failed to set RVA for field '%s' (HRESULT=0x%08X)\n",pFD->m_szName,hr);
+ ret = FALSE;
+ }
+ }
+ //--------------------------------------------------------------------------------
+ EmitCustomAttributes(mb, &(pFD->m_CustomDescrList));
+
+ }
+ pFD->m_fdFieldTok = mb;
+ return ret;
+}
+
+/**************************************************************************/
+void Assembler::EmitByte(int val)
+{
+ char ch = (char)val;
+ //if((val < -128)||(val > 127))
+ // report->warn("Emitting 0x%X as a byte: data truncated to 0x%X\n",(unsigned)val,(BYTE)ch);
+ EmitBytes((BYTE *)&ch,1);
+}
+
+/**************************************************************************/
+void Assembler::NewSEHDescriptor(void) //sets m_SEHD
+{
+ m_SEHDstack.PUSH(m_SEHD);
+ m_SEHD = new SEH_Descriptor;
+ if(m_SEHD == NULL) report->error("Failed to allocate SEH descriptor\n");
+}
+/**************************************************************************/
+void Assembler::SetTryLabels(__in __nullterminated char * szFrom, __in __nullterminated char *szTo)
+{
+ if(!m_SEHD) return;
+ Label *pLbl = m_pCurMethod->FindLabel(szFrom);
+ if(pLbl)
+ {
+ m_SEHD->tryFrom = pLbl->m_PC;
+ if((pLbl = m_pCurMethod->FindLabel(szTo))) m_SEHD->tryTo = pLbl->m_PC; //FindLabel: Method.CPP
+ else report->error("Undefined 2nd label in 'try <label> to <label>'\n");
+ }
+ else report->error("Undefined 1st label in 'try <label> to <label>'\n");
+}
+/**************************************************************************/
+void Assembler::SetFilterLabel(__in __nullterminated char *szFilter)
+{
+ if(!m_SEHD) return;
+ Label *pLbl = m_pCurMethod->FindLabel(szFilter);
+ if(pLbl) m_SEHD->sehFilter = pLbl->m_PC;
+ else report->error("Undefined label in 'filter <label>'\n");
+}
+/**************************************************************************/
+void Assembler::SetCatchClass(mdToken catchClass)
+{
+ if(!m_SEHD) return;
+ m_SEHD->cException = catchClass;
+
+}
+/**************************************************************************/
+void Assembler::SetHandlerLabels(__in __nullterminated char *szHandlerFrom, __in __nullterminated char *szHandlerTo)
+{
+ if(!m_SEHD) return;
+ Label *pLbl = m_pCurMethod->FindLabel(szHandlerFrom);
+ if(pLbl)
+ {
+ m_SEHD->sehHandler = pLbl->m_PC;
+ if(szHandlerTo)
+ {
+ pLbl = m_pCurMethod->FindLabel(szHandlerTo);
+ if(pLbl)
+ {
+ m_SEHD->sehHandlerTo = pLbl->m_PC;
+ return;
+ }
+ }
+ else
+ {
+ m_SEHD->sehHandlerTo = m_SEHD->sehHandler - 1;
+ return;
+ }
+ }
+ report->error("Undefined label in 'handler <label> to <label>'\n");
+}
+/**************************************************************************/
+void Assembler::EmitTry(void) //enum CorExceptionFlag kind, char* beginLabel, char* endLabel, char* handleLabel, char* filterOrClass)
+{
+ if(m_SEHD)
+ {
+ bool isFilter=(m_SEHD->sehClause == COR_ILEXCEPTION_CLAUSE_FILTER),
+ isFault=(m_SEHD->sehClause == COR_ILEXCEPTION_CLAUSE_FAULT),
+ isFinally=(m_SEHD->sehClause == COR_ILEXCEPTION_CLAUSE_FINALLY);
+
+ AddException(m_SEHD->tryFrom, m_SEHD->tryTo, m_SEHD->sehHandler, m_SEHD->sehHandlerTo,
+ m_SEHD->cException, isFilter, isFault, isFinally);
+ }
+ else report->error("Attempt to EmitTry with NULL SEH descriptor\n");
+}
+/**************************************************************************/
+
+void Assembler::AddException(DWORD pcStart, DWORD pcEnd, DWORD pcHandler, DWORD pcHandlerTo, mdTypeRef crException, BOOL isFilter, BOOL isFault, BOOL isFinally)
+{
+ if (m_pCurMethod == NULL)
+ {
+ report->error("Exceptions can be declared only when in a method scope\n");
+ return;
+ }
+
+ if (m_pCurMethod->m_dwNumExceptions >= m_pCurMethod->m_dwMaxNumExceptions)
+ {
+ COR_ILMETHOD_SECT_EH_CLAUSE_FAT *ptr =
+ new COR_ILMETHOD_SECT_EH_CLAUSE_FAT[m_pCurMethod->m_dwMaxNumExceptions+MAX_EXCEPTIONS];
+ if(ptr == NULL)
+ {
+ report->error("Failed to reallocate SEH buffer\n");
+ return;
+ }
+ memcpy(ptr,m_pCurMethod->m_ExceptionList,m_pCurMethod->m_dwNumExceptions*sizeof(COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
+ delete [] m_pCurMethod->m_ExceptionList;
+ m_pCurMethod->m_ExceptionList = ptr;
+ m_pCurMethod->m_dwMaxNumExceptions += MAX_EXCEPTIONS;
+ }
+
+ COR_ILMETHOD_SECT_EH_CLAUSE_FAT *clause = &m_pCurMethod->m_ExceptionList[m_pCurMethod->m_dwNumExceptions];
+ clause->SetTryOffset(pcStart);
+ clause->SetTryLength(pcEnd - pcStart);
+ clause->SetHandlerOffset(pcHandler);
+ clause->SetHandlerLength(pcHandlerTo - pcHandler);
+ clause->SetClassToken(crException);
+
+ int flags = COR_ILEXCEPTION_CLAUSE_OFFSETLEN;
+ if (isFilter) {
+ flags |= COR_ILEXCEPTION_CLAUSE_FILTER;
+ }
+ if (isFault) {
+ flags |= COR_ILEXCEPTION_CLAUSE_FAULT;
+ }
+ if (isFinally) {
+ flags |= COR_ILEXCEPTION_CLAUSE_FINALLY;
+ }
+ clause->SetFlags((CorExceptionFlag)flags);
+
+ m_pCurMethod->m_dwNumExceptions++;
+}
+
+/**************************************************************************/
+void Assembler::EmitMaxStack(unsigned val)
+{
+ if(val > 0xFFFF) report->warn(".maxstack parameter exceeds 65535, truncated to %d\n",val&0xFFFF);
+ if (m_pCurMethod) m_pCurMethod->m_MaxStack = val&0xFFFF;
+ else report->error(".maxstack can be used only within a method scope\n");
+}
+
+/**************************************************************************/
+void Assembler::EmitLocals(BinStr* sig)
+{
+ if(sig)
+ {
+ if (m_pCurMethod)
+ {
+ ARG_NAME_LIST *pAN, *pList= getArgNameList();
+ if(pList)
+ {
+ VarDescr* pVD;
+ for(pAN=pList; pAN; pAN = pAN->pNext)
+ {
+ if(pAN->dwAttr == 0) pAN->dwAttr = m_pCurMethod->m_Locals.COUNT() +1;
+ (pAN->dwAttr)--;
+ if((pVD = m_pCurMethod->m_Locals.PEEK(pAN->dwAttr)))
+ {
+ if(pVD->bInScope)
+ {
+ report->warn("Local var slot %d is in use\n",pAN->dwAttr);
+ }
+ if(pVD->pbsSig && ((pVD->pbsSig->length() != pAN->pSig->length()) ||
+ (memcmp(pVD->pbsSig->ptr(),pAN->pSig->ptr(),pVD->pbsSig->length()))))
+ {
+ report->error("Local var slot %d: type conflict\n",pAN->dwAttr);
+ }
+ }
+ else
+ { // create new entry:
+ for(unsigned n = m_pCurMethod->m_Locals.COUNT(); n <= pAN->dwAttr; n++)
+ {
+ pVD = new VarDescr;
+ if(pVD != NULL) m_pCurMethod->m_Locals.PUSH(pVD);
+ else
+ {
+ report->error("Out of memory allocating local var descriptor\n");
+ delete sig;
+ return;
+ }
+ }
+ }
+ pVD->dwSlot = pAN->dwAttr;
+ pVD->pbsSig = pAN->pSig;
+ pVD->bInScope = TRUE;
+ }
+ if(pVD->pbsSig && (pVD->pbsSig->length() == 1))
+ {
+ if(pVD->pbsSig->ptr()[0] == ELEMENT_TYPE_VOID)
+ report->error("Illegal local var type: 'void'\n");
+ }
+ m_pCurMethod->m_pCurrScope->pLocals =
+ m_pCurMethod->catArgNameList(m_pCurMethod->m_pCurrScope->pLocals, pList);
+ }
+ }
+ else report->error(".locals can be used only within a method scope\n");
+ delete sig;
+ }
+ else report->error("Attempt to EmitLocals with NULL argument\n");
+}
+
+/**************************************************************************/
+void Assembler::EmitEntryPoint()
+{
+ if (m_pCurMethod)
+ {
+ if(!m_fEntryPointPresent)
+ {
+ if(IsMdStatic(m_pCurMethod->m_Attr))
+ {
+ m_pCurMethod->m_fEntryPoint = TRUE;
+ m_fEntryPointPresent = TRUE;
+ }
+ else report->error("Non-static method as entry point\n");
+ }
+ else report->error("Multiple .entrypoint declarations\n");
+ }
+ else report->error(".entrypoint can be used only within a method scope\n");
+}
+
+/**************************************************************************/
+void Assembler::EmitZeroInit()
+{
+ if (m_pCurMethod) m_pCurMethod->m_Flags |= CorILMethod_InitLocals;
+ else report->error(".zeroinit can be used only within a method scope\n");
+}
+
+/**************************************************************************/
+void Assembler::SetImplAttr(unsigned short attrval)
+{
+ if (m_pCurMethod)
+ {
+ if(IsMiNative(attrval)||IsMiOPTIL(attrval)||IsMiUnmanaged(attrval))
+ report->error("Cannot compile native/unmanaged method\n");
+ m_pCurMethod->m_wImplAttr = attrval;
+ }
+}
+
+/**************************************************************************/
+void Assembler::EmitData(__in_opt void *buffer, unsigned len)
+{
+ if (len != 0)
+ {
+ void* ptr;
+ HRESULT hr = m_pCeeFileGen->GetSectionBlock(m_pCurSection, len, 1, &ptr);
+ if (FAILED(hr))
+ {
+ report->error("Could not extend data section (out of memory?)");
+ exit(1);
+ }
+
+ if (buffer != NULL)
+ {
+ memcpy(ptr, buffer, len);
+ }
+ else
+ {
+ memset(ptr, 0, len);
+ }
+ }
+}
+
+/**************************************************************************/
+void Assembler::EmitDD(__in __nullterminated char *str)
+{
+ DWORD dwAddr = 0;
+ GlobalLabel *pLabel = FindGlobalLabel(str);
+
+ ULONG loc;
+ HRESULT hr = m_pCeeFileGen->GetSectionDataLen(m_pCurSection, &loc);
+ _ASSERTE(SUCCEEDED(hr));
+
+ DWORD* ptr;
+ DWORD sizeofptr = (DWORD)((m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32) ? sizeof(DWORD) : sizeof(__int64));
+ hr = m_pCeeFileGen->GetSectionBlock(m_pCurSection, sizeofptr, 1, (void**) &ptr);
+ if (FAILED(hr))
+ {
+ report->error("Could not extend data section (out of memory?)");
+ exit(1);
+ }
+
+ if (pLabel != 0) {
+ dwAddr = pLabel->m_GlobalOffset;
+ if (pLabel->m_Section != m_pGlobalDataSection) {
+ report->error("For '&label', label must be in data section");
+ m_State = STATE_FAIL;
+ }
+ }
+ else
+ AddDeferredGlobalFixup(str, (BYTE*) ptr);
+
+ hr = m_pCeeFileGen->AddSectionReloc(m_pCurSection, loc, m_pGlobalDataSection, srRelocHighLow);
+ _ASSERTE(SUCCEEDED(hr));
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_STRIP_RELOCS)
+ {
+ report->error("Base relocations are emitted, while /STRIPRELOC option has been specified");
+ }
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32)
+ {
+ m_dwComImageFlags &= ~COMIMAGE_FLAGS_ILONLY;
+ if (m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ COR_SET_32BIT_REQUIRED(m_dwComImageFlags);
+ *ptr = dwAddr;
+ }
+ else
+ {
+ m_dwComImageFlags &= ~COMIMAGE_FLAGS_ILONLY;
+ *((__int64*)ptr) = (__int64)dwAddr;
+ }
+}
+
+/**************************************************************************/
+GlobalLabel *Assembler::FindGlobalLabel(LPCUTF8 pszName)
+{
+ GlobalLabel lSearch(pszName,0,NULL), *pL;
+ pL = m_lstGlobalLabel.FIND(&lSearch);
+ lSearch.m_szName = NULL;
+ return pL;
+ //return m_lstGlobalLabel.FIND(pszName);
+}
+
+/**************************************************************************/
+
+GlobalFixup *Assembler::AddDeferredGlobalFixup(__in __nullterminated char *pszLabel, BYTE* pReference)
+{
+ GlobalFixup *pNew = new GlobalFixup(pszLabel, (BYTE*) pReference);
+ if (pNew == NULL)
+ {
+ report->error("Failed to allocate global fixup\n");
+ m_State = STATE_FAIL;
+ }
+ else
+ m_lstGlobalFixup.PUSH(pNew);
+
+ return pNew;
+}
+
+/**************************************************************************/
+void Assembler::AddDeferredILFixup(ILFixupType Kind)
+{
+ _ASSERTE(Kind != ilGlobal);
+ AddDeferredILFixup(Kind, NULL);
+}
+/**************************************************************************/
+
+void Assembler::AddDeferredILFixup(ILFixupType Kind,
+ GlobalFixup *GFixup)
+{
+ ILFixup *pNew = new ILFixup(m_CurPC, Kind, GFixup);
+
+ _ASSERTE(m_pCurMethod != NULL);
+ if (pNew == NULL)
+ {
+ report->error("Failed to allocate IL fixup\n");
+ m_State = STATE_FAIL;
+ }
+ else
+ m_pCurMethod->m_lstILFixup.PUSH(pNew);
+}
+
+/**************************************************************************/
+void Assembler::EmitDataString(BinStr* str)
+{
+ if(str)
+ {
+ str->appendInt8(0);
+ DWORD DataLen = str->length();
+ char *pb = (char*)(str->ptr());
+ WCHAR *UnicodeString = (DataLen >= dwUniBuf) ? new WCHAR[DataLen] : &wzUniBuf[0];
+
+ if(UnicodeString)
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pb,-1,UnicodeString,DataLen);
+ EmitData(UnicodeString,DataLen*sizeof(WCHAR));
+ if(DataLen >= dwUniBuf) delete [] UnicodeString;
+ }
+ else report->error("\nOut of memory!\n");
+ delete str;
+ }
+}
+
+
+
+/**************************************************************************/
+unsigned Assembler::OpcodeLen(Instr* instr)
+{
+ return (m_fStdMapping ? OpcodeInfo[instr->opcode].Len : 3);
+}
+/**************************************************************************/
+void Assembler::EmitOpcode(Instr* instr)
+{
+ if(m_fGeneratePDB &&
+ ((instr->linenum != m_ulLastDebugLine)
+ ||(instr->column != m_ulLastDebugColumn)
+ ||(instr->linenum_end != m_ulLastDebugLineEnd)
+ ||(instr->column_end != m_ulLastDebugColumnEnd)))
+ {
+ if(m_pCurMethod)
+ {
+ LinePC *pLPC = new LinePC;
+ if(pLPC)
+ {
+ pLPC->Line = instr->linenum;
+ pLPC->Column = instr->column;
+ pLPC->LineEnd = instr->linenum_end;
+ pLPC->ColumnEnd = instr->column_end;
+ pLPC->PC = m_CurPC;
+ pLPC->pWriter = instr->pWriter;
+
+ pLPC->pOwnerDocument = instr->pOwnerDocument;
+ if (0xfeefee == instr->linenum &&
+ 0xfeefee == instr->linenum_end &&
+ 0 == instr->column &&
+ 0 == instr->column_end)
+ {
+ pLPC->IsHidden = TRUE;
+ }
+ else
+ {
+ pLPC->IsHidden = FALSE;
+ }
+
+ m_pCurMethod->m_LinePCList.PUSH(pLPC);
+ }
+ else report->error("\nOut of memory!\n");
+ }
+ m_ulLastDebugLine = instr->linenum;
+ m_ulLastDebugColumn = instr->column;
+ m_ulLastDebugLineEnd = instr->linenum_end;
+ m_ulLastDebugColumnEnd = instr->column_end;
+ }
+ if(instr->opcode == CEE_ENDFILTER)
+ {
+ if(m_pCurMethod)
+ {
+ if(m_pCurMethod->m_dwNumEndfilters >= m_pCurMethod->m_dwMaxNumEndfilters)
+ {
+ DWORD *pdw = new DWORD[m_pCurMethod->m_dwMaxNumEndfilters+MAX_EXCEPTIONS];
+ if(pdw == NULL)
+ {
+ report->error("Failed to reallocate auxiliary SEH buffer\n");
+ instr->opcode = -1;
+ return;
+ }
+ memcpy(pdw,m_pCurMethod->m_EndfilterOffsetList,m_pCurMethod->m_dwNumEndfilters*sizeof(DWORD));
+ delete m_pCurMethod->m_EndfilterOffsetList;
+ m_pCurMethod->m_EndfilterOffsetList = pdw;
+ m_pCurMethod->m_dwMaxNumEndfilters += MAX_EXCEPTIONS;
+ }
+ m_pCurMethod->m_EndfilterOffsetList[m_pCurMethod->m_dwNumEndfilters++] = m_CurPC+2;
+ }
+ }
+ if (m_fStdMapping)
+ {
+ if (OpcodeInfo[instr->opcode].Len == 2)
+ EmitByte(OpcodeInfo[instr->opcode].Std1);
+ EmitByte(OpcodeInfo[instr->opcode].Std2);
+ }
+ else
+ {
+ unsigned short us = (unsigned short)instr->opcode;
+ EmitByte(REFPRE);
+ EmitBytes((BYTE *)&us,2);
+ }
+ instr->opcode = -1;
+}
+
+/**************************************************************************/
+//void Assembler::OptimizeInstr(Instr* instr, int var)
+//{
+
+//}
+/**************************************************************************/
+unsigned Assembler::ShortOf(unsigned opcode)
+{
+ unsigned retcode;
+ switch(opcode)
+ {
+ case CEE_LDARG: retcode=CEE_LDARG_S; break;
+ case CEE_LDARGA: retcode=CEE_LDARGA_S; break;
+ case CEE_STARG: retcode=CEE_STARG_S; break;
+
+ case CEE_LDLOC: retcode=CEE_LDLOC_S; break;
+ case CEE_LDLOCA: retcode=CEE_LDLOCA_S; break;
+ case CEE_STLOC: retcode=CEE_STLOC_S; break;
+
+ case CEE_BR: retcode=CEE_BR_S; break;
+ case CEE_BRFALSE: retcode=CEE_BRFALSE_S; break;
+ case CEE_BRTRUE: retcode=CEE_BRTRUE_S; break;
+ case CEE_BEQ: retcode=CEE_BEQ_S; break;
+ case CEE_BGE: retcode=CEE_BGE_S; break;
+ case CEE_BGT: retcode=CEE_BGT_S; break;
+ case CEE_BLE: retcode=CEE_BLE_S; break;
+ case CEE_BLT: retcode=CEE_BLT_S; break;
+ case CEE_BNE_UN: retcode=CEE_BNE_UN_S; break;
+ case CEE_BGE_UN: retcode=CEE_BGE_UN_S; break;
+ case CEE_BGT_UN: retcode=CEE_BGT_UN_S; break;
+ case CEE_BLE_UN: retcode=CEE_BLE_UN_S; break;
+ case CEE_BLT_UN: retcode=CEE_BLT_UN_S; break;
+ case CEE_LEAVE: retcode=CEE_LEAVE_S; break;
+
+ case CEE_LDC_I4: retcode=CEE_LDC_I4_S; break;
+ case CEE_LDC_R8: retcode=CEE_LDC_R4; break;
+
+
+ default: retcode = opcode; break;
+ }
+ return retcode;
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrVar(Instr* instr, int var)
+{
+ unsigned opc = instr->opcode;
+ if(m_fOptimize)
+ {
+ if(var < 4)
+ {
+ switch(opc)
+ {
+ case CEE_LDARG:
+ case CEE_LDARG_S: opc = CEE_LDARG_0 + var; break;
+
+ case CEE_LDLOC:
+ case CEE_LDLOC_S: opc = CEE_LDLOC_0 + var; break;
+
+ case CEE_STLOC:
+ case CEE_STLOC_S: opc = CEE_STLOC_0 + var; break;
+
+ default: break;
+ }
+ if(opc != (unsigned) instr->opcode)
+ {
+ instr->opcode = opc;
+ EmitOpcode(instr);
+ return;
+ }
+ }
+ if(var <= 0xFF)
+ {
+ opc = instr->opcode = ShortOf(opc);
+ }
+ }
+ EmitOpcode(instr);
+ if (isShort(opc))
+ {
+ EmitByte(var);
+ }
+ else
+ {
+ short sh = (short)var;
+ EmitBytes((BYTE *)&sh,2);
+ }
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrVarByName(Instr* instr, __in __nullterminated char* label)
+{
+ int idx = -1, nArgVarFlag=0;
+ switch(instr->opcode)
+ {
+ case CEE_LDARGA:
+ case CEE_LDARGA_S:
+ case CEE_LDARG:
+ case CEE_LDARG_S:
+ case CEE_STARG:
+ case CEE_STARG_S:
+ nArgVarFlag++;
+ FALLTHROUGH;
+ case CEE_LDLOCA:
+ case CEE_LDLOCA_S:
+ case CEE_LDLOC:
+ case CEE_LDLOC_S:
+ case CEE_STLOC:
+ case CEE_STLOC_S:
+
+ if(m_pCurMethod)
+ {
+ DWORD L = (DWORD)strlen(label);
+ if(nArgVarFlag == 1)
+ {
+ idx = m_pCurMethod->findArgNum(m_pCurMethod->m_firstArgName,label,L);
+ }
+ else
+ {
+ for(Scope* pSC = m_pCurMethod->m_pCurrScope; pSC; pSC=pSC->pSuperScope)
+ {
+ idx = m_pCurMethod->findLocSlot(pSC->pLocals,label,L);
+ if(idx >= 0) break;
+ }
+ }
+ if(idx >= 0) EmitInstrVar(instr,
+ ((nArgVarFlag==0)||(m_pCurMethod->m_Attr & mdStatic))? idx : idx+1);
+ else report->error("Undeclared identifier %s\n",label);
+ }
+ else
+ report->error("Instructions can be used only when in a method scope\n");
+ break;
+ default:
+ report->error("Named argument illegal for this instruction\n");
+ }
+ instr->opcode = -1; // in case we got here with error
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrI(Instr* instr, int val)
+{
+ int opc = instr->opcode;
+ if(m_fOptimize)
+ {
+ if((val >= -1)&&(val <= 8))
+ {
+ switch(opc)
+ {
+ case CEE_LDC_I4:
+ case CEE_LDC_I4_S: opc = CEE_LDC_I4_M1 + (val+1); break;
+
+ default: break;
+ }
+ if(opc != instr->opcode)
+ {
+ instr->opcode = opc;
+ EmitOpcode(instr);
+ return;
+ }
+ }
+ if((-128 <= val)&&(val <= 127))
+ {
+ opc = instr->opcode = ShortOf(opc);
+ }
+ }
+ EmitOpcode(instr);
+ if (isShort(opc))
+ {
+ EmitByte(val);
+ }
+ else
+ {
+ int i = val;
+ EmitBytes((BYTE *)&i,sizeof(int));
+ }
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrI8(Instr* instr, __int64* val)
+{
+ EmitOpcode(instr);
+ EmitBytes((BYTE *)val, sizeof(__int64));
+ delete val;
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrR(Instr* instr, double* pval)
+{
+ unsigned opc = instr->opcode;
+ EmitOpcode(instr);
+ if (isShort(opc))
+ {
+ float val = (float)*pval;
+ EmitBytes((BYTE *)&val, sizeof(float));
+ }
+ else
+ EmitBytes((BYTE *)pval, sizeof(double));
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrBrTarget(Instr* instr, __in __nullterminated char* label)
+{
+ Label * pLabel = m_pCurMethod->FindLabel(label);
+ int offset=0;
+ if (pLabel == NULL) // branching forward -- no optimization
+ {
+ int pcrelsize = 1+(isShort(instr->opcode) ? 1 : 4); //size of the instruction plus argument
+ AddDeferredFixup(label, m_pCurOutputPos+1,
+ (m_CurPC + pcrelsize), pcrelsize-1);
+ }
+ else
+ {
+ offset = pLabel->m_PC - m_CurPC;
+ if(m_fOptimize)
+ {
+ if((-128 <= offset-5)&&(offset-2 <= 127)) //need to take into account the argument size (worst cases)
+ {
+ instr->opcode = ShortOf(instr->opcode);
+ }
+ }
+ if(isShort(instr->opcode))
+ {
+ offset -= 2;
+ if((-128 > offset)||(offset > 127))
+ report->error("Offset too large for short branching instruction, truncated\n");
+ }
+ else
+ offset -= 5;
+ delete [] label;
+ }
+ int opc = instr->opcode;
+ EmitOpcode(instr);
+ if(isShort(opc)) EmitByte(offset);
+ else EmitBytes((BYTE *)&offset,4);
+}
+/**************************************************************************/
+void Assembler::AddDeferredFixup(__in __nullterminated char *pszLabel, BYTE *pBytes, DWORD RelativeToPC, BYTE FixupSize)
+{
+ Fixup *pNew = new Fixup(pszLabel, pBytes, RelativeToPC, FixupSize);
+
+ if (pNew == NULL)
+ {
+ report->error("Failed to allocate deferred fixup\n");
+ m_State = STATE_FAIL;
+ }
+ else
+ m_pCurMethod->m_lstFixup.PUSH(pNew);
+}
+/**************************************************************************/
+void Assembler::EmitInstrBrOffset(Instr* instr, int offset)
+{
+ unsigned opc=instr->opcode;
+ if(m_fOptimize)
+ {
+ if((-128 <= offset)&&(offset <= 127))
+ {
+ opc = instr->opcode = ShortOf(opc);
+ }
+ }
+ EmitOpcode(instr);
+ if(isShort(opc)) EmitByte(offset);
+ else
+ {
+ int i = offset;
+ EmitBytes((BYTE *)&i,4);
+ }
+}
+
+/**************************************************************************/
+mdToken Assembler::MakeMemberRef(mdToken cr, __in __nullterminated char* pszMemberName, BinStr* sig)
+{
+ DWORD cSig = sig->length();
+ COR_SIGNATURE* mySig = (COR_SIGNATURE *)(sig->ptr());
+ mdToken mr = mdMemberRefNil;
+ Class* pClass = NULL;
+ if(cr == 0x00000001) cr = mdTokenNil; // Module -> nil for globals
+ if(TypeFromToken(cr) == mdtTypeDef) pClass = m_lstClass.PEEK(RidFromToken(cr)-1);
+ if((TypeFromToken(cr) == mdtTypeDef)||(cr == mdTokenNil))
+ {
+ MemberRefDescriptor* pMRD = new MemberRefDescriptor;
+ if(pMRD)
+ {
+ pMRD->m_tdClass = cr;
+ pMRD->m_pClass = pClass;
+ pMRD->m_szName = pszMemberName;
+ pMRD->m_dwName = (DWORD)strlen(pszMemberName);
+ pMRD->m_pSigBinStr = sig;
+ pMRD->m_tkResolved = 0;
+ if(*(sig->ptr())== IMAGE_CEE_CS_CALLCONV_FIELD)
+ {
+ m_LocalFieldRefDList.PUSH(pMRD);
+ mr = 0x98000000 | m_LocalFieldRefDList.COUNT();
+ }
+ else
+ {
+ m_LocalMethodRefDList.PUSH(pMRD);
+ mr = 0x99000000 | m_LocalMethodRefDList.COUNT();
+ }
+ }
+ else
+ {
+ report->error("Failed to allocate MemberRef Descriptor\n");
+ return 0;
+ }
+ }
+ else
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pszMemberName,-1,wzUniBuf,dwUniBuf);
+
+ if(cr == mdTokenNil) cr = mdTypeRefNil;
+ if(TypeFromToken(cr) == mdtAssemblyRef)
+ {
+ report->error("Cross-assembly global references are not supported ('%s')\n", pszMemberName);
+ mr = 0;
+ }
+ else
+ {
+ HRESULT hr = m_pEmitter->DefineMemberRef(cr, wzUniBuf, mySig, cSig, &mr);
+ if(FAILED(hr))
+ {
+ report->error("Unable to define member reference '%s'\n", pszMemberName);
+ mr = 0;
+ }
+ }
+ //if(m_fOBJ) m_pCurMethod->m_TRDList.PUSH(new TokenRelocDescr(m_CurPC,mr));
+ delete [] pszMemberName;
+ delete sig;
+ }
+ return mr;
+}
+/**************************************************************************/
+void Assembler::SetMemberRefFixup(mdToken tk, unsigned opcode_len)
+{
+ if(opcode_len)
+ {
+ switch(TypeFromToken(tk))
+ {
+ case 0x98000000:
+ case 0x99000000:
+ case 0x9A000000:
+ if(m_pCurMethod != NULL)
+ m_pCurMethod->m_LocalMemberRefFixupList.PUSH(
+ new LocalMemberRefFixup(tk,(size_t)(m_CurPC + opcode_len)));
+ break;
+ }
+ }
+}
+
+/**************************************************************************/
+mdToken Assembler::MakeMethodSpec(mdToken tkParent, BinStr* sig)
+{
+ DWORD cSig = sig->length();
+ COR_SIGNATURE* mySig = (COR_SIGNATURE *)(sig->ptr());
+ mdMethodSpec mi = mdMethodSpecNil;
+ if(TypeFromToken(tkParent) == 0x99000000) // Local MemberRef: postpone until resolved
+ {
+ MemberRefDescriptor* pMRD = new MemberRefDescriptor;
+ if(pMRD)
+ {
+ memset(pMRD,0,sizeof(MemberRefDescriptor));
+ pMRD->m_tdClass = tkParent;
+ pMRD->m_pSigBinStr = sig;
+ m_MethodSpecList.PUSH(pMRD);
+ mi = 0x9A000000 | m_MethodSpecList.COUNT();
+ }
+ else
+ {
+ report->error("Failed to allocate MemberRef Descriptor\n");
+ return 0;
+ }
+ }
+ else
+ {
+ HRESULT hr = m_pEmitter->DefineMethodSpec(tkParent, mySig, cSig, &mi);
+ if(FAILED(hr))
+ {
+ report->error("Unable to define method instantiation");
+ return 0;
+ }
+ }
+ return mi;
+}
+
+/**************************************************************************/
+void Assembler::EndEvent(void)
+{
+ Class* pClass = (m_pCurClass ? m_pCurClass : m_pModuleClass);
+ if(m_pCurEvent->m_tkAddOn == 0)
+ report->error("Event %s of class %s has no Add method. Event not emitted.",
+ m_pCurEvent->m_szName,pClass->m_szFQN);
+ else if(m_pCurEvent->m_tkRemoveOn == 0)
+ report->error("Event %s of class %s has no Remove method. Event not emitted.",
+ m_pCurEvent->m_szName,pClass->m_szFQN);
+ else
+ {
+ pClass->m_EventDList.PUSH(m_pCurEvent);
+ pClass->m_fNewMembers = TRUE;
+ }
+ m_pCurEvent = NULL;
+ m_tkCurrentCVOwner = 0;
+ m_pCustomDescrList = m_CustomDescrListStack.POP();
+}
+
+void Assembler::ResetEvent(__inout_z __inout char* szName, mdToken typeSpec, DWORD dwAttr)
+{
+ if(strlen(szName) >= MAX_CLASSNAME_LENGTH)
+ {
+ char c = szName[MAX_CLASSNAME_LENGTH-1];
+ szName[MAX_CLASSNAME_LENGTH-1] = 0;
+ report->error("Event '%s...' -- name too long (%d characters).\n",szName,strlen(szName));
+ szName[MAX_CLASSNAME_LENGTH-1] = c;
+ }
+ if((m_pCurEvent = new EventDescriptor))
+ {
+ memset(m_pCurEvent,0,sizeof(EventDescriptor));
+ m_pCurEvent->m_tdClass = m_pCurClass->m_cl;
+ m_pCurEvent->m_szName = szName;
+ m_pCurEvent->m_dwAttr = dwAttr;
+ m_pCurEvent->m_tkEventType = typeSpec;
+ m_pCurEvent->m_fNew = TRUE;
+ m_tkCurrentCVOwner = 0;
+ m_CustomDescrListStack.PUSH(m_pCustomDescrList);
+ m_pCustomDescrList = &(m_pCurEvent->m_CustomDescrList);
+ }
+ else report->error("Failed to allocate Event Descriptor\n");
+}
+
+void Assembler::SetEventMethod(int MethodCode, mdToken tk)
+{
+ switch(MethodCode)
+ {
+ case 0:
+ m_pCurEvent->m_tkAddOn = tk;
+ break;
+ case 1:
+ m_pCurEvent->m_tkRemoveOn = tk;
+ break;
+ case 2:
+ m_pCurEvent->m_tkFire = tk;
+ break;
+ case 3:
+ m_pCurEvent->m_tklOthers.PUSH((mdToken*)(UINT_PTR)tk);
+ break;
+ }
+}
+/**************************************************************************/
+
+void Assembler::EndProp(void)
+{
+ Class* pClass = (m_pCurClass ? m_pCurClass : m_pModuleClass);
+ pClass->m_PropDList.PUSH(m_pCurProp);
+ pClass->m_fNewMembers = TRUE;
+ m_pCurProp = NULL;
+ m_tkCurrentCVOwner = 0;
+ m_pCustomDescrList = m_CustomDescrListStack.POP();
+}
+
+void Assembler::ResetProp(__inout_z __inout char * szName, BinStr* bsType, DWORD dwAttr, BinStr* pValue)
+{
+ DWORD cSig = bsType->length();
+ COR_SIGNATURE* mySig = (COR_SIGNATURE *)(bsType->ptr());
+
+ if(strlen(szName) >= MAX_CLASSNAME_LENGTH)
+ {
+ char c = szName[MAX_CLASSNAME_LENGTH-1];
+ szName[MAX_CLASSNAME_LENGTH-1] = 0;
+ report->error("Property '%s...' -- name too long (%d characters).\n",szName,strlen(szName));
+ szName[MAX_CLASSNAME_LENGTH-1] = c;
+ }
+ m_pCurProp = new PropDescriptor;
+ if(m_pCurProp == NULL)
+ {
+ report->error("Failed to allocate Property Descriptor\n");
+ return;
+ }
+ memset(m_pCurProp,0,sizeof(PropDescriptor));
+ m_pCurProp->m_tdClass = m_pCurClass->m_cl;
+ m_pCurProp->m_szName = szName;
+ m_pCurProp->m_dwAttr = dwAttr;
+ m_pCurProp->m_fNew = TRUE;
+
+ m_pCurProp->m_pSig = new COR_SIGNATURE[cSig];
+ if(m_pCurProp->m_pSig == NULL)
+ {
+ report->error("\nOut of memory!\n");
+ return;
+ }
+ memcpy(m_pCurProp->m_pSig,mySig,cSig);
+ m_pCurProp->m_dwCSig = cSig;
+
+ if(pValue && pValue->length())
+ {
+ BYTE* pch = pValue->ptr();
+ m_pCurProp->m_dwCPlusTypeFlag = (DWORD)(*pch);
+ m_pCurProp->m_cbValue = pValue->length() - 1;
+ m_pCurProp->m_pValue = (PVOID)(pch+1);
+ if(m_pCurProp->m_dwCPlusTypeFlag == ELEMENT_TYPE_STRING) m_pCurProp->m_cbValue /= sizeof(WCHAR);
+ m_pCurProp->m_dwAttr |= prHasDefault;
+ }
+ else
+ {
+ m_pCurProp->m_dwCPlusTypeFlag = ELEMENT_TYPE_VOID;
+ m_pCurProp->m_pValue = NULL;
+ m_pCurProp->m_cbValue = 0;
+ }
+ m_tkCurrentCVOwner = 0;
+ m_CustomDescrListStack.PUSH(m_pCustomDescrList);
+ m_pCustomDescrList = &(m_pCurProp->m_CustomDescrList);
+}
+
+void Assembler::SetPropMethod(int MethodCode, mdToken tk)
+{
+ switch(MethodCode)
+ {
+ case 0:
+ m_pCurProp->m_tkSet = tk;
+ break;
+ case 1:
+ m_pCurProp->m_tkGet = tk;
+ break;
+ case 2:
+ m_pCurProp->m_tklOthers.PUSH((mdToken*)(UINT_PTR)tk);
+ break;
+ }
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL ConvertToUnicode, BOOL Swap /*=FALSE*/)
+{
+ DWORD DataLen = literal->length(),L;
+ unsigned __int8 *pb = literal->ptr();
+ HRESULT hr = S_OK;
+ mdToken tk;
+ WCHAR *UnicodeString;
+ if(DataLen == 0)
+ {
+ //report->warn("Zero length string emitted\n");
+ ConvertToUnicode = FALSE;
+ }
+ if(ConvertToUnicode)
+ {
+ UnicodeString = (DataLen >= dwUniBuf) ? new WCHAR[DataLen+1] : &wzUniBuf[0];
+ literal->appendInt8(0);
+ pb = literal->ptr();
+ // convert string to Unicode
+ L = UnicodeString ? WszMultiByteToWideChar(g_uCodePage,0,(char*)pb,-1,UnicodeString,DataLen+1) : 0;
+ if(L == 0)
+ {
+ const char* sz=NULL;
+ DWORD dw;
+ switch(dw=GetLastError())
+ {
+ case ERROR_INSUFFICIENT_BUFFER: sz = "ERROR_INSUFFICIENT_BUFFER"; break;
+ case ERROR_INVALID_FLAGS: sz = "ERROR_INVALID_FLAGS"; break;
+ case ERROR_INVALID_PARAMETER: sz = "ERROR_INVALID_PARAMETER"; break;
+ case ERROR_NO_UNICODE_TRANSLATION: sz = "ERROR_NO_UNICODE_TRANSLATION"; break;
+ }
+ if(sz) report->error("Failed to convert string '%s' to Unicode: %s\n",(char*)pb,sz);
+ else report->error("Failed to convert string '%s' to Unicode: error 0x%08X\n",(char*)pb,dw);
+ goto OuttaHere;
+ }
+ L--;
+ }
+ else
+ {
+ if(DataLen & 1)
+ {
+ literal->appendInt8(0);
+ pb = literal->ptr();
+ DataLen++;
+ }
+ UnicodeString = (WCHAR*)pb;
+ L = DataLen/sizeof(WCHAR);
+
+#if BIGENDIAN
+ if (Swap)
+ SwapStringLength(UnicodeString, L);
+#endif
+ }
+ // Add the string data to the metadata, which will fold dupes.
+ hr = m_pEmitter->DefineUserString(
+ UnicodeString,
+ L,
+ &tk
+ );
+ if (FAILED(hr))
+ {
+ report->error("Failed to add user string using DefineUserString, hr=0x%08x, data: '%S'\n",
+ hr, UnicodeString);
+ }
+ else
+ {
+ EmitOpcode(instr);
+ if(m_fOBJ) m_pCurMethod->m_TRDList.PUSH(new TokenRelocDescr(m_CurPC,tk));
+
+ EmitBytes((BYTE *)&tk,sizeof(mdToken));
+ }
+OuttaHere:
+ delete literal;
+ if(((void*)UnicodeString != (void*)pb)&&(DataLen >= dwUniBuf)) delete [] UnicodeString;
+ instr->opcode = -1; // in case we got here with error
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrSig(Instr* instr, BinStr* sig)
+{
+ mdSignature MetadataToken;
+ DWORD cSig = sig->length();
+ COR_SIGNATURE* mySig = (COR_SIGNATURE *)(sig->ptr());
+
+ if (FAILED(m_pEmitter->GetTokenFromSig(mySig, cSig, &MetadataToken)))
+ {
+ report->error("Unable to convert signature to metadata token.\n");
+ }
+ else
+ {
+ EmitOpcode(instr);
+ if(m_fOBJ) m_pCurMethod->m_TRDList.PUSH(new TokenRelocDescr(m_CurPC,MetadataToken));
+ EmitBytes((BYTE *)&MetadataToken, sizeof(mdSignature));
+ }
+ delete sig;
+ instr->opcode = -1; // in case we got here with error
+}
+
+/**************************************************************************/
+void Assembler::EmitInstrSwitch(Instr* instr, Labels* targets)
+{
+ Labels *pLbls;
+ int NumLabels;
+ Label *pLabel;
+ UINT offset;
+
+ EmitOpcode(instr);
+
+ // count # labels
+ for(pLbls = targets, NumLabels = 0; pLbls; pLbls = pLbls->Next, NumLabels++);
+
+ EmitBytes((BYTE *)&NumLabels,sizeof(int));
+ DWORD PC_nextInstr = m_CurPC + 4*NumLabels;
+ for(pLbls = targets; pLbls; pLbls = pLbls->Next)
+ {
+ if(pLbls->isLabel)
+ {
+ if((pLabel = m_pCurMethod->FindLabel(pLbls->Label)))
+ {
+ offset = pLabel->m_PC - PC_nextInstr;
+ if (m_fDisplayTraceOutput) report->msg("%d\n", offset);
+ }
+ else
+ {
+ // defer until we find the label
+ AddDeferredFixup(pLbls->Label, m_pCurOutputPos, PC_nextInstr, 4 /* pcrelsize */ );
+ offset = 0;
+ pLbls->Label = NULL;
+ if (m_fDisplayTraceOutput) report->msg("forward label %s\n", pLbls->Label);
+ }
+ }
+ else
+ {
+ offset = (UINT)(UINT_PTR)pLbls->Label;
+ if (m_fDisplayTraceOutput) report->msg("%d\n", offset);
+ }
+ EmitBytes((BYTE *)&offset, sizeof(UINT));
+ }
+ delete targets;
+}
+
+/**************************************************************************/
+void Assembler::EmitLabel(__in __nullterminated char* label)
+{
+ _ASSERTE(m_pCurMethod);
+ AddLabel(m_CurPC, label);
+}
+/**************************************************************************/
+void Assembler::EmitDataLabel(__in __nullterminated char* label)
+{
+ AddGlobalLabel(label, m_pCurSection);
+}
+
+/**************************************************************************/
+void Assembler::EmitBytes(BYTE *p, unsigned len)
+{
+ if(m_pCurOutputPos + len >= m_pEndOutputPos)
+ {
+ size_t buflen = m_pEndOutputPos - m_pOutputBuffer;
+ size_t newlen = buflen+(len/OUTPUT_BUFFER_INCREMENT + 1)*OUTPUT_BUFFER_INCREMENT;
+ BYTE *pb = new BYTE[newlen];
+ if(pb == NULL)
+ {
+ report->error("Failed to extend output buffer from %d to %d bytes. Aborting\n",
+ buflen, newlen);
+ exit(1);
+ }
+ size_t delta = pb - m_pOutputBuffer;
+ int i;
+ Fixup* pSearch;
+ GlobalFixup *pGSearch;
+ for (i=0; (pSearch = m_pCurMethod->m_lstFixup.PEEK(i)); i++) pSearch->m_pBytes += delta;
+ for (i=0; (pGSearch = m_lstGlobalFixup.PEEK(i)); i++) //need to move only those pointing to output buffer
+ {
+ if((pGSearch->m_pReference >= m_pOutputBuffer)&&(pGSearch->m_pReference <= m_pEndOutputPos))
+ pGSearch->m_pReference += delta;
+ }
+
+
+ memcpy(pb,m_pOutputBuffer,m_CurPC);
+ delete [] m_pOutputBuffer;
+ m_pOutputBuffer = pb;
+ m_pCurOutputPos = &m_pOutputBuffer[m_CurPC];
+ m_pEndOutputPos = &m_pOutputBuffer[newlen];
+
+ }
+
+ switch (len)
+ {
+ case 1:
+ *m_pCurOutputPos = *p;
+ break;
+ case 2:
+ SET_UNALIGNED_VAL16(m_pCurOutputPos, GET_UNALIGNED_16(p));
+ break;
+ case 4:
+ SET_UNALIGNED_VAL32(m_pCurOutputPos, GET_UNALIGNED_32(p));
+ break;
+ case 8:
+ SET_UNALIGNED_VAL64(m_pCurOutputPos, GET_UNALIGNED_64(p));
+ break;
+ default:
+ _ASSERTE(!"NYI");
+ break;
+ }
+
+ m_pCurOutputPos += len;
+ m_CurPC += len;
+}
+/**************************************************************************/
+BinStr* Assembler::EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps)
+{
+ unsigned cnt;
+
+ // build the blob As BinStr
+ unsigned L = (unsigned) strlen(szReflName);
+ BYTE* pb = NULL;
+ BinStr* pbsRet = new BinStr();
+ // encode the Reflection name length
+ cnt = CorSigCompressData(L, pbsRet->getBuff(5));
+ pbsRet->remove(5 - cnt);
+ //put the name in
+ if((pb = pbsRet->getBuff(L)) != NULL)
+ memcpy(pb,szReflName,L);
+ // find out the size of compressed nProps
+ cnt = CorSigCompressData(nProps, pbsRet->getBuff(5));
+ pbsRet->remove(5);
+ // encode blob size
+ unsigned nSize = cnt + pbsSecAttrBlob->length();
+ cnt = CorSigCompressData(nSize, pbsRet->getBuff(5));
+ pbsRet->remove(5 - cnt);
+ // actually encode nProps
+ cnt = CorSigCompressData(nProps, pbsRet->getBuff(5));
+ pbsRet->remove(5 - cnt);
+ // append the props/values blob
+ pbsRet->append(pbsSecAttrBlob);
+ delete pbsSecAttrBlob;
+ return pbsRet;
+}
+/**************************************************************************/
+void Assembler::EmitSecurityInfo(mdToken token,
+ PermissionDecl* pPermissions,
+ PermissionSetDecl* pPermissionSets)
+{
+ PermissionDecl *pPerm, *pPermNext;
+ PermissionSetDecl *pPset, *pPsetNext;
+ unsigned uCount = 0;
+ COR_SECATTR *pAttrs;
+ unsigned i;
+ unsigned uLength;
+ mdTypeRef tkTypeRef;
+ BinStr *pSig;
+ char *szMemberName;
+ DWORD dwErrorIndex = 0;
+
+ if (pPermissions) {
+
+ for (pPerm = pPermissions; pPerm; pPerm = pPerm->m_Next)
+ uCount++;
+
+ _ASSERTE(uCount > 0);
+ // uCount is expected to be positive all the time. The if statement is here to please prefast.
+ if (uCount > 0)
+ {
+ if((pAttrs = new COR_SECATTR[uCount])==NULL)
+ {
+ report->error("\nOut of memory!\n");
+ return;
+ }
+
+ mdToken tkMscorlib = m_fIsMscorlib ? 1 : GetAsmRef("mscorlib");
+ tkTypeRef = ResolveClassRef(tkMscorlib,"System.Security.Permissions.SecurityAction", NULL);
+ for (pPerm = pPermissions, i = 0; pPerm; pPerm = pPermNext, i++) {
+ pPermNext = pPerm->m_Next;
+
+ pSig = new BinStr();
+ pSig->appendInt8(IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS);
+ pSig->appendInt8(1);
+ pSig->appendInt8(ELEMENT_TYPE_VOID);
+ pSig->appendInt8(ELEMENT_TYPE_VALUETYPE);
+ uLength = CorSigCompressToken(tkTypeRef, pSig->getBuff(5));
+ pSig->remove(5 - uLength);
+
+ uLength = (unsigned)strlen(COR_CTOR_METHOD_NAME) + 1;
+ if((szMemberName = new char[uLength]))
+ {
+ memcpy(szMemberName, COR_CTOR_METHOD_NAME, uLength);
+ pAttrs[i].tkCtor = MakeMemberRef(pPerm->m_TypeSpec, szMemberName, pSig);
+ pAttrs[i].pCustomAttribute = (const void *)pPerm->m_Blob;
+ pAttrs[i].cbCustomAttribute = pPerm->m_BlobLength;
+ }
+ else report->error("\nOut of memory!\n");
+ }
+
+ if (FAILED(m_pEmitter->DefineSecurityAttributeSet(token,
+ pAttrs,
+ uCount,
+ &dwErrorIndex)))
+ {
+ _ASSERT(uCount >= dwErrorIndex);
+ if (dwErrorIndex == uCount)
+ {
+ report->error("Failed to define security attribute set for 0x%08X\n", token);
+ }
+ else
+ {
+ report->error("Failed to define security attribute set for 0x%08X\n (error in permission %u)\n",
+ token, uCount - dwErrorIndex);
+ }
+ }
+ delete [] pAttrs;
+ for (pPerm = pPermissions, i = 0; pPerm; pPerm = pPermNext, i++) {
+ pPermNext = pPerm->m_Next;
+ delete pPerm;
+ }
+ }
+ }
+
+ for (pPset = pPermissionSets; pPset; pPset = pPsetNext) {
+ pPsetNext = pPset->m_Next;
+ if(FAILED(m_pEmitter->DefinePermissionSet(token,
+ pPset->m_Action,
+ pPset->m_Value->ptr(),
+ pPset->m_Value->length(),
+ NULL)))
+ report->error("Failed to define security permission set for 0x%08X\n", token);
+ delete pPset;
+ }
+}
+
+void Assembler::AddMethodImpl(mdToken tkImplementedTypeSpec, __in __nullterminated char* szImplementedName, BinStr* pImplementedSig,
+ mdToken tkImplementingTypeSpec, __in_opt __nullterminated char* szImplementingName, BinStr* pImplementingSig)
+{
+ if(m_pCurClass)
+ {
+ MethodImplDescriptor* pMID = new MethodImplDescriptor;
+ if(pMID == NULL)
+ {
+ report->error("Failed to allocate MethodImpl Descriptor\n");
+ return;
+ }
+ pMID->m_fNew = TRUE;
+ pMID->m_tkDefiningClass = m_pCurClass->m_cl;
+ if(szImplementingName) //called from class scope, overriding method specified
+ {
+ pMID->m_tkImplementedMethod = MakeMemberRef(tkImplementedTypeSpec,szImplementedName,pImplementedSig);
+ pMID->m_tkImplementingMethod = MakeMemberRef(tkImplementingTypeSpec,szImplementingName,pImplementingSig);
+ }
+ else //called from method scope, use current method as overriding
+ {
+ if(m_pCurMethod)
+ {
+ if (pImplementedSig == NULL)
+ {
+ pImplementedSig = new BinStr();
+ memcpy(pImplementedSig->getBuff(m_pCurMethod->m_dwMethodCSig), m_pCurMethod->m_pMethodSig,m_pCurMethod->m_dwMethodCSig);
+ }
+ pMID->m_tkImplementedMethod = MakeMemberRef(tkImplementedTypeSpec,szImplementedName,pImplementedSig);
+ pMID->m_tkImplementingMethod = 0;
+
+ m_pCurMethod->m_MethodImplDList.PUSH(pMID); // copy goes to method's own list (ptr only)
+ }
+ else
+ {
+ report->error("No overriding method specified");
+ delete pMID;
+ return;
+ }
+ }
+ m_MethodImplDList.PUSH(pMID);
+ }
+ else
+ report->error(".override directive outside class scope");
+}
+// source file name paraphernalia
+void Assembler::SetSourceFileName(__in __nullterminated char* szName)
+{
+ if(szName)
+ {
+ if(*szName)
+ {
+ if(strcmp(m_szSourceFileName,szName))
+ {
+ strcpy_s(m_szSourceFileName,MAX_FILENAME_LENGTH*3+1,szName);
+ WszMultiByteToWideChar(g_uCodePage,0,szName,-1,m_wzSourceFileName,MAX_FILENAME_LENGTH);
+ }
+ if(m_fGeneratePDB)
+ {
+ if (IsPortablePdb())
+ {
+ if (FAILED(m_pPortablePdbWriter->DefineDocument(szName, &m_guidLang)))
+ {
+ report->error("Failed to define a document: '%s'", szName);
+ }
+ delete[] szName;
+ }
+ else
+ {
+ DocWriter* pDW;
+ unsigned i = 0;
+ while ((pDW = m_DocWriterList.PEEK(i++)) != NULL)
+ {
+ if (!strcmp(szName, pDW->Name)) break;
+ }
+ if (pDW)
+ {
+ m_pSymDocument = pDW->pWriter;
+ delete[] szName;
+ }
+ else if (m_pSymWriter)
+ {
+ HRESULT hr;
+ WszMultiByteToWideChar(g_uCodePage, 0, szName, -1, wzUniBuf, dwUniBuf);
+ if (FAILED(hr = m_pSymWriter->DefineDocument(wzUniBuf, &m_guidLang,
+ &m_guidLangVendor, &m_guidDoc, &m_pSymDocument)))
+ {
+ m_pSymDocument = NULL;
+ report->error("Failed to define a document writer");
+ }
+ if ((pDW = new DocWriter()) != NULL)
+ {
+ pDW->Name = szName;
+ pDW->pWriter = m_pSymDocument;
+ m_DocWriterList.PUSH(pDW);
+ }
+ else
+ {
+ report->error("Out of memory");
+ delete[] szName;
+ }
+ }
+ else delete[] szName;
+ }
+ }
+ else delete [] szName;
+ }
+ else delete [] szName;
+ }
+}
+void Assembler::SetSourceFileName(BinStr* pbsName)
+{
+ ULONG L;
+ if(pbsName && (L = (ULONG)(pbsName->length())))
+ {
+ pbsName->appendInt8(0);
+ char* sz = new char[L+1];
+ memcpy(sz,pbsName->ptr(),L+1);
+ SetSourceFileName(sz);
+ delete pbsName;
+ }
+}
+
+// Portable PDB paraphernalia
+void Assembler::SetPdbFileName(__in __nullterminated char* szName)
+{
+ if (szName)
+ {
+ if (*szName)
+ {
+ strcpy_s(m_szPdbFileName, MAX_FILENAME_LENGTH * 3 + 1, szName);
+ WszMultiByteToWideChar(g_uCodePage, 0, szName, -1, m_wzPdbFileName, MAX_FILENAME_LENGTH);
+ }
+ }
+}
+HRESULT Assembler::SavePdbFile()
+{
+ HRESULT hr = S_OK;
+ mdMethodDef entryPoint;
+
+ if (m_pdbFormat == PORTABLE)
+ {
+ if (FAILED(hr = (m_pPortablePdbWriter == NULL ? E_FAIL : S_OK))) goto exit;
+ if (FAILED(hr = (m_pPortablePdbWriter->GetEmitter() == NULL ? E_FAIL : S_OK))) goto exit;
+ if (FAILED(hr = m_pCeeFileGen->GetEntryPoint(m_pCeeFile, &entryPoint))) goto exit;
+ if (FAILED(hr = m_pPortablePdbWriter->BuildPdbStream(m_pEmitter, entryPoint))) goto exit;
+ if (FAILED(hr = m_pPortablePdbWriter->GetEmitter()->Save(m_wzPdbFileName, NULL))) goto exit;
+ }
+exit:
+ return hr;
+}
+BOOL Assembler::IsPortablePdb()
+{
+ return (m_pdbFormat == PORTABLE) && (m_pPortablePdbWriter != NULL);
+}
+
+// This method is called after we have parsed the generic type parameters for either
+// a generic class or a generic method. It calls CheckAddGenericParamConstraint on
+// each generic parameter constraint that was recorded.
+//
+void Assembler::RecordTypeConstraints(GenericParamConstraintList* pGPCList, int numTyPars, TyParDescr* tyPars)
+{
+ if (numTyPars > 0)
+ {
+ for (int i = 0; i < numTyPars; i++)
+ {
+ // Decode any type constraints held by tyPars[i].Bounds()
+ BinStr* typeConstraints = tyPars[i].Bounds();
+ _ASSERTE((typeConstraints->length() % 4) == 0);
+ int numConstraints = (typeConstraints->length() / 4) - 1;
+ if (numConstraints > 0)
+ {
+ mdToken* ptk = (mdToken*)typeConstraints->ptr();
+ for (int j = 0; j < numConstraints; j++)
+ {
+ mdToken tkTypeConstraint = ptk[j];
+
+ // pass false for isParamDirective, these constraints are from the class or method definition
+ //
+ CheckAddGenericParamConstraint(pGPCList, i, tkTypeConstraint, false);
+ }
+ }
+ }
+ }
+}
+
+// AddGenericParamConstraint is called when we have a .param constraint directive after a class definition
+//
+void Assembler::AddGenericParamConstraint(int index, char * pStrGenericParam, mdToken tkTypeConstraint)
+{
+ if (!m_pCurClass)
+ {
+ report->error(".parm constraint directive outside class scope");
+ return;
+ }
+ if (index > 0)
+ {
+ if (pStrGenericParam != 0)
+ {
+ report->error("LOGIC ERROR - we have both an index and a pStrGenericParam");
+ return;
+ }
+ if (index > (int)m_pCurClass->m_NumTyPars)
+ {
+ report->error("Type parameter index out of range\n");
+ return;
+ }
+ index = index - 1;
+ }
+ else // index was 0, so a name must be supplied by pStrGenericParam
+ {
+ if (pStrGenericParam == 0)
+ {
+ report->error("LOGIC ERROR - we have neither an index or a pStrGenericParam");
+ return;
+ }
+ index = m_pCurClass->FindTyPar(pStrGenericParam);
+ if (index == -1)
+ {
+ report->error("Type parameter '%s' undefined\n", pStrGenericParam);
+ return;
+ }
+ }
+
+ // pass true for isParamDirective, we are parsing a .param directive for a class here
+ //
+ CheckAddGenericParamConstraint(&m_pCurClass->m_GPCList, index, tkTypeConstraint, true);
+}
+
+// CheckAddGenericParamConstraint is called when we have to handle a generic parameter constraint
+// When parsing a generic class/method definition isParamDirective is false - we have a generic type constaint
+// for this case we do not setup m_pCustomDescrList as a .custom after a generic class/method definition is
+// for the class/method
+// When isParamDirective is true, we have a .param constraint directive and we will setup m_pCustomDescrList
+// and any subsequent .custom is for the generic parameter constrant
+//
+void Assembler::CheckAddGenericParamConstraint(GenericParamConstraintList* pGPCList, int index, mdToken tkTypeConstraint, bool isParamDirective)
+{
+ _ASSERTE(tkTypeConstraint != 0);
+ _ASSERTE(index >= 0);
+
+ // Look for an existing match in m_pCurClass->m_GPCList
+ //
+ // Iterate the GenericParamConstraints list
+ //
+ bool match = false;
+ GenericParamConstraintDescriptor *pGPC = nullptr;
+ for (int listIndex = 0; (pGPC = pGPCList->PEEK(listIndex)) != nullptr; listIndex++)
+ {
+ int curParamIndex = pGPC->GetParamIndex();
+ if (curParamIndex == index)
+ {
+ mdToken curTypeConstraint = pGPC->GetTypeConstraint();
+ if (curTypeConstraint == tkTypeConstraint)
+ {
+ match = true;
+ break;
+ }
+ }
+ }
+
+ if (match)
+ {
+ // Found an existing generic parameter constraint
+ //
+ if (isParamDirective)
+ {
+ // Setup the custom descr list so that we can record
+ // custom attributes on this generic param contraint
+ //
+ m_pCustomDescrList = pGPC->CAList();
+ }
+ }
+ else
+ {
+ // not found - add it to our pGPCList
+ //
+ GenericParamConstraintDescriptor* pNewGPCDescr = new GenericParamConstraintDescriptor();
+ pNewGPCDescr->Init(index, tkTypeConstraint);
+ pGPCList->PUSH(pNewGPCDescr);
+ if (isParamDirective)
+ {
+ // Setup the custom descr list so that we can record
+ // custom attributes on this generic param contraint
+ //
+ m_pCustomDescrList = pNewGPCDescr->CAList();
+ }
+ }
+}
+
+// Emit the proper metadata for the generic parameter type constraints
+// This will create one GenericParamConstraint tokens for each type constraint.
+// Finally associate any custom attributes with their GenericParamConstraint
+// and emit them as well
+//
+void Assembler::EmitGenericParamConstraints(int numTyPars, TyParDescr* pTyPars, mdToken tkOwner, GenericParamConstraintList* pGPCL)
+{
+ // If we haver no generic parameters, or a null or empty list of generic param constraints
+ // then we can early out and just return.
+ //
+ if ((numTyPars == 0) || (pGPCL == NULL) || (pGPCL->COUNT() == 0))
+ {
+ return;
+ }
+
+ int* nConstraintsArr = new int[numTyPars];
+ int* nConstraintIndexArr = new int[numTyPars];
+ mdToken** pConstraintsArr = new mdToken*[numTyPars];
+ mdGenericParamConstraint** pGPConstraintsArr = new mdToken*[numTyPars];
+
+ // Zero initialize the arrays that we just created
+ int paramIndex;
+ for (paramIndex = 0; paramIndex < numTyPars; paramIndex++)
+ {
+ nConstraintsArr[paramIndex] = 0;
+ nConstraintIndexArr[paramIndex] = 0;
+ pConstraintsArr[paramIndex] = nullptr;
+ pGPConstraintsArr[paramIndex] = nullptr;
+ }
+
+ // Set all the owner tokens and calculate the number of constraints for each type parameter
+ GenericParamConstraintDescriptor *pGPC;
+ int listIndex;
+ for (listIndex = 0; (pGPC = pGPCL->PEEK(listIndex)) != nullptr; listIndex++)
+ {
+ pGPC->SetOwner(tkOwner);
+ paramIndex = pGPC->GetParamIndex();
+ nConstraintsArr[paramIndex]++;
+ }
+
+ // Allocate an appropriately sized array of type constraints for each generic type param
+ // If the generic type param has no type constraints we will just leave the value
+ // of pConstraintsArr[paramIndex] (and pGPConstraintsArr[]) as nullptr
+ for (paramIndex = 0; paramIndex < numTyPars; paramIndex++)
+ {
+ // How many constraints are there for this generic parameter?
+ int currNumConstraints = nConstraintsArr[paramIndex];
+ if (currNumConstraints > 0)
+ {
+ // We are required to have an extra mdTokenNil as the last element in the array
+ int currConstraintArraySize = currNumConstraints + 1;
+
+ mdToken* currConstraintsArr = new mdToken[currConstraintArraySize];
+ mdToken* currGPConstraintsArr = new mdToken[currConstraintArraySize];
+
+ // initialize this new array to all mdTokenNil
+ for (int i = 0; i < currConstraintArraySize; i++)
+ {
+ currConstraintsArr[i] = mdTokenNil;
+ currGPConstraintsArr[i] = mdTokenNil;
+ }
+
+ // Assign these empty arrays to the proper elements of pConstraintsArr[] and pConstraintsArr[]
+ pConstraintsArr[paramIndex] = currConstraintsArr;
+ pGPConstraintsArr[paramIndex] = currGPConstraintsArr;
+ }
+ }
+
+ // Iterate the GenericParamConstraints list again and
+ // record the type constraints in the pConstraintsArr[][]
+ for (listIndex = 0; (pGPC = pGPCL->PEEK(listIndex)) != nullptr; listIndex++)
+ {
+ paramIndex = pGPC->GetParamIndex();
+
+ mdToken currTypeConstraint = pGPC->GetTypeConstraint();
+ mdToken* currConstraintArr = pConstraintsArr[paramIndex];
+ _ASSERTE(currConstraintArr != nullptr);
+ int constraintArrayLast = nConstraintsArr[paramIndex];
+ int currConstraintArrIndex = nConstraintIndexArr[paramIndex];
+ _ASSERTE(currConstraintArrIndex < constraintArrayLast);
+
+ currConstraintArr[currConstraintArrIndex++] = currTypeConstraint;
+ _ASSERTE(currConstraintArr[currConstraintArrIndex] == mdTokenNil); // the last element must be mdTokenNil
+ nConstraintIndexArr[paramIndex] = currConstraintArrIndex;
+ }
+
+ // Next emit the metadata for the Generic parameter type constraints
+ //
+ for (paramIndex = 0; paramIndex < numTyPars; paramIndex++)
+ {
+ int currParamNumConstraints = nConstraintIndexArr[paramIndex];
+
+ if (currParamNumConstraints > 0)
+ {
+ mdGenericParam tkGenericParam = pTyPars[paramIndex].Token();
+ DWORD paramAttrs = pTyPars[paramIndex].Attrs();
+ ULONG currNumConstraints = (ULONG) nConstraintsArr[paramIndex];
+ mdToken* currConstraintArr = pConstraintsArr[paramIndex];
+ mdGenericParamConstraint* currGPConstraintArr = pGPConstraintsArr[paramIndex];
+
+ // call SetGenericParamProps for each generic parameter that has a non-zero count of constraints
+ // to record each generic parameters tyupe constraints.
+ //
+ // Pass the paramAttrs, these contain values in CorGenericParamAttr such as:
+ // gpReferenceTypeConstraint = 0x0004, // type argument must be a reference type
+ // gpNotNullableValueTypeConstraint = 0x0008, // type argument must be a value type but not Nullable
+ // gpDefaultConstructorConstraint = 0x0010, // type argument must have a public default constructor
+ //
+ // This Metadata operation will also create a new GenericParamConstraint token
+ // for each of the generic parameters type constraints.
+ //
+ if (FAILED(m_pEmitter->SetGenericParamProps(tkGenericParam, paramAttrs, NULL, 0, currConstraintArr)))
+ {
+ report->error("Failed in SetGenericParamProp");
+ }
+ else
+ {
+ // We now need to fetch the values of the new GenericParamConstraint tokens
+ // that were created by the call to SetGenericParamProps
+ //
+ // These tokens are the token owners for the custom attributes
+ // such as NulableAttribute and TupleElementNamesAttribute
+ //
+ HCORENUM hEnum = NULL;
+ ULONG uCount = 0;
+ if (FAILED(m_pImporter->EnumGenericParamConstraints(&hEnum, tkGenericParam, currGPConstraintArr, (ULONG)currNumConstraints, &uCount)))
+ {
+ report->error("Failed in EnumGenericParamConstraints");
+ }
+ else
+ {
+ _ASSERTE(uCount == currNumConstraints);
+ m_pImporter->CloseEnum(hEnum);
+ }
+ }
+ }
+ }
+
+ // Emit any Custom Attributes associated with these Generic Paaram Constraints
+ //
+ while ((pGPC = pGPCL->POP()))
+ {
+ paramIndex = pGPC->GetParamIndex();
+
+ mdToken tkTypeConstraint = pGPC->GetTypeConstraint();
+ int currNumConstraints = nConstraintsArr[paramIndex];
+ mdToken* currConstraintArr = pConstraintsArr[paramIndex];
+ mdGenericParamConstraint* currGPConstraintArr = pGPConstraintsArr[paramIndex];
+ mdGenericParamConstraint tkOwnerOfCA = mdTokenNil;
+
+ // find the matching type constraint and fetch the GenericParamConstraint
+ //
+ for (int i = 0; i < currNumConstraints; i++)
+ {
+ if (currConstraintArr[i] == tkTypeConstraint)
+ {
+ tkOwnerOfCA = currGPConstraintArr[i];
+ break;
+ }
+ }
+ _ASSERTE(tkOwnerOfCA != mdTokenNil);
+
+ // Record the Generic Param Constraint token
+ // and supply it as the owner for the list of Custom attributes.
+ //
+ pGPC->Token(tkOwnerOfCA);
+ EmitCustomAttributes(tkOwnerOfCA, pGPC->CAList());
+ }
+}
diff --git a/src/coreclr/ilasm/assembler.h b/src/coreclr/ilasm/assembler.h
new file mode 100644
index 00000000000..8f87df66645
--- /dev/null
+++ b/src/coreclr/ilasm/assembler.h
@@ -0,0 +1,1304 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/************************************************************************/
+/* Assembler.h */
+/************************************************************************/
+
+#ifndef Assember_h
+#define Assember_h
+
+#define NEW_INLINE_NAMES
+
+#include "binstr.h"
+
+#include "specstrings.h"
+
+#include "asmenum.h"
+#include "asmtemplates.h"
+
+#include "portable_pdb.h"
+#include "portablepdbmdi.h"
+
+// Disable the "initialization of static local vars is no thread safe" error
+#ifdef _MSC_VER
+#pragma warning(disable : 4640)
+#endif
+
+#ifdef ResetEvent
+#undef ResetEvent
+#endif
+
+#define OUTPUT_BUFFER_SIZE 8192 // initial size of asm code for a single method
+#define OUTPUT_BUFFER_INCREMENT 1024 // size of code buffer increment when it's full
+#define MAX_FILENAME_LENGTH 2048 //256
+#define MAX_SIGNATURE_LENGTH 256 // unused
+#define MAX_LABEL_SIZE 256 //64
+#define MAX_CALL_SIG_SIZE 32 // unused
+#define MAX_SCOPE_LENGTH _MAX_PATH // follow the RegMeta::SetModuleProps limitation
+
+#define MAX_NAMESPACE_LENGTH 1024 //256 //64
+#define MAX_MEMBER_NAME_LENGTH 1024 //256 //64
+
+#define MAX_INTERFACES_IMPLEMENTED 16 // initial number; extended by 16 when needed
+#define GLOBAL_DATA_SIZE 8192 // initial size of global data buffer
+#define GLOBAL_DATA_INCREMENT 1024 // size of global data buffer increment when it's full
+#define MAX_METHODS 1024 // unused
+#define MAX_INPUT_LINE_LEN 1024 // unused
+#define MAX_TYPAR 8
+#define BASE_OBJECT_CLASSNAME "System.Object"
+#define MAX_MANIFEST_RESOURCES 1024
+
+// Fully-qualified class name separators:
+#define NESTING_SEP ((char)0xF8)
+
+#define dwUniBuf 16384
+
+#ifdef TARGET_UNIX
+extern char *g_pszExeFile;
+#endif
+
+extern WCHAR wzUniBuf[]; // Unicode conversion global buffer (assem.cpp)
+
+class Class;
+class Method;
+class PermissionDecl;
+class PermissionSetDecl;
+
+unsigned hash( // defined in assem.cpp
+ __in_ecount(length) const BYTE *k, /* the key */
+ unsigned length, /* the length of the key */
+ unsigned initval); /* the previous hash, or an arbitrary value */
+
+struct MemberRefDescriptor
+{
+ mdToken m_tdClass;
+ Class* m_pClass;
+ char* m_szName;
+ DWORD m_dwName;
+ BinStr* m_pSigBinStr;
+ mdToken m_tkResolved;
+};
+typedef FIFO<MemberRefDescriptor> MemberRefDList;
+
+
+struct MethodImplDescriptor
+{
+ mdToken m_tkImplementedMethod;
+ mdToken m_tkImplementingMethod;
+ mdToken m_tkDefiningClass;
+ BOOL m_fNew;
+};
+typedef FIFO<MethodImplDescriptor> MethodImplDList;
+
+struct LocalMemberRefFixup
+{
+ mdToken tk;
+ size_t offset;
+ BOOL m_fNew;
+ LocalMemberRefFixup(mdToken TK, size_t Offset)
+ {
+ tk = TK;
+ offset = Offset;
+ m_fNew = TRUE;
+ }
+};
+typedef FIFO<LocalMemberRefFixup> LocalMemberRefFixupList;
+
+struct CustomDescr
+{
+ mdToken tkType;
+ mdToken tkOwner;
+ mdToken tkInterfacePair; // Needed for InterfaceImpl CA's
+ BinStr* pBlob;
+
+ CustomDescr(mdToken tko, mdToken tk, BinStr* pblob)
+ {
+ tkType = tk;
+ pBlob = pblob;
+ tkOwner = tko;
+ tkInterfacePair = 0;
+ };
+ CustomDescr(mdToken tk, BinStr* pblob)
+ {
+ tkType = tk;
+ pBlob = pblob;
+ tkOwner = 0;
+ tkInterfacePair = 0;
+ };
+ CustomDescr(CustomDescr* pOrig)
+ {
+ tkType = pOrig->tkType;
+ pBlob = new BinStr();
+ pBlob->append(pOrig->pBlob);
+ tkOwner = pOrig->tkOwner;
+ tkInterfacePair = pOrig->tkInterfacePair;
+ };
+ ~CustomDescr()
+ {
+ if(pBlob)
+ delete pBlob;
+ };
+};
+typedef FIFO<CustomDescr> CustomDescrList;
+typedef LIFO<CustomDescrList> CustomDescrListStack;
+
+class GenericParamConstraintDescriptor
+{
+public:
+ GenericParamConstraintDescriptor()
+ {
+ m_tk = mdTokenNil;
+ m_tkOwner = mdTokenNil;
+ m_iGenericParamIndex = -1;
+ m_tkTypeConstraint = mdTokenNil;
+ };
+ ~GenericParamConstraintDescriptor()
+ {
+ m_lstCA.RESET(true);
+ };
+ void Init(int index, mdToken typeConstraint)
+ {
+ m_iGenericParamIndex = index;
+ m_tkTypeConstraint = typeConstraint;
+ };
+ void Token(mdToken tk)
+ {
+ m_tk = tk;
+ };
+ mdToken Token()
+ {
+ return m_tk;
+ };
+ void SetOwner(mdToken tk)
+ {
+ m_tkOwner = tk;
+ };
+ mdToken GetOwner()
+ {
+ return m_tkOwner;
+ };
+ int GetParamIndex()
+ {
+ return m_iGenericParamIndex;
+ };
+ mdToken GetTypeConstraint()
+ {
+ return m_tkTypeConstraint;
+ };
+ CustomDescrList* CAList()
+ {
+ return &m_lstCA;
+ };
+
+private:
+ mdGenericParamConstraint m_tk;
+ mdToken m_tkOwner;
+ int m_iGenericParamIndex;
+ mdToken m_tkTypeConstraint;
+
+ CustomDescrList m_lstCA;
+};
+typedef FIFO<GenericParamConstraintDescriptor> GenericParamConstraintList;
+/**************************************************************************/
+#include "typar.hpp"
+#include "method.hpp"
+#include "iceefilegen.h"
+#include "asmman.hpp"
+
+#include "nvpair.h"
+
+
+typedef enum
+{
+ STATE_OK,
+ STATE_FAIL,
+ STATE_ENDMETHOD,
+ STATE_ENDFILE
+} state_t;
+
+
+class GlobalLabel
+{
+public:
+ LPCUTF8 m_szName;
+ DWORD m_GlobalOffset;
+ HCEESECTION m_Section;
+ unsigned m_Hash;
+
+ GlobalLabel(LPCUTF8 pszName, DWORD GlobalOffset, HCEESECTION section)
+ {
+ m_GlobalOffset = GlobalOffset;
+ m_Section = section;
+ m_szName = pszName;
+ m_Hash = hash((const BYTE*)pszName, (unsigned)strlen(pszName),10);
+ }
+
+ ~GlobalLabel(){ delete [] m_szName; }
+
+ int ComparedTo(GlobalLabel* L)
+ {
+ return (m_Hash == L->m_Hash) ? strcmp(m_szName, L->m_szName)
+ : ((m_Hash > L->m_Hash) ? 1 : -1);
+ }
+
+ //int ComparedTo(GlobalLabel* L) { return strcmp(m_szName,L->m_szName); };
+ //int Compare(char* L) { return strcmp(L, m_szNam); };
+ //char* NameOf() { return m_szName; };
+};
+//typedef SORTEDARRAY<GlobalLabel> GlobalLabelList;
+typedef RBTREE<GlobalLabel> GlobalLabelList;
+//typedef FIFO_INDEXED<GlobalLabel> GlobalLabelList;
+
+class CeeFileGenWriter;
+class CeeSection;
+
+class BinStr;
+
+/************************************************************************/
+/* represents an object that knows how to report errors back to the user */
+
+class ErrorReporter
+{
+public:
+ virtual void error(const char* fmt, ...) = 0;
+ virtual void warn(const char* fmt, ...) = 0;
+ virtual void msg(const char* fmt, ...) = 0;
+};
+
+/**************************************************************************/
+/* represents a switch table before the lables are bound */
+
+struct Labels {
+ Labels(__in __nullterminated char* aLabel, Labels* aNext, bool aIsLabel) : Label(aLabel), Next(aNext), isLabel(aIsLabel) {}
+ ~Labels() { if(isLabel && Label) delete [] Label; delete Next; }
+
+ char* Label;
+ Labels* Next;
+ bool isLabel;
+};
+
+/**************************************************************************/
+/* descriptor of the structured exception handling construct */
+struct SEH_Descriptor
+{
+ DWORD sehClause; // catch/filter/finally
+ DWORD tryFrom; // start of try block
+ DWORD tryTo; // end of try block
+ DWORD sehHandler; // start of exception handler
+ DWORD sehHandlerTo; // end of exception handler
+ union {
+ DWORD sehFilter; // start of filter block
+ mdTypeRef cException; // what to catch
+ };
+
+ SEH_Descriptor()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+};
+
+
+typedef LIFO<char> StringStack;
+typedef LIFO<SEH_Descriptor> SEHD_Stack;
+
+typedef FIFO<Method> MethodList;
+//typedef SORTEDARRAY<Method> MethodSortedList;
+typedef FIFO<mdToken> TokenList;
+/**************************************************************************/
+/* The field, event and property descriptor structures */
+
+struct FieldDescriptor
+{
+ mdTypeDef m_tdClass;
+ char* m_szName;
+ DWORD m_dwName;
+ mdFieldDef m_fdFieldTok;
+ ULONG m_ulOffset;
+ char* m_rvaLabel; // if field has RVA associated with it, label for it goes here.
+ BinStr* m_pbsSig;
+ Class* m_pClass;
+ BinStr* m_pbsValue;
+ BinStr* m_pbsMarshal;
+ PInvokeDescriptor* m_pPInvoke;
+ CustomDescrList m_CustomDescrList;
+ DWORD m_dwAttr;
+ BOOL m_fNew;
+ // Security attributes
+ PermissionDecl* m_pPermissions;
+ PermissionSetDecl* m_pPermissionSets;
+ FieldDescriptor() { m_szName = NULL; m_pbsSig = NULL; m_fNew = TRUE; };
+ ~FieldDescriptor() { if(m_szName) delete [] m_szName; if(m_pbsSig) delete m_pbsSig; };
+};
+typedef FIFO<FieldDescriptor> FieldDList;
+
+struct EventDescriptor
+{
+ mdTypeDef m_tdClass;
+ char* m_szName;
+ DWORD m_dwAttr;
+ mdToken m_tkEventType;
+ mdToken m_tkAddOn;
+ mdToken m_tkRemoveOn;
+ mdToken m_tkFire;
+ TokenList m_tklOthers;
+ mdEvent m_edEventTok;
+ BOOL m_fNew;
+ CustomDescrList m_CustomDescrList;
+ ~EventDescriptor() { m_tklOthers.RESET(false); };
+};
+typedef FIFO<EventDescriptor> EventDList;
+
+struct PropDescriptor
+{
+ mdTypeDef m_tdClass;
+ char* m_szName;
+ DWORD m_dwAttr;
+ COR_SIGNATURE* m_pSig;
+ DWORD m_dwCSig;
+ DWORD m_dwCPlusTypeFlag;
+ PVOID m_pValue;
+ DWORD m_cbValue;
+ mdToken m_tkSet;
+ mdToken m_tkGet;
+ TokenList m_tklOthers;
+ mdProperty m_pdPropTok;
+ BOOL m_fNew;
+ CustomDescrList m_CustomDescrList;
+ ~PropDescriptor() { m_tklOthers.RESET(false); };
+};
+typedef FIFO<PropDescriptor> PropDList;
+
+struct ImportDescriptor
+{
+ char* szDllName;
+// char szDllName[MAX_FILENAME_LENGTH];
+ DWORD dwDllName;
+ mdModuleRef mrDll;
+ ImportDescriptor(__in __nullterminated char* sz, DWORD l)
+ {
+ if((sz != NULL)&&(l > 0))
+ {
+ szDllName = new char[l+1];
+ if(szDllName != NULL)
+ {
+ memcpy(szDllName,sz,l);
+ szDllName[l] = 0;
+ dwDllName = l;
+ }
+ }
+ else
+ {
+ szDllName = NULL;
+ dwDllName = 0;
+ }
+ };
+ ~ImportDescriptor() { delete [] szDllName; };
+};
+typedef FIFO<ImportDescriptor> ImportList;
+
+
+/**************************************************************************/
+#include "class.hpp"
+typedef LIFO<Class> ClassStack;
+typedef FIFO<Class> ClassList;
+//typedef SORTEDARRAY<Class> ClassHash;
+typedef RBTREE<Class> ClassHash;
+//typedef FIFO_INDEXED<Class> ClassHash;
+
+/**************************************************************************/
+/* Classes to hold lists of security permissions and permission sets. We build
+ these lists as we find security directives in the input stream and drain
+ them every time we see a class or method declaration (to which the
+ security info is attached). */
+
+class PermissionDecl
+{
+public:
+ PermissionDecl(CorDeclSecurity action, mdToken type, NVPair *pairs)
+ {
+ m_Action = action;
+ m_TypeSpec = type;
+ m_pbsBlob = NULL;
+ BuildConstructorBlob(action, pairs);
+ m_Next = NULL;
+ }
+
+ PermissionDecl(CorDeclSecurity action, mdToken type, BinStr* pbsPairs)
+ {
+ m_Action = action;
+ m_TypeSpec = type;
+
+ m_pbsBlob = new BinStr();
+ m_pbsBlob->appendInt16(VAL16(1)); // prolog 0x01 0x00
+ m_pbsBlob->appendInt32((int)action); // 4-byte action
+ if(pbsPairs) // name-value pairs if any
+ {
+ if(pbsPairs->length() > 2)
+ m_pbsBlob->appendFrom(pbsPairs,2);
+ delete pbsPairs;
+ }
+ if(m_pbsBlob->length() == 6) // no pairs added
+ m_pbsBlob->appendInt16(0);
+ m_Blob = m_pbsBlob->ptr();
+ m_BlobLength = m_pbsBlob->length();
+ m_Next = NULL;
+ }
+
+ ~PermissionDecl()
+ {
+ if(m_pbsBlob) delete m_pbsBlob;
+ else delete [] m_Blob;
+ }
+
+ CorDeclSecurity m_Action;
+ mdToken m_TypeSpec;
+ BYTE *m_Blob;
+ BinStr *m_pbsBlob;
+ long m_BlobLength;
+ PermissionDecl *m_Next;
+
+private:
+ void BuildConstructorBlob(CorDeclSecurity action, NVPair *pairs)
+ {
+ NVPair *p = pairs;
+ int count = 0;
+ int bytes = 8;
+ int length;
+ int i;
+ BYTE *pBlob;
+
+ // Calculate number of name/value pairs and the memory required for the
+ // custom attribute blob.
+ while (p) {
+ BYTE *pVal = (BYTE*)p->Value()->ptr();
+ count++;
+ bytes += 2; // One byte field/property specifier, one byte type code
+
+ length = (int)strlen((const char *)p->Name()->ptr());
+ bytes += CPackedLen::Size(length) + length;
+
+ switch (pVal[0]) {
+ case SERIALIZATION_TYPE_BOOLEAN:
+ bytes += 1;
+ break;
+ case SERIALIZATION_TYPE_I4:
+ bytes += 4;
+ break;
+ case SERIALIZATION_TYPE_STRING:
+ length = (int)strlen((const char *)&pVal[1]);
+ bytes += CPackedLen::Size(length) + length;
+ break;
+ case SERIALIZATION_TYPE_ENUM:
+ length = (int)strlen((const char *)&pVal[1]);
+ bytes += CPackedLen::Size((ULONG)length) + length;
+ bytes += 4;
+ break;
+ }
+ p = p->Next();
+ }
+
+ m_Blob = new BYTE[bytes];
+ if(m_Blob==NULL)
+ {
+ fprintf(stderr,"\nOut of memory!\n");
+ return;
+ }
+
+ m_Blob[0] = 0x01; // Version
+ m_Blob[1] = 0x00;
+ m_Blob[2] = (BYTE)action; // Constructor arg (security action code)
+ m_Blob[3] = 0x00;
+ m_Blob[4] = 0x00;
+ m_Blob[5] = 0x00;
+ m_Blob[6] = (BYTE)count; // Property/field count
+ m_Blob[7] = (BYTE)(count >> 8);
+
+ for (i = 0, pBlob = &m_Blob[8], p = pairs; i < count; i++, p = p->Next()) {
+ BYTE *pVal = (BYTE*)p->Value()->ptr();
+ char *szType;
+
+ // Set field/property setter type.
+ *pBlob++ = SERIALIZATION_TYPE_PROPERTY;
+
+ // Set type code. There's additional info for enums (the enum class
+ // name).
+ *pBlob++ = pVal[0];
+ if (pVal[0] == SERIALIZATION_TYPE_ENUM) {
+ szType = (char *)&pVal[1];
+ length = (int)strlen(szType);
+ pBlob = (BYTE*)CPackedLen::PutLength(pBlob, length);
+ strcpy_s((char *)pBlob, bytes, szType);
+ pBlob += length;
+ }
+
+ // Record the field/property name.
+ length = (int)strlen((const char *)p->Name()->ptr());
+ pBlob = (BYTE*)CPackedLen::PutLength(pBlob, length);
+ strcpy_s((char *)pBlob, bytes-(pBlob-m_Blob), (const char *)p->Name()->ptr());
+ pBlob += length;
+
+ // Record the serialized value.
+ switch (pVal[0]) {
+ case SERIALIZATION_TYPE_BOOLEAN:
+ *pBlob++ = pVal[1];
+ break;
+ case SERIALIZATION_TYPE_I4:
+ *(__int32*)pBlob = *(__int32*)&pVal[1];
+ pBlob += 4;
+ break;
+ case SERIALIZATION_TYPE_STRING:
+ length = (int)strlen((const char *)&pVal[1]);
+ pBlob = (BYTE*)CPackedLen::PutLength(pBlob, length);
+ strcpy_s((char *)pBlob, bytes-(pBlob-m_Blob), (const char *)&pVal[1]);
+ pBlob += length;
+ break;
+ case SERIALIZATION_TYPE_ENUM:
+ length = (int)strlen((const char *)&pVal[1]);
+ // We can have enums with base type of I1, I2 and I4.
+ switch (pVal[1 + length + 1]) {
+ case 1:
+ *(__int8*)pBlob = *(__int8*)&pVal[1 + length + 2];
+ pBlob += 1;
+ break;
+ case 2:
+ *(__int16*)pBlob = *(__int16*)&pVal[1 + length + 2];
+ pBlob += 2;
+ break;
+ case 4:
+ *(__int32*)pBlob = *(__int32*)&pVal[1 + length + 2];
+ pBlob += 4;
+ break;
+ default:
+ _ASSERTE(!"Invalid enum size");
+ }
+ break;
+ }
+
+ }
+
+ _ASSERTE((pBlob - m_Blob) == bytes);
+
+ m_BlobLength = (long)bytes;
+ }
+};
+
+class PermissionSetDecl
+{
+public:
+ PermissionSetDecl(CorDeclSecurity action, BinStr *value)
+ {
+ m_Action = action;
+ m_Value = value;
+ m_Next = NULL;
+ }
+
+ ~PermissionSetDecl()
+ {
+ delete m_Value;
+ }
+
+ CorDeclSecurity m_Action;
+ BinStr *m_Value;
+ PermissionSetDecl *m_Next;
+};
+
+struct VTFEntry
+{
+ char* m_szLabel;
+ WORD m_wCount;
+ WORD m_wType;
+ VTFEntry(WORD wCount, WORD wType, __in __nullterminated char* szLabel) { m_wCount = wCount; m_wType = wType; m_szLabel = szLabel; }
+ ~VTFEntry() { delete m_szLabel; }
+};
+typedef FIFO<VTFEntry> VTFList;
+
+struct EATEntry
+{
+ DWORD dwStubRVA;
+ DWORD dwOrdinal;
+ char* szAlias;
+};
+typedef FIFO<EATEntry> EATList;
+
+struct DocWriter
+{
+ char* Name;
+ ISymUnmanagedDocumentWriter* pWriter;
+ DocWriter() { Name=NULL; pWriter=NULL; };
+ ~DocWriter() { delete [] Name; if(pWriter) pWriter->Release();};
+};
+typedef FIFO<DocWriter> DocWriterList;
+/**************************************************************************/
+/* The assembler object does all the code generation (dealing with meta-data)
+ writing a PE file etc etc. But does NOT deal with syntax (that is what
+ AsmParse is for). Thus the API below is how AsmParse 'controls' the
+ Assember. Note that the Assembler object does know about the
+ AsmParse object (that is Assember is more fundamental than AsmParse) */
+struct Instr
+{
+ int opcode;
+ unsigned linenum;
+ unsigned column;
+ unsigned linenum_end;
+ unsigned column_end;
+ unsigned pc;
+ ISymUnmanagedDocumentWriter* pWriter;
+ Document* pOwnerDocument;
+};
+#define INSTR_POOL_SIZE 16
+
+// For code folding:
+struct MethodBody
+{
+ BinStr* pbsBody;
+ unsigned RVA;
+ BYTE* pCode;
+};
+typedef FIFO<MethodBody> MethodBodyList;
+
+struct Clockwork
+{
+ DWORD cBegin;
+ DWORD cEnd;
+ DWORD cParsBegin;
+ DWORD cParsEnd;
+ DWORD cMDInitBegin;
+ DWORD cMDInitEnd;
+ DWORD cMDEmitBegin;
+ DWORD cMDEmitEnd;
+ DWORD cMDEmit1;
+ DWORD cMDEmit2;
+ DWORD cMDEmit3;
+ DWORD cMDEmit4;
+ DWORD cRef2DefBegin;
+ DWORD cRef2DefEnd;
+ DWORD cFilegenBegin;
+ DWORD cFilegenEnd;
+};
+
+struct TypeDefDescr
+{
+ char* m_szName;
+ union
+ {
+ BinStr* m_pbsTypeSpec;
+ CustomDescr* m_pCA;
+ };
+ mdToken m_tkTypeSpec;
+ TypeDefDescr(__in_opt __nullterminated char *pszName, BinStr* pbsTypeSpec, mdToken tkTypeSpec)
+ {
+ m_szName = pszName;
+ m_pbsTypeSpec = pbsTypeSpec;
+ m_tkTypeSpec = tkTypeSpec;
+ };
+ ~TypeDefDescr() { delete [] m_szName; delete m_pbsTypeSpec; };
+ int ComparedTo(TypeDefDescr* T) { return strcmp(m_szName,T->m_szName); };
+ //int Compare(char* T) { return strcmp(T,m_szName); };
+};
+typedef SORTEDARRAY<TypeDefDescr> TypeDefDList;
+
+struct Indx
+{
+ void* table[128];
+ Indx() { memset(table,0,sizeof(table)); };
+ ~Indx()
+ {
+ for(int i = 1; i < 128; i++) delete ((Indx*)(table[i]));
+ };
+ void IndexString(__in_z __in char* psz, void* pkywd)
+ {
+ int i = (int) *psz;
+ if(i == 0)
+ table[0] = pkywd;
+ else
+ {
+ _ASSERTE((i > 0)&&(i <= 127));
+ Indx* pInd = (Indx*)(table[i]);
+ if(pInd == NULL)
+ {
+ pInd = new Indx;
+ _ASSERTE(pInd);
+ table[i] = pInd;
+ }
+ pInd->IndexString(psz+1,pkywd);
+ }
+ }
+ void* FindString(__in __nullterminated char* psz)
+ {
+ if(*psz > 0)
+ {
+ unsigned char uch = (unsigned char) *psz;
+ if(table[uch] != NULL)
+ return ((Indx*)(table[uch]))->FindString(psz+1);
+ }
+ else if(*psz == 0) return table[0];
+ return NULL;
+ }
+};
+
+typedef enum {
+ CLASSIC, // default - classic PDB format, currently not supported for CoreCLR
+ PORTABLE,
+ // EMBEDDED // for future use
+} PdbFormat;
+
+class Assembler {
+public:
+ Assembler();
+ ~Assembler();
+ //--------------------------------------------------------
+ GlobalLabelList m_lstGlobalLabel;
+ GlobalFixupList m_lstGlobalFixup;
+
+ LabelList m_lstLabel;
+
+ Class * m_pModuleClass;
+ ClassList m_lstClass;
+ ClassHash m_hshClass;
+
+ Indx indxKeywords;
+
+ BYTE * m_pOutputBuffer;
+ BYTE * m_pCurOutputPos;
+ BYTE * m_pEndOutputPos;
+
+
+ DWORD m_CurPC;
+ BOOL m_fStdMapping;
+ BOOL m_fDisplayTraceOutput;
+ BOOL m_fInitialisedMetaData;
+ BOOL m_fAutoInheritFromObject;
+ BOOL m_fReportProgress;
+ BOOL m_fIsMscorlib;
+ BOOL m_fTolerateDupMethods;
+ BOOL m_fENCMode;
+ BOOL m_fOptimize;
+ mdToken m_tkSysObject;
+ mdToken m_tkSysString;
+ mdToken m_tkSysValue;
+ mdToken m_tkSysEnum;
+ BOOL m_fDidCoInitialise;
+
+ IMetaDataDispenserEx2 *m_pDisp;
+ IMetaDataEmit3 *m_pEmitter;
+ ICeeFileGen *m_pCeeFileGen;
+ IMetaDataImport2 *m_pImporter; // Import interface.
+ HCEEFILE m_pCeeFile;
+ HCEESECTION m_pGlobalDataSection;
+ HCEESECTION m_pILSection;
+ HCEESECTION m_pTLSSection;
+ HCEESECTION m_pCurSection; // The section EmitData* things go to
+
+ AsmMan* m_pManifest;
+
+ char m_szScopeName[MAX_SCOPE_LENGTH];
+ char *m_szNamespace; //[MAX_NAMESPACE_LENGTH];
+ char *m_szFullNS; //[MAX_NAMESPACE_LENGTH];
+ unsigned m_ulFullNSLen;
+
+ WCHAR *m_wzMetadataVersion;
+
+ StringStack m_NSstack;
+ mdTypeSpec m_crExtends;
+
+ // char m_szExtendsClause[MAX_CLASSNAME_LENGTH];
+
+ // The (resizable) array of "implements" types
+ mdToken *m_crImplList;
+ int m_nImplList;
+ int m_nImplListSize;
+
+ TyParList *m_TyParList;
+
+ Method *m_pCurMethod;
+ Class *m_pCurClass;
+ ClassStack m_ClassStack; // for nested classes
+ Class *dummyClass; // for FindCreateClass
+
+ // moved to Class
+ //MethodList m_MethodList;
+
+ BOOL m_fCPlusPlus;
+ BOOL m_fWindowsCE;
+ BOOL m_fDLL;
+ BOOL m_fOBJ;
+ BOOL m_fEntryPointPresent;
+ BOOL m_fHaveFieldsWithRvas;
+ BOOL m_fFoldCode;
+ DWORD m_dwMethodsFolded;
+
+ state_t m_State;
+
+ BinStr* m_pbsMD;
+
+ Instr m_Instr[INSTR_POOL_SIZE]; // 16
+ inline Instr* GetInstr()
+ {
+ int i;
+ for(i=0; (i<INSTR_POOL_SIZE)&&(m_Instr[i].opcode != -1); i++);
+ if(i<INSTR_POOL_SIZE) return &m_Instr[i];
+ report->error("Instruction pool exhausted: source contains invalid instructions\n");
+ return NULL;
+ }
+ // Labels, fixups and IL fixups are defined in Method.hpp,.cpp
+ void AddLabel(DWORD CurPC, __in __nullterminated char *pszName);
+ void AddDeferredFixup(__in __nullterminated char *pszLabel, BYTE *pBytes, DWORD RelativeToPC, BYTE FixupSize);
+ void AddDeferredILFixup(ILFixupType Kind);
+ void AddDeferredILFixup(ILFixupType Kind, GlobalFixup *GFixup);
+ void DoDeferredILFixups(Method* pMethod);
+ BOOL DoFixups(Method* pMethod);
+ //--------------------------------------------------------------------------------
+ void ClearImplList(void);
+ void AddToImplList(mdToken);
+ void ClearBoundList(void);
+ //--------------------------------------------------------------------------------
+ BOOL Init(BOOL generatePdb, PdbFormat pdbFormat);
+ void ProcessLabel(__in_z __in char *pszName);
+ GlobalLabel *FindGlobalLabel(LPCUTF8 pszName);
+ GlobalFixup *AddDeferredGlobalFixup(__in __nullterminated char *pszLabel, BYTE* reference);
+ //void AddDeferredDescrFixup(__in __nullterminated char *pszLabel);
+ BOOL DoGlobalFixups();
+ BOOL DoDescrFixups();
+ OPCODE DecodeOpcode(const BYTE *pCode, DWORD *pdwLen);
+ BOOL AddMethod(Method *pMethod);
+ void SetTLSSection() { m_pCurSection = m_pTLSSection; }
+ void SetILSection() { m_pCurSection = m_pILSection; }
+ void SetDataSection() { m_pCurSection = m_pGlobalDataSection; }
+ BOOL EmitMethod(Method *pMethod);
+ BOOL EmitMethodBody(Method* pMethod, BinStr* pbsOut);
+ BOOL EmitClass(Class *pClass);
+ HRESULT CreatePEFile(__in __nullterminated WCHAR *pwzOutputFilename);
+ HRESULT CreateTLSDirectory();
+ HRESULT CreateDebugDirectory();
+ HRESULT InitMetaData();
+ Class *FindCreateClass(__in __nullterminated const char *pszFQN);
+ BOOL EmitFieldRef(__in_z __in char *pszArg, int opcode);
+ BOOL EmitSwitchData(__in_z __in char *pszArg);
+ mdToken ResolveClassRef(mdToken tkResScope, __in __nullterminated const char *pszClassName, Class** ppClass);
+ mdToken ResolveTypeSpec(BinStr* typeSpec);
+ mdToken GetBaseAsmRef();
+ mdToken GetAsmRef(__in __nullterminated const char* szName);
+ mdToken GetModRef(__in __nullterminated char* szName);
+ mdToken GetInterfaceImpl(mdToken tsClass, mdToken tsInterface);
+ char* ReflectionNotation(mdToken tk);
+ HRESULT ConvLocalSig(__in char* localsSig, CQuickBytes* corSig, DWORD* corSigLen, BYTE*& localTypes);
+ DWORD GetCurrentILSectionOffset();
+ BOOL EmitCALLISig(__in char *p);
+ void AddException(DWORD pcStart, DWORD pcEnd, DWORD pcHandler, DWORD pcHandlerTo, mdTypeRef crException, BOOL isFilter, BOOL isFault, BOOL isFinally);
+ state_t CheckLocalTypeConsistancy(int instr, unsigned arg);
+ state_t AddGlobalLabel(__in __nullterminated char *pszName, HCEESECTION section);
+ void SetDLL(BOOL);
+ void SetOBJ(BOOL);
+ void ResetForNextMethod();
+ void ResetLineNumbers();
+ void SetStdMapping(BOOL val = TRUE) { m_fStdMapping = val; };
+
+ //--------------------------------------------------------------------------------
+ BOOL isShort(unsigned instr) { return ((OpcodeInfo[instr].Type & 16) != 0); };
+ unsigned ShortOf(unsigned opcode);
+ void SetErrorReporter(ErrorReporter* aReport) { report = aReport; if(m_pManifest) m_pManifest->SetErrorReporter(aReport); }
+
+ void StartNameSpace(__in __nullterminated char* name);
+ void EndNameSpace();
+ void StartClass(__in __nullterminated char* name, DWORD attr, TyParList *typars);
+ DWORD CheckClassFlagsIfNested(Class* pEncloser, DWORD attr);
+ void AddClass();
+ void EndClass();
+ void StartMethod(__in __nullterminated char* name, BinStr* sig, CorMethodAttr flags, BinStr* retMarshal, DWORD retAttr, TyParList *typars = NULL);
+ void EndMethod();
+
+ void AddField(__inout_z __inout char* name, BinStr* sig, CorFieldAttr flags, __in __nullterminated char* rvaLabel, BinStr* pVal, ULONG ulOffset);
+ BOOL EmitField(FieldDescriptor* pFD);
+ void EmitByte(int val);
+ //void EmitTry(enum CorExceptionFlag kind, char* beginLabel, char* endLabel, char* handleLabel, char* filterOrClass);
+ void EmitMaxStack(unsigned val);
+ void EmitLocals(BinStr* sig);
+ void EmitEntryPoint();
+ void EmitZeroInit();
+ void SetImplAttr(unsigned short attrval);
+
+ // Emits zeros if the buffer parameter is NULL.
+ void EmitData(__in_opt void *buffer, unsigned len);
+
+ void EmitDD(__in __nullterminated char *str);
+ void EmitDataString(BinStr* str);
+
+ void EmitInstrVar(Instr* instr, int var);
+ void EmitInstrVarByName(Instr* instr, __in __nullterminated char* label);
+ void EmitInstrI(Instr* instr, int val);
+ void EmitInstrI8(Instr* instr, __int64* val);
+ void EmitInstrR(Instr* instr, double* val);
+ void EmitInstrBrOffset(Instr* instr, int offset);
+ void EmitInstrBrTarget(Instr* instr, __in __nullterminated char* label);
+ mdToken MakeMemberRef(mdToken typeSpec, __in __nullterminated char* name, BinStr* sig);
+ mdToken MakeMethodSpec(mdToken tkParent, BinStr* sig);
+ void SetMemberRefFixup(mdToken tk, unsigned opcode_len);
+ mdToken MakeTypeRef(mdToken tkResScope, LPCUTF8 szFullName);
+ void EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL ConvertToUnicode, BOOL Swap = FALSE);
+ void EmitInstrSig(Instr* instr, BinStr* sig);
+ void EmitInstrSwitch(Instr* instr, Labels* targets);
+ void EmitLabel(__in __nullterminated char* label);
+ void EmitDataLabel(__in __nullterminated char* label);
+
+ unsigned OpcodeLen(Instr* instr); //returns opcode length
+ // Emit just the opcode (no parameters to the instruction stream.
+ void EmitOpcode(Instr* instr);
+
+ // Emit primitive types to the instruction stream.
+ void EmitBytes(BYTE*, unsigned len);
+
+ ErrorReporter* report;
+
+ BOOL EmitFieldsMethods(Class* pClass);
+ BOOL EmitEventsProps(Class* pClass);
+
+ // named args/vars paraphernalia:
+public:
+ void addArgName(__in_opt __nullterminated char *szNewName, BinStr* pbSig, BinStr* pbMarsh, DWORD dwAttr)
+ {
+ if(pbSig && (*(pbSig->ptr()) == ELEMENT_TYPE_VOID))
+ report->error("Illegal use of type 'void'\n");
+ if(m_lastArgName)
+ {
+ m_lastArgName->pNext = new ARG_NAME_LIST(m_lastArgName->nNum+1,szNewName,pbSig,pbMarsh,dwAttr);
+ m_lastArgName = m_lastArgName->pNext;
+ }
+ else
+ {
+ m_lastArgName = new ARG_NAME_LIST(0,szNewName,pbSig,pbMarsh,dwAttr);
+ m_firstArgName = m_lastArgName;
+ }
+ };
+ ARG_NAME_LIST *getArgNameList(void)
+ { ARG_NAME_LIST *pRet = m_firstArgName; m_firstArgName=NULL; m_lastArgName=NULL; return pRet;};
+ // Added because recursive destructor of ARG_NAME_LIST may overflow the system stack
+ void delArgNameList(ARG_NAME_LIST *pFirst)
+ {
+ ARG_NAME_LIST *pArgList=pFirst, *pArgListNext;
+ for(; pArgList; pArgListNext=pArgList->pNext,
+ delete pArgList,
+ pArgList=pArgListNext);
+ };
+
+ ARG_NAME_LIST *findArg(ARG_NAME_LIST *pFirst, int num)
+ {
+ ARG_NAME_LIST *pAN;
+ for(pAN=pFirst; pAN; pAN = pAN->pNext)
+ {
+ if(pAN->nNum == num) return pAN;
+ }
+ return NULL;
+ };
+ ARG_NAME_LIST *m_firstArgName;
+ ARG_NAME_LIST *m_lastArgName;
+ void ResetArgNameList();
+
+ // Structured exception handling paraphernalia:
+public:
+ SEH_Descriptor *m_SEHD; // current descriptor ptr
+ void NewSEHDescriptor(void); //sets m_SEHD
+ void SetTryLabels(__in __nullterminated char * szFrom, __in __nullterminated char *szTo);
+ void SetFilterLabel(__in __nullterminated char *szFilter);
+ void SetCatchClass(mdToken catchClass);
+ void SetHandlerLabels(__in __nullterminated char *szHandlerFrom, __in __nullterminated char *szHandlerTo);
+ void EmitTry(void); //uses m_SEHD
+
+//private:
+ SEHD_Stack m_SEHDstack;
+
+ // Events and Properties paraphernalia:
+public:
+ void EndEvent(void); //emits event definition
+ void EndProp(void); //emits property definition
+ void ResetEvent(__inout_z __inout char * szName, mdToken typeSpec, DWORD dwAttr);
+ void ResetProp(__inout_z __inout char * szName, BinStr* bsType, DWORD dwAttr, BinStr* bsValue);
+ void SetEventMethod(int MethodCode, mdToken tk);
+ void SetPropMethod(int MethodCode, mdToken tk);
+ BOOL EmitEvent(EventDescriptor* pED); // impl. in ASSEM.CPP
+ BOOL EmitProp(PropDescriptor* pPD); // impl. in ASSEM.CPP
+ EventDescriptor* m_pCurEvent;
+ PropDescriptor* m_pCurProp;
+
+private:
+ MemberRefDList m_LocalMethodRefDList;
+ MemberRefDList m_LocalFieldRefDList;
+ LocalMemberRefFixupList m_LocalMemberRefFixupList;
+ MethodBodyList m_MethodBodyList;
+ MemberRefDList m_MethodSpecList;
+public:
+ HRESULT ResolveLocalMemberRefs();
+ HRESULT DoLocalMemberRefFixups();
+ mdToken ResolveLocalMemberRef(mdToken tok);
+
+ // PInvoke paraphernalia
+public:
+ PInvokeDescriptor* m_pPInvoke;
+ ImportList m_ImportList;
+ void SetPinvoke(BinStr* DllName, int Ordinal, BinStr* Alias, int Attrs);
+ HRESULT EmitPinvokeMap(mdToken tk, PInvokeDescriptor* pDescr);
+ ImportDescriptor* EmitImport(BinStr* DllName);
+ void EmitImports();
+
+ // Debug metadata paraphernalia
+public:
+ ISymUnmanagedWriter* m_pSymWriter;
+ ISymUnmanagedDocumentWriter* m_pSymDocument;
+ DocWriterList m_DocWriterList;
+ ULONG m_ulCurLine; // set by Parser
+ ULONG m_ulCurColumn; // set by Parser
+ ULONG m_ulLastDebugLine;
+ ULONG m_ulLastDebugColumn;
+ ULONG m_ulLastDebugLineEnd;
+ ULONG m_ulLastDebugColumnEnd;
+ DWORD m_dwIncludeDebugInfo;
+ BOOL m_fGeneratePDB;
+ char m_szSourceFileName[MAX_FILENAME_LENGTH*3+1];
+ WCHAR m_wzOutputFileName[MAX_FILENAME_LENGTH];
+ WCHAR m_wzSourceFileName[MAX_FILENAME_LENGTH];
+ GUID m_guidLang;
+ GUID m_guidLangVendor;
+ GUID m_guidDoc;
+
+ // Portable PDB paraphernalia
+public:
+ PdbFormat m_pdbFormat;
+ PortablePdbWriter* m_pPortablePdbWriter;
+ char m_szPdbFileName[MAX_FILENAME_LENGTH * 3 + 1];
+ WCHAR m_wzPdbFileName[MAX_FILENAME_LENGTH];
+
+ // Sets the pdb file name of the assembled file.
+ void SetPdbFileName(__in __nullterminated char* szName);
+ // Saves the pdb file.
+ HRESULT SavePdbFile();
+ // Checks whether pdb generation is portable
+ BOOL IsPortablePdb();
+
+ // Security paraphernalia
+public:
+ void AddPermissionDecl(CorDeclSecurity action, mdToken type, NVPair *pairs)
+ {
+ PermissionDecl *decl = new PermissionDecl(action, type, pairs);
+ if(decl==NULL)
+ {
+ report->error("\nOut of memory!\n");
+ return;
+ }
+ if (m_pCurMethod) {
+ decl->m_Next = m_pCurMethod->m_pPermissions;
+ m_pCurMethod->m_pPermissions = decl;
+ } else if (m_pCurClass) {
+ decl->m_Next = m_pCurClass->m_pPermissions;
+ m_pCurClass->m_pPermissions = decl;
+ } else if (m_pManifest && m_pManifest->m_pAssembly) {
+ decl->m_Next = m_pManifest->m_pAssembly->m_pPermissions;
+ m_pManifest->m_pAssembly->m_pPermissions = decl;
+ } else {
+ report->error("Cannot declare security permissions without the owner\n");
+ delete decl;
+ }
+ };
+
+ void AddPermissionDecl(CorDeclSecurity action, mdToken type, BinStr *pbsPairs)
+ {
+ PermissionDecl *decl = new PermissionDecl(action, type, pbsPairs);
+ if(decl==NULL)
+ {
+ report->error("\nOut of memory!\n");
+ return;
+ }
+ if (m_pCurMethod) {
+ decl->m_Next = m_pCurMethod->m_pPermissions;
+ m_pCurMethod->m_pPermissions = decl;
+ } else if (m_pCurClass) {
+ decl->m_Next = m_pCurClass->m_pPermissions;
+ m_pCurClass->m_pPermissions = decl;
+ } else if (m_pManifest && m_pManifest->m_pAssembly) {
+ decl->m_Next = m_pManifest->m_pAssembly->m_pPermissions;
+ m_pManifest->m_pAssembly->m_pPermissions = decl;
+ } else {
+ report->error("Cannot declare security permissions without the owner\n");
+ delete decl;
+ }
+ };
+
+ void AddPermissionSetDecl(CorDeclSecurity action, BinStr *value)
+ {
+ PermissionSetDecl *decl = new PermissionSetDecl(action, value);
+ if(decl==NULL)
+ {
+ report->error("\nOut of memory!\n");
+ return;
+ }
+ if (m_pCurMethod) {
+ decl->m_Next = m_pCurMethod->m_pPermissionSets;
+ m_pCurMethod->m_pPermissionSets = decl;
+ } else if (m_pCurClass) {
+ decl->m_Next = m_pCurClass->m_pPermissionSets;
+ m_pCurClass->m_pPermissionSets = decl;
+ } else if (m_pManifest && m_pManifest->m_pAssembly) {
+ decl->m_Next = m_pManifest->m_pAssembly->m_pPermissionSets;
+ m_pManifest->m_pAssembly->m_pPermissionSets = decl;
+ } else {
+ report->error("Cannot declare security permission sets without the owner\n");
+ delete decl;
+ }
+ };
+ void EmitSecurityInfo(mdToken token,
+ PermissionDecl* pPermissions,
+ PermissionSetDecl*pPermissionSets);
+ BinStr* EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps);
+
+ HRESULT AllocateStrongNameSignature();
+
+ // Custom values paraphernalia:
+public:
+ mdToken m_tkCurrentCVOwner;
+ CustomDescrList* m_pCustomDescrList;
+ CustomDescrListStack m_CustomDescrListStack;
+ CustomDescrList m_CustomDescrList;
+
+ void DefineCV(CustomDescr* pCD)
+ {
+ if(pCD)
+ {
+ ULONG cTemp = 0;
+ void * pBlobBody = NULL;
+ mdToken cv;
+ mdToken tkOwnerType, tkTypeType = TypeFromToken(pCD->tkType);
+
+ if((tkTypeType != 0x99000000)&&(tkTypeType != 0x98000000))
+ {
+ tkOwnerType = TypeFromToken(pCD->tkOwner);
+ if((tkOwnerType != 0x99000000)&&(tkOwnerType != 0x98000000))
+ {
+ if(pCD->pBlob)
+ {
+ pBlobBody = (void *)(pCD->pBlob->ptr());
+ cTemp = pCD->pBlob->length();
+ }
+ if (pCD->tkInterfacePair)
+ {
+ pCD->tkOwner = GetInterfaceImpl(pCD->tkOwner, pCD->tkInterfacePair);
+ }
+ m_pEmitter->DefineCustomAttribute(pCD->tkOwner,pCD->tkType,pBlobBody,cTemp,&cv);
+
+ delete pCD;
+ return;
+ }
+ }
+ m_CustomDescrList.PUSH(pCD);
+ }
+ };
+ void EmitCustomAttributes(mdToken tok, CustomDescrList* pCDL)
+ {
+ CustomDescr *pCD;
+ if(pCDL == NULL || RidFromToken(tok)==0) return;
+ while((pCD = pCDL->POP()))
+ {
+ pCD->tkOwner = tok;
+ DefineCV(pCD);
+ }
+ };
+ void EmitUnresolvedCustomAttributes(); // implementation: writer.cpp
+ // VTable blob (if any)
+public:
+ BinStr *m_pVTable;
+ // Field marshaling
+ BinStr *m_pMarshal;
+ // VTable fixup list
+ VTFList m_VTFList;
+ // Export Address Table entries list
+ EATList m_EATList;
+ HRESULT CreateExportDirectory();
+ DWORD EmitExportStub(DWORD dwVTFSlotRVA);
+
+ // Method implementation paraphernalia:
+private:
+ MethodImplDList m_MethodImplDList;
+public:
+ void AddMethodImpl(mdToken tkImplementedTypeSpec, __in __nullterminated char* szImplementedName, BinStr* pImplementedSig,
+ mdToken tkImplementingTypeSpec, __in_opt __nullterminated char* szImplementingName, BinStr* pImplementingSig);
+ BOOL EmitMethodImpls();
+ // lexical scope handling paraphernalia:
+ void EmitScope(Scope* pSCroot); // struct Scope - see Method.hpp
+ // source file name paraphernalia
+ BOOL m_fSourceFileSet;
+ void SetSourceFileName(__in __nullterminated char* szName);
+ void SetSourceFileName(BinStr* pbsName);
+ // header flags
+ DWORD m_dwSubsystem;
+ WORD m_wSSVersionMajor;
+ WORD m_wSSVersionMinor;
+ DWORD m_dwComImageFlags;
+ DWORD m_dwFileAlignment;
+ ULONGLONG m_stBaseAddress;
+ size_t m_stSizeOfStackReserve;
+ DWORD m_dwCeeFileFlags;
+ WORD m_wMSVmajor;
+ WORD m_wMSVminor;
+ BOOL m_fAppContainer;
+ BOOL m_fHighEntropyVA;
+
+ // Former globals
+ WCHAR *m_wzResourceFile;
+ WCHAR *m_wzKeySourceName;
+ bool OnErrGo;
+ void SetCodePage(unsigned val) { g_uCodePage = val; };
+ Clockwork* bClock;
+ void SetClock(Clockwork* val) { bClock = val; };
+ // ENC paraphernalia
+ HRESULT InitMetaDataForENC(__in __nullterminated WCHAR* wzOrigFileName, BOOL generatePdb, PdbFormat pdbFormat);
+ BOOL EmitFieldsMethodsENC(Class* pClass);
+ BOOL EmitEventsPropsENC(Class* pClass);
+ HRESULT CreateDeltaFiles(__in __nullterminated WCHAR *pwzOutputFilename);
+
+ // Syntactic sugar paraphernalia
+private:
+ TypeDefDList m_TypeDefDList;
+public:
+ void AddTypeDef(BinStr* pbsTypeSpec, __in_z __in char* szName)
+ {
+ m_TypeDefDList.PUSH(new TypeDefDescr(szName, pbsTypeSpec, ResolveTypeSpec(pbsTypeSpec)));
+ };
+ void AddTypeDef(mdToken tkTypeSpec, __in_z __in char* szName)
+ {
+ m_TypeDefDList.PUSH(new TypeDefDescr(szName, NULL, tkTypeSpec));
+ };
+ void AddTypeDef(CustomDescr* pCA, __in_z __in char* szName)
+ {
+ TypeDefDescr* pNew = new TypeDefDescr(szName,NULL,mdtCustomAttribute);
+ pNew->m_pCA = pCA;
+ m_TypeDefDList.PUSH(pNew);
+ };
+ TypeDefDescr* FindTypeDef(__in_z __in char* szName)
+ {
+ CHECK_LOCAL_STATIC_VAR(static TypeDefDescr X(NULL, NULL, 0));
+
+ X.m_szName = szName;
+ TypeDefDescr* Y = m_TypeDefDList.FIND(&X);
+ X.m_szName = NULL; // to avoid deletion when X goes out of scope
+ return Y;
+ //return m_TypeDefDList.FIND(szName);
+ };
+ unsigned NumTypeDefs() {return m_TypeDefDList.COUNT();};
+private:
+ HRESULT GetCAName(mdToken tkCA, __out LPWSTR *ppszName);
+
+public:
+ void RecordTypeConstraints(GenericParamConstraintList* pGPCList, int numTyPars, TyParDescr* tyPars);
+
+ void AddGenericParamConstraint(int index, char * pStrGenericParam, mdToken tkTypeConstraint);
+
+ void CheckAddGenericParamConstraint(GenericParamConstraintList* pGPCList, int index, mdToken tkTypeConstraint, bool isParamDirective);
+
+ void EmitGenericParamConstraints(int numTyPars, TyParDescr* pTyPars, mdToken tkOwner, GenericParamConstraintList* pGPCL);
+
+};
+
+#endif // Assember_h
+
+#ifdef _MSC_VER
+#pragma warning(default : 4640)
+#endif
+
+
diff --git a/src/coreclr/ilasm/binstr.h b/src/coreclr/ilasm/binstr.h
new file mode 100644
index 00000000000..d0e8da1e490
--- /dev/null
+++ b/src/coreclr/ilasm/binstr.h
@@ -0,0 +1,76 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/**************************************************************************/
+/* a binary string (blob) class */
+
+#ifndef BINSTR_H
+#define BINSTR_H
+
+#include <string.h> // for memmove, memcpy ...
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22008) // "Suppress PREfast warnings about integer overflow"
+#endif
+
+class BinStr {
+public:
+ BinStr() { len = 0L; max = 8L; ptr_ = buff; }
+ BinStr(BYTE* pb, DWORD cb) { len = cb; max = cb+8; ptr_ = pb; }
+ ~BinStr() { if (ptr_ != buff) delete [] ptr_; }
+
+ void insertInt8(int val) { if (len >= max) Realloc(); memmove(ptr_+1, ptr_, len); *ptr_ = val; len++; }
+ void insertInt32(int val) { if (len + 4 > max) Realloc(); memmove(ptr_+4, ptr_, len); SET_UNALIGNED_32(&ptr_[0], val); len+=4; }
+ void appendInt8(int val) { if (len >= max) Realloc(); ptr_[len++] = val; }
+ void appendInt16(int val) { if (len + 2 > max) Realloc(); SET_UNALIGNED_16(&ptr_[len], val); len += 2; }
+ void appendInt32(int val) { if (len + 4 > max) Realloc(); SET_UNALIGNED_32(&ptr_[len], val); len += 4; }
+ void appendInt64(__int64 *pval) { if (len + 8 > max) Realloc(8); SET_UNALIGNED_64(&ptr_[len],(*pval)); len += 8; }
+ unsigned __int8* getBuff(unsigned size) {
+ if (len + size > max) Realloc(size);
+ _ASSERTE(len + size <= max);
+ unsigned __int8* ret = &ptr_[len];
+ len += size;
+ return(ret);
+ }
+ void append(BinStr* str) {
+ memcpy(getBuff(str->length()), str->ptr(), str->length());
+ }
+
+ void appendFrom(BinStr* str, unsigned ix) {
+ _ASSERTE(str->length() >= ix);
+ if (str->length() >= ix)
+ {
+ memcpy(getBuff(str->length()-ix), str->ptr()+ix, str->length()-ix);
+ }
+ }
+
+ void remove(unsigned size) { _ASSERTE(len >= size); len -= size; }
+
+ unsigned __int8* ptr() { return(ptr_); }
+ unsigned length() { return(len); }
+
+private:
+ void Realloc(unsigned atLeast = 4) {
+ max = max * 2;
+ if (max < atLeast + len)
+ max = atLeast + len;
+ _ASSERTE(max >= len + atLeast);
+ unsigned __int8* newPtr = new unsigned __int8[max];
+ memcpy(newPtr, ptr_, len);
+ if (ptr_ != buff) delete [] ptr_;
+ ptr_ = newPtr;
+ }
+
+private:
+ unsigned len;
+ unsigned max;
+ unsigned __int8 *ptr_;
+ unsigned __int8 buff[8];
+};
+BinStr* BinStrToUnicode(BinStr* pSource, bool Swap = false);
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/src/coreclr/ilasm/class.hpp b/src/coreclr/ilasm/class.hpp
new file mode 100644
index 00000000000..b8675895700
--- /dev/null
+++ b/src/coreclr/ilasm/class.hpp
@@ -0,0 +1,119 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// class.hpp
+//
+
+#ifndef _CLASS_HPP
+#define _CLASS_HPP
+
+class PermissionDecl;
+class PermissionSetDecl;
+
+extern unsigned int g_uCodePage;
+extern WCHAR wzUniBuf[];
+
+class Class
+{
+public:
+ Class * m_pEncloser;
+ LPCUTF8 m_szFQN;
+ DWORD m_dwFQN;
+ unsigned m_Hash;
+ mdTypeDef m_cl;
+ mdTypeRef m_crExtends;
+ mdTypeRef *m_crImplements;
+ TyParDescr* m_TyPars;
+ DWORD m_NumTyPars;
+ GenericParamConstraintList m_GPCList;
+
+ DWORD m_Attr;
+ DWORD m_dwNumInterfaces;
+ DWORD m_dwNumFieldsWithOffset;
+ PermissionDecl* m_pPermissions;
+ PermissionSetDecl* m_pPermissionSets;
+ ULONG m_ulSize;
+ ULONG m_ulPack;
+ BOOL m_bIsMaster;
+ BOOL m_fNew;
+ BOOL m_fNewMembers;
+
+ MethodList m_MethodList;
+ //MethodSortedList m_MethodSList;
+ FieldDList m_FieldDList;
+ EventDList m_EventDList;
+ PropDList m_PropDList;
+ CustomDescrList m_CustDList;
+
+ Class(LPCUTF8 pszFQN)
+ {
+ m_pEncloser = NULL;
+ m_cl = mdTypeDefNil;
+ m_crExtends = mdTypeRefNil;
+ m_NumTyPars = 0;
+ m_TyPars = NULL;
+ m_dwNumInterfaces = 0;
+ m_dwNumFieldsWithOffset = 0;
+ m_crImplements = NULL;
+ m_szFQN = pszFQN;
+ m_dwFQN = pszFQN ? (DWORD)strlen(pszFQN) : 0;
+ m_Hash = pszFQN ? hash((const BYTE*)pszFQN, m_dwFQN, 10) : 0;
+
+ m_Attr = tdPublic;
+
+ m_bIsMaster = TRUE;
+ m_fNew = TRUE;
+
+ m_pPermissions = NULL;
+ m_pPermissionSets = NULL;
+
+ m_ulPack = 0;
+ m_ulSize = 0xFFFFFFFF;
+ }
+
+ ~Class()
+ {
+ delete [] m_szFQN;
+ delete [] m_crImplements;
+ delete [] m_TyPars;
+ }
+
+ int FindTyPar(LPCWSTR wz)
+ {
+ int i,retval=-1;
+ for(i=0; i < (int)m_NumTyPars; i++)
+ {
+ if(!wcscmp(wz,m_TyPars[i].Name()))
+ {
+ retval = i;
+ break;
+ }
+ }
+ return retval;
+ };
+ int FindTyPar(LPCUTF8 sz)
+ {
+ if(sz)
+ {
+ wzUniBuf[0] = 0;
+ WszMultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf);
+ return FindTyPar(wzUniBuf);
+ }
+ else return -1;
+ };
+ int ComparedTo(Class* T)
+ {
+ if (m_Hash == T->m_Hash)
+ {
+ // Properly handle hash conflict
+ return (m_szFQN == T->m_szFQN) ? 0 : strcmp(m_szFQN, T->m_szFQN);
+ } else
+ {
+ return (m_Hash > T->m_Hash) ? 1 : -1;
+ }
+ }
+};
+
+
+#endif /* _CLASS_HPP */
+
diff --git a/src/coreclr/ilasm/extractGrammar.pl b/src/coreclr/ilasm/extractGrammar.pl
new file mode 100644
index 00000000000..0c2019ef98b
--- /dev/null
+++ b/src/coreclr/ilasm/extractGrammar.pl
@@ -0,0 +1,59 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+#
+# a simple script that extracts the grammar from a yacc file
+
+undef $/; # read in the whole file
+my $file = <>;
+$file =~ /^(.*)%%(.*)%%/s || die "Could not find %% markers";
+my $prefix = $1;
+my $grammar = $2;
+
+#my $line;
+#foreach $line (split /\n/s, $prefix) {
+# if ($line =~ /^\s*%token/) {
+# $line =~ s/\s*<.*>//g;
+# print "$line\n"
+# }
+#}
+
+ # remove any text in {}
+while ($grammar =~ s/\s*([^']){[^{}]*}/$1/sg) {}
+
+ # change keyword identifiers into the string they represent
+$grammar =~ s/\b([A-Z0-9_]+)_\b/'\L$1\E'/sg;
+
+ # change assembler directives into their string
+$grammar =~ s/\b_([A-Z0-9]+)\b/'\L.$1\E'/sg;
+
+ # do the special punctuation by hand
+$grammar =~ s/\bELIPSIS\b/'...'/sg;
+$grammar =~ s/\bDCOLON\b/'::'/sg;
+
+#<STRIP>
+ # remove TODO comments
+$grammar =~ s/\n\s*\/\*[^\n]*TODO[^\n]*\*\/\s*\n/\n/sg;
+#</STRIP>
+
+print "Lexical tokens\n";
+print " ID - C style alphaNumeric identifier (e.g. Hello_There2)\n";
+print " DOTTEDNAME - Sequence of dot-separated IDs (e.g. System.Object)\n";
+print " QSTRING - C style quoted string (e.g. \"hi\\n\")\n";
+print " SQSTRING - C style singlely quoted string(e.g. 'hi')\n";
+print " INT32 - C style 32 bit integer (e.g. 235, 03423, 0x34FFF)\n";
+print " INT64 - C style 64 bit integer (e.g. -2353453636235234, 0x34FFFFFFFFFF)\n";
+print " FLOAT64 - C style floating point number (e.g. -0.2323, 354.3423, 3435.34E-5)\n";
+print " INSTR_* - IL instructions of a particular class (see opcode.def).\n";
+print " HEXBYTE - 1- or 2-digit hexadecimal number (e.g., A2, F0).\n";
+print "Auxiliary lexical tokens\n";
+print " TYPEDEF_T - Aliased class (TypeDef or TypeRef).\n";
+print " TYPEDEF_M - Aliased method.\n";
+print " TYPEDEF_F - Aliased field.\n";
+print " TYPEDEF_TS - Aliased type specification (TypeSpec).\n";
+print " TYPEDEF_MR - Aliased field/method reference (MemberRef).\n";
+print " TYPEDEF_CA - Aliased Custom Attribute.\n";
+print "----------------------------------------------------------------------------------\n";
+print "START : decls\n";
+print " ;";
+
+print $grammar;
diff --git a/src/coreclr/ilasm/grammar_after.cpp b/src/coreclr/ilasm/grammar_after.cpp
new file mode 100644
index 00000000000..1fcb1bf9049
--- /dev/null
+++ b/src/coreclr/ilasm/grammar_after.cpp
@@ -0,0 +1,1695 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/********************************************************************************/
+/* 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* 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*)dbuff, (WCHAR**)&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 || PASM->IsPortablePdb())
+ {
+ 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;
+ // Portable PDB rule:
+ // - If Start Line is equal to End Line then End Column is greater than Start Column.
+ // To fulfill this condition the column_end is set to 2 instead of 0
+ pVal->column_end = PASM->IsPortablePdb() ? 2 : 0;
+ pVal->pc = PASM->m_CurPC;
+ }
+ pVal->pOwnerDocument = PASM->IsPortablePdb() ? PASM->m_pPortablePdbWriter->GetCurrentDocument() : NULL;
+ }
+ }
+ 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 */
+
+
+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]; }
+
+
+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,DIRECTORY_SEPARATOR_CHAR_A)==NULL)
+#ifdef TARGET_WINDOWS
+ &&(wcschr(wzFile,':')==NULL)
+#endif
+ )
+ {
+ PathString wzFullName;
+
+ WCHAR* pwz;
+ DWORD dw = WszSearchPath(parser->wzIncludePath,wzFile,NULL,
+ TRUE, wzFullName,&pwz);
+ if(dw != 0)
+ {
+ 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)
+ {
+ 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 dependent 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());
+}
+
+/**************************************************************************/
+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;
+ g_uCodePage = CP_UTF8;
+ iPutToBuffer = (int)penv->in->getAll(&(penv->curPos));
+
+ penv->endPos = penv->curPos + iPutToBuffer;
+ if(iPutToBuffer > 128) iPutToBuffer = 128;
+ if(iPutToBuffer >= 4 && (penv->curPos[0] & 0xFF) == 0xFF && (penv->curPos[1] & 0xFF) == 0xFE)
+ {
+ // U+FFFE followed by U+0000 is UTF-32 LE, any other value than 0 is a true UTF-16 LE
+ if((penv->curPos[2] & 0xFF) == 0x00 && (penv->curPos[3] & 0xFF) == 0x00)
+ {
+ error("UTF-32 LE is not supported\n\n");
+ return NULL;
+ }
+
+ penv->curPos += 2; // skip signature
+ 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)
+ {
+ penv->curPos += 3;
+ }
+
+ if(assem->m_fReportProgress) printf("Source file is UTF-8\n\n");
+ penv->pfn_nextchar = nextcharU;
+ 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
diff --git a/src/coreclr/ilasm/grammar_before.cpp b/src/coreclr/ilasm/grammar_before.cpp
new file mode 100644
index 00000000000..43b45bf36b9
--- /dev/null
+++ b/src/coreclr/ilasm/grammar_before.cpp
@@ -0,0 +1,137 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+#include <asmparse.h>
+#include <assembler.h>
+
+// Disable the "initialization of static local vars is no thread safe" error
+#ifdef _MSC_VER
+#pragma warning(disable : 4640)
+#endif
+
+#define YYMAXDEPTH 0x80000
+#define YYLOCAL int
+//#define YYRECURSIVE
+
+//#define DEBUG_PARSING
+#ifdef DEBUG_PARSING
+bool parseDBFlag = true;
+#define dbprintf(x) if (parseDBFlag) printf x
+#define YYDEBUG 1
+#else
+#define dbprintf(x)
+#endif
+
+#define FAIL_UNLESS(cond, msg) if (!(cond)) { parser->success = false; parser->error msg; }
+
+static AsmParse* parser = 0;
+#define PASM (parser->assem)
+#define PASMM (parser->assem->m_pManifest)
+#define PENV (parser->penv)
+
+
+
+PFN_NEXTCHAR nextchar;
+PFN_SYM Sym;
+PFN_NEWSTRFROMTOKEN NewStrFromToken;
+PFN_NEWSTATICSTRFROMTOKEN NewStaticStrFromToken;
+PFN_GETDOUBLE GetDouble;
+
+void SetFunctionPtrs()
+{
+ nextchar = PENV->pfn_nextchar;
+ Sym = PENV->pfn_Sym;
+ NewStrFromToken = PENV->pfn_NewStrFromToken;
+ NewStaticStrFromToken = PENV->pfn_NewStaticStrFromToken;
+ GetDouble = PENV->pfn_GetDouble;
+}
+
+
+static char* newStringWDel(__in __nullterminated char* str1, char delimiter, __in __nullterminated char* str3 = 0);
+static char* newString(__in __nullterminated const char* str1);
+static void corEmitInt(BinStr* buff, unsigned data);
+static void AppendStringWithLength(BinStr* pbs, __in __nullterminated char* sz);
+bool bParsingByteArray = FALSE;
+int iOpcodeLen = 0;
+int iCallConv = 0;
+unsigned IfEndif = 0;
+unsigned IfEndifSkip = 0;
+unsigned nCustomBlobNVPairs = 0;
+unsigned nSecAttrBlobs = 0;
+unsigned nCurrPC = 0;
+BOOL SkipToken = FALSE;
+BOOL neg = FALSE;
+BOOL newclass = FALSE;
+
+extern unsigned int g_uConsoleCP;
+
+struct VarName
+{
+ char* name;
+ BinStr* pbody;
+ VarName(__in_opt __nullterminated char* sz, BinStr* pbs) { name = sz; pbody = pbs; };
+ ~VarName() { delete [] name; delete pbody; };
+ int ComparedTo(VarName* pN) { return strcmp(name,pN->name); };
+};
+SORTEDARRAY<VarName> VarNameList;
+void DefineVar(__in __nullterminated char* sz, BinStr* pbs) { VarNameList.PUSH(new VarName(sz,pbs)); };
+void UndefVar(__in __nullterminated char* sz)
+{
+ CHECK_LOCAL_STATIC_VAR(static VarName VN(NULL,NULL));
+
+ VN.name = sz;
+ VarNameList.DEL(&VN);
+ VN.name = NULL;
+ delete [] sz;
+}
+VarName* FindVarDef(__in __nullterminated char* sz)
+{
+ CHECK_LOCAL_STATIC_VAR(static VarName VN(NULL,NULL));
+
+ VarName* Ret = NULL;
+ VN.name = sz;
+ Ret = VarNameList.FIND(&VN);
+ VN.name = NULL;
+ delete [] sz;
+ return Ret;
+}
+BOOL IsVarDefined(__in __nullterminated char* sz)
+{
+ return (FindVarDef(sz) != NULL);
+}
+
+int nTemp=0;
+
+unsigned int uMethodBeginLine,uMethodBeginColumn;
+
+#define ELEMENT_TYPE_VARFIXUP (ELEMENT_TYPE_MAX+2)
+#define ELEMENT_TYPE_MVARFIXUP (ELEMENT_TYPE_MAX+3)
+
+FIFO<char> TyParFixupList;
+void FixupTyPars(PCOR_SIGNATURE pSig, ULONG cSig);
+void FixupTyPars(BinStr* pbstype);
+void FixupConstraints()
+{
+ if((TyParFixupList.COUNT()) && (PASM->m_TyParList))
+ {
+ TyParList* pTPL;
+ for(pTPL = PASM->m_TyParList; pTPL; pTPL=pTPL->Next())
+ {
+ mdToken* ptk;
+ for(ptk = (mdToken*)(pTPL->Bound()->ptr()); *ptk; ptk++)
+ {
+ if(TypeFromToken(*ptk)==mdtTypeSpec)
+ {
+ PCOR_SIGNATURE pSig;
+ ULONG cSig;
+ PASM->m_pImporter->GetTypeSpecFromToken(*ptk,(PCCOR_SIGNATURE*)&pSig,&cSig);
+ if((pSig)&&(cSig))
+ {
+ FixupTyPars(pSig,cSig);
+ } // end if((pSig)&&(cSig))
+ } // end if(TypeFromToken(*ptk)==mdtTypeSpec)
+ } //end for(ptk
+ } // end for(pTPL
+ } //end if((TyParFixupList.COUNT())
+}
+
+#define SET_PA(x,y,z) {x = (CorAssemblyFlags)(((y) & ~afPA_FullMask)|(z)|afPA_Specified);}
diff --git a/src/coreclr/ilasm/ilasmpch.h b/src/coreclr/ilasm/ilasmpch.h
new file mode 100644
index 00000000000..ece4130ae57
--- /dev/null
+++ b/src/coreclr/ilasm/ilasmpch.h
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#if !defined(_ILASMPCH_H)
+#define _ILASMPCH_H
+#define NEW_INLINE_NAMES
+
+#include "cor.h" // for CorMethodAttr ...
+#include <crtdbg.h> // For _ASSERTE
+#include <corsym.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "utilcode.h"
+#include "debugmacros.h"
+#include "corpriv.h"
+
+#include "specstrings.h"
+#include <string.h> // for strcmp
+#include <ctype.h> // for isspace
+#include "openum.h" // for CEE_*
+#include <stdarg.h> // for vararg macros
+
+#include "mdfileformat.h"
+#include "stgpooli.h"
+
+#endif
diff --git a/src/coreclr/ilasm/main.cpp b/src/coreclr/ilasm/main.cpp
new file mode 100644
index 00000000000..82a93d7eb52
--- /dev/null
+++ b/src/coreclr/ilasm/main.cpp
@@ -0,0 +1,1010 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// File: main.cpp
+//
+
+//
+
+#include "ilasmpch.h"
+
+#include "asmparse.h"
+#include "clrversion.h"
+#include "shimload.h"
+
+#include "strsafe.h"
+#define ASSERTE_ALL_BUILDS(expr) _ASSERTE_ALL_BUILDS(__FILE__, (expr))
+
+WCHAR* EqualOrColon(__in __nullterminated WCHAR* szArg)
+{
+ WCHAR* pchE = wcschr(szArg,L'=');
+ WCHAR* pchC = wcschr(szArg,L':');
+ WCHAR* ret;
+ if(pchE == NULL) ret = pchC;
+ else if(pchC == NULL) ret = pchE;
+ else ret = (pchE < pchC)? pchE : pchC;
+ return ret;
+}
+
+static DWORD g_dwSubsystem=(DWORD)-1,g_dwComImageFlags=(DWORD)-1,g_dwFileAlignment=0,g_dwTestRepeat=0;
+static ULONGLONG g_stBaseAddress=0;
+static size_t g_stSizeOfStackReserve=0;
+extern unsigned int g_uConsoleCP;
+#ifdef TARGET_UNIX
+char * g_pszExeFile;
+#endif
+
+void MakeTestFile(__in __nullterminated char* szFileName)
+{
+ if(g_dwTestRepeat)
+ {
+ FILE* pF = NULL;
+ if(fopen_s(&pF,szFileName,"wt")==0 && pF != NULL)
+ {
+ printf("Making test file\n");
+ fprintf(pF,".assembly extern mscorlib {}\n");
+ fprintf(pF,".assembly test%d {}\n",g_dwTestRepeat);
+ fprintf(pF,".module test%d.exe\n",g_dwTestRepeat);
+ fprintf(pF,".method public static void Exec() { .entrypoint\n");
+ for(unsigned i=0; i<g_dwTestRepeat*1000; i++)
+ {
+ fprintf(pF,"ldc.i4.1\ncall void [mscorlib]System.Console::WriteLine(int32)\n");
+ }
+ fprintf(pF,"ret }\n");
+ fclose(pF);
+ }
+ }
+}
+
+void MakeProperSourceFileName(__in __nullterminated WCHAR* wzOrigName,
+ unsigned uCodePage,
+ __out_ecount(MAX_FILENAME_LENGTH) WCHAR* wzProperName,
+ __out_ecount(MAX_FILENAME_LENGTH*3) char* szProperName)
+{
+ wcscpy_s(wzProperName,MAX_FILENAME_LENGTH, wzOrigName);
+ size_t j = wcslen(wzProperName);
+ do
+ {
+ j--;
+ if(wzProperName[j] == '.') break;
+ if((wzProperName[j] == DIRECTORY_SEPARATOR_CHAR_A)||(j == 0))
+ {
+ wcscat_s(wzProperName,MAX_FILENAME_LENGTH,W(".il"));
+ break;
+ }
+ }
+ while(j);
+ WszWideCharToMultiByte(uCodePage,0,wzProperName,-1,szProperName,MAX_FILENAME_LENGTH*3-1,NULL,NULL);
+}
+
+char* FullFileName(__in __nullterminated WCHAR* wzFileName, unsigned uCodePage)
+{
+ static WCHAR wzFullPath[MAX_FILENAME_LENGTH];
+ WCHAR* pwz;
+ WszGetFullPathName(wzFileName,MAX_FILENAME_LENGTH,wzFullPath,&pwz);
+ char szFullPath[MAX_FILENAME_LENGTH*3];
+ WszWideCharToMultiByte(uCodePage,0,wzFullPath,-1,szFullPath,MAX_FILENAME_LENGTH*3-1,NULL,NULL);
+ char* sz = new char[strlen(szFullPath)+1];
+ if(sz) strcpy_s(sz,strlen(szFullPath)+1,szFullPath);
+ return sz;
+}
+
+WCHAR *pwzInputFiles[1024];
+WCHAR *pwzDeltaFiles[1024];
+
+char szInputFilename[MAX_FILENAME_LENGTH*3];
+WCHAR wzInputFilename[MAX_FILENAME_LENGTH];
+WCHAR wzOutputFilename[MAX_FILENAME_LENGTH];
+WCHAR wzPdbFilename[MAX_FILENAME_LENGTH];
+
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
+
+extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
+{
+ int i, NumFiles = 0, NumDeltaFiles = 0;
+ bool IsDLL = false, IsOBJ = false;
+ Assembler *pAsm;
+ MappedFileStream *pIn;
+ AsmParse *pParser;
+ int exitval=1;
+ bool bLogo = TRUE;
+ bool bReportProgress = TRUE;
+ BOOL bGeneratePdb = FALSE;
+ PdbFormat pdbFormat = CLASSIC;
+ WCHAR* wzIncludePath = NULL;
+ int exitcode = 0;
+ unsigned uCodePage;
+
+ bool bClock = false;
+ Clockwork cw;
+
+#ifdef HOST_WINDOWS
+ // SWI has requested that the exact form of the function call below be used. For details
+ // see http://swi/SWI%20Docs/Detecting%20Heap%20Corruption.doc
+ (void)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+#endif
+
+ memset(pwzInputFiles,0,1024*sizeof(WCHAR*));
+ memset(pwzDeltaFiles,0,1024*sizeof(WCHAR*));
+ memset(&cw,0,sizeof(Clockwork));
+ cw.cBegin = GetTickCount();
+
+ g_uConsoleCP = GetConsoleOutputCP();
+ memset(wzOutputFilename,0,sizeof(wzOutputFilename));
+ memset(wzPdbFilename, 0, sizeof(wzPdbFilename));
+
+#ifdef _DEBUG
+ DisableThrowCheck();
+ //CONTRACT_VIOLATION(ThrowsViolation);
+#endif
+
+ if(argc < 2) goto ErrorExit;
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:26000) // "Suppress prefast warning about index overflow"
+#endif
+ if (! wcscmp(argv[1], W("/?")) || ! wcscmp(argv[1],W("-?")))
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+ {
+ printf("\nMicrosoft (R) .NET IL Assembler version " CLR_PRODUCT_VERSION);
+ printf("\n%S\n\n", VER_LEGALCOPYRIGHT_LOGO_STR_L);
+ goto PrintUsageAndExit;
+
+ ErrorExit:
+ exitcode = 1;
+ PrintUsageAndExit:
+ printf("\n\nUsage: ilasm [Options] <sourcefile> [Options]");
+ printf("\n\nOptions:");
+ printf("\n/NOLOGO Don't type the logo");
+ printf("\n/QUIET Don't report assembly progress");
+ printf("\n/NOAUTOINHERIT Disable inheriting from System.Object by default");
+ printf("\n/DLL Compile to .dll");
+ printf("\n/EXE Compile to .exe (default)");
+ printf("\n/PDB Create the PDB file without enabling debug info tracking");
+ printf("\n/PDBFMT=CLASSIC Use classic PDB format for PDB file generation (default)");
+ printf("\n/PDBFMT=PORTABLE Use portable PDB format for PDB file generation");
+ printf("\n/APPCONTAINER Create an AppContainer exe or dll");
+ printf("\n/DEBUG Disable JIT optimization, create PDB file, use sequence points from PDB");
+ printf("\n/DEBUG=IMPL Disable JIT optimization, create PDB file, use implicit sequence points");
+ printf("\n/DEBUG=OPT Enable JIT optimization, create PDB file, use implicit sequence points");
+ printf("\n/OPTIMIZE Optimize long instructions to short");
+ printf("\n/FOLD Fold the identical method bodies into one");
+ printf("\n/CLOCK Measure and report compilation times");
+// printf("\n/ERROR Try to create .exe or .dll file despite errors reported");
+// printf("\n Warning! Results are unpredictable, use this option at your own risk!");
+ printf("\n/OUTPUT=<targetfile> Compile to file with specified name \n\t\t\t(user must provide extension, if any)");
+ printf("\n/KEY=<keyfile> Compile with strong signature \n\t\t\t(<keyfile> contains private key)");
+ printf("\n/KEY=@<keysource> Compile with strong signature \n\t\t\t(<keysource> is the private key source name)");
+ printf("\n/INCLUDE=<path> Set path to search for #include'd files");
+ printf("\n/SUBSYSTEM=<int> Set Subsystem value in the NT Optional header");
+ printf("\n/SSVER=<int>.<int> Set Subsystem version number in the NT Optional header");
+ printf("\n/FLAGS=<int> Set CLR ImageFlags value in the CLR header");
+ printf("\n/ALIGNMENT=<int> Set FileAlignment value in the NT Optional header");
+ printf("\n/BASE=<int> Set ImageBase value in the NT Optional header (max 2GB for 32-bit images)");
+ printf("\n/STACK=<int> Set SizeOfStackReserve value in the NT Optional header");
+ printf("\n/MDV=<version_string> Set Metadata version string");
+ printf("\n/MSV=<int>.<int> Set Metadata stream version (<major>.<minor>)");
+ printf("\n/PE64 Create a 64bit image (PE32+)");
+ printf("\n/HIGHENTROPYVA Set High Entropy Virtual Address capable PE32+ images (default for /APPCONTAINER)");
+ printf("\n/NOCORSTUB Suppress generation of CORExeMain stub");
+ printf("\n/STRIPRELOC Indicate that no base relocations are needed");
+ printf("\n/X64 Target processor: 64bit AMD processor");
+ printf("\n/ARM Target processor: ARM (AArch32) processor");
+ printf("\n/ARM64 Target processor: ARM64 (AArch64) processor");
+ printf("\n/32BITPREFERRED Create a 32BitPreferred image (PE32)");
+ printf("\n/ENC=<file> Create Edit-and-Continue deltas from specified source file");
+
+ printf("\n\nKey may be '-' or '/'\nOptions are recognized by first 3 characters (except ARM/ARM64)\nDefault source file extension is .il\n");
+
+ printf("\nTarget defaults:");
+ printf("\n/PE64 => /PE64 /X64");
+ printf("\n/X64 => /PE64 /X64");
+ printf("\n/ARM64 => /PE64 /ARM64");
+
+ printf("\n\n");
+ exit(exitcode);
+ }
+
+ uCodePage = CP_UTF8;
+ WszSetEnvironmentVariable(W("COMP_ENC_OPENSCOPE"), W(""));
+ WszSetEnvironmentVariable(W("COMP_ENC_EMIT"), W(""));
+ if((pAsm = new Assembler()))
+ {
+ pAsm->SetCodePage(uCodePage);
+ //if(pAsm->Init())
+ {
+ pAsm->SetStdMapping(1);
+ //-------------------------------------------------
+ for (i = 1; i < argc; i++)
+ {
+#ifdef TARGET_UNIX
+ if(argv[i][0] == L'-')
+#else
+ if((argv[i][0] == L'/') || (argv[i][0] == L'-'))
+#endif
+ {
+ char szOpt[3 + 1] = { 0 };
+ WszWideCharToMultiByte(uCodePage, 0, &argv[i][1], 3, szOpt, sizeof(szOpt), NULL, NULL);
+ if (!_stricmp(szOpt, "NOA"))
+ {
+ pAsm->m_fAutoInheritFromObject = FALSE;
+ }
+ else if (!_stricmp(szOpt, "QUI"))
+ {
+ pAsm->m_fReportProgress = FALSE;
+ bReportProgress = FALSE;
+ bLogo = FALSE;
+ }
+ else if (!_stricmp(szOpt, "NOL"))
+ {
+ bLogo = FALSE;
+ }
+ else if (!_stricmp(szOpt, "FOL"))
+ {
+ pAsm->m_fFoldCode = TRUE;
+ }
+ else if (!_stricmp(szOpt, "DEB"))
+ {
+ bGeneratePdb = TRUE;
+
+ pAsm->m_dwIncludeDebugInfo = 0x101;
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr != NULL)
+ {
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no suboption
+ else
+ {
+ WCHAR wzSubOpt[8];
+ wcsncpy_s(wzSubOpt,8,pStr,3);
+ wzSubOpt[3] = 0;
+ if(0 == _wcsicmp(wzSubOpt,W("OPT")))
+ pAsm->m_dwIncludeDebugInfo = 0x3;
+ else if(0 == _wcsicmp(wzSubOpt,W("IMP")))
+ pAsm->m_dwIncludeDebugInfo = 0x103;
+ else
+ {
+ const WCHAR *pFmt =((*pStr == '0')&&(*(pStr+1) == 'x'))? W("%lx") : W("%ld");
+ if(swscanf_s(pStr,pFmt,&(pAsm->m_dwIncludeDebugInfo))!=1)
+ goto InvalidOption; // bad subooption
+ }
+ }
+ }
+ }
+ else if (!_stricmp(szOpt, "PDB"))
+ {
+ bGeneratePdb = TRUE;
+
+ // check for /PDBFMT= command line option
+ char szOpt2[3 + 1] = { 0 };
+ WszWideCharToMultiByte(uCodePage, 0, &argv[i][4], 3, szOpt2, sizeof(szOpt2), NULL, NULL);
+ if (!_stricmp(szOpt2, "FMT"))
+ {
+ WCHAR* pStr = EqualOrColon(argv[i]);
+ if (pStr != NULL)
+ {
+ for (pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if (wcslen(pStr) == 0)
+ {
+ goto InvalidOption; //if no suboption
+ }
+ else
+ {
+ WCHAR wzSubOpt[8 + 1];
+ wcsncpy_s(wzSubOpt, 8 + 1, pStr, 8);
+ wzSubOpt[8] = 0;
+ if (0 == _wcsicmp(wzSubOpt, W("CLASSIC")))
+ pdbFormat = CLASSIC;
+ else if (0 == _wcsicmp(wzSubOpt, W("PORTABLE")))
+ pdbFormat = PORTABLE;
+ else
+ goto InvalidOption; // bad subooption
+ }
+ }
+ else
+ {
+ goto InvalidOption; // bad subooption
+ }
+ }
+ else if (*szOpt2)
+ {
+ goto InvalidOption; // bad subooption
+ }
+ }
+ else if (!_stricmp(szOpt, "CLO"))
+ {
+ bClock = true;
+ pAsm->SetClock(&cw);
+ }
+ else if (!_stricmp(szOpt, "DLL"))
+ {
+ IsDLL = true; IsOBJ = false;
+ }
+ else if (!_stricmp(szOpt, "OBJ"))
+ {
+ //IsOBJ = true; IsDLL = false;
+ printf("Option /OBJECT is not supported.\n");
+ goto ErrorExit;
+ }
+ else if (!_stricmp(szOpt, "ERR"))
+ {
+ pAsm->OnErrGo = true;
+ }
+ else if (!_stricmp(szOpt, "EXE"))
+ {
+ IsDLL = false;
+ }
+ else if (!_stricmp(szOpt, "APP"))
+ {
+ pAsm->m_fAppContainer = TRUE;
+ }
+ else if (!_stricmp(szOpt, "HIG"))
+ {
+ pAsm->m_fHighEntropyVA = TRUE;
+ }
+ else if (!_stricmp(szOpt, "OPT"))
+ {
+ pAsm->m_fOptimize = TRUE;
+ }
+ else if (!_stricmp(szOpt, "X64"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_AMD64;
+ }
+ else if (!_stricmp(szOpt, "ARM"))
+ {
+ // szOpt is only 3 characters long. That is not enough to distinguish "ARM" and "ARM64".
+ // We could change it to be longer, but that would affect the existing usability (ARM64 was
+ // added much later). Thus, just distinguish the two here.
+ char szOpt2[5 + 1] = { 0 };
+ WszWideCharToMultiByte(uCodePage, 0, &argv[i][1], 5, szOpt2, sizeof(szOpt2), NULL, NULL);
+ if (!_stricmp(szOpt2, "ARM"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_ARM;
+ }
+ else if (!_stricmp(szOpt2, "ARM64"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_ARM64;
+ }
+ else
+ {
+ goto InvalidOption;
+ }
+ }
+ else if (!_stricmp(szOpt, "32B"))
+ {
+ if (g_dwComImageFlags == (DWORD)-1)
+ g_dwComImageFlags = pAsm->m_dwComImageFlags;
+ COR_SET_32BIT_PREFERRED(g_dwComImageFlags);
+ }
+ else if (!_stricmp(szOpt, "PE6"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_FILE_PE32;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_FILE_PE64;
+ }
+ else if (!_stricmp(szOpt, "NOC"))
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_FILE_CORMAIN_STUB;
+ }
+ else if (!_stricmp(szOpt, "STR"))
+ {
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_FILE_STRIP_RELOCS;
+ }
+ else if (!_stricmp(szOpt, "OPT"))
+ {
+ pAsm->m_fOptimize = TRUE;
+ }
+ else if (!_stricmp(szOpt, "LIS"))
+ {
+ printf("Option /LISTING is not supported, use ILDASM.EXE\n");
+ }
+ else if (!_stricmp(szOpt, "RES"))
+ {
+ if(pAsm->m_wzResourceFile==NULL)
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto ErrorExit;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no file name
+ pAsm->m_wzResourceFile = pStr;
+ }
+ else
+ printf("Multiple resource files not allowed. Option %ls skipped\n",argv[i]);
+ }
+ else if (!_stricmp(szOpt, "KEY"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no file name
+ pAsm->m_wzKeySourceName = pStr;
+ }
+ else if (!_stricmp(szOpt, "INC"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no file name
+ wzIncludePath = pStr;
+ }
+ else if (!_stricmp(szOpt, "OUT"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no file name
+ if(wcslen(pStr) >= MAX_FILENAME_LENGTH)
+ {
+ fprintf(stderr,"\nError: Output file name exceeds %d characters\n",MAX_FILENAME_LENGTH-1);
+ goto ErrorExit;
+ }
+ wcscpy_s(wzOutputFilename,MAX_FILENAME_LENGTH,pStr);
+ }
+ else if (!_stricmp(szOpt, "MDV"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no version string
+ pAsm->m_wzMetadataVersion = pStr;
+ }
+ else if (!_stricmp(szOpt, "MSV"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no version
+ {
+ int major=-1,minor=-1;
+ if(swscanf_s(pStr,W("%d.%d"),&major, &minor)==2)
+ {
+ if((major >= 0)&&(major < 0xFF))
+ pAsm->m_wMSVmajor = (WORD)major;
+ if((minor >= 0)&&(minor < 0xFF))
+ pAsm->m_wMSVminor = (WORD)minor;
+ }
+ }
+ }
+ else if (!_stricmp(szOpt, "ENC"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no file name
+ pwzDeltaFiles[NumDeltaFiles++] = pStr;
+ pAsm->m_fTolerateDupMethods = TRUE;
+ }
+ else if (!_stricmp(szOpt, "SUB"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ const WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? W("%lx") : W("%ld");
+ if(swscanf_s(pStr,pFmt,&g_dwSubsystem)!=1) goto InvalidOption;
+ }
+ else if (!_stricmp(szOpt, "SSV"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ for(pStr++; *pStr == L' '; pStr++); //skip the blanks
+ if(wcslen(pStr)==0) goto InvalidOption; //if no version
+ {
+ int major=-1,minor=-1;
+ if(swscanf_s(pStr,W("%d.%d"),&major, &minor)==2)
+ {
+ if((major >= 0)&&(major < 0xFFFF))
+ pAsm->m_wSSVersionMajor = (WORD)major;
+ if((minor >= 0)&&(minor < 0xFFFF))
+ pAsm->m_wSSVersionMinor = (WORD)minor;
+ } else
+ goto InvalidOption;
+ }
+ }
+ else if (!_stricmp(szOpt, "ALI"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ const WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? W("%lx") : W("%ld");
+ if(swscanf_s(pStr,pFmt,&g_dwFileAlignment)!=1) goto InvalidOption;
+ if((g_dwFileAlignment & (g_dwFileAlignment-1))
+ || (g_dwFileAlignment < 0x200) || (g_dwFileAlignment > 0x10000))
+ {
+ fprintf(stderr,"\nFile Alignment must be power of 2 from 0x200 to 0x10000\n");
+ if(!pAsm->OnErrGo) goto InvalidOption;
+ }
+ }
+ else if (!_stricmp(szOpt, "FLA"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ const WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? W("%lx") : W("%ld");
+ if(swscanf_s(pStr,pFmt,&g_dwComImageFlags)!=1) goto InvalidOption;
+ }
+ else if (!_stricmp(szOpt, "BAS"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ const WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? W("%I64x") : W("%I64d");
+ if(swscanf_s(pStr,pFmt,&g_stBaseAddress)!=1) goto InvalidOption;
+ if(g_stBaseAddress & 0xFFFF)
+ {
+ fprintf(stderr,"\nBase address must be 0x10000-aligned\n");
+ if(!pAsm->OnErrGo) goto InvalidOption;
+ }
+ }
+ else if (!_stricmp(szOpt, "STA"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ const WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? W("%lx") : W("%ld");
+ if(swscanf_s(pStr,pFmt,&g_stSizeOfStackReserve)!=1) goto InvalidOption;
+ }
+#ifdef _SPECIAL_INTERNAL_USE_ONLY
+ else if (!_stricmp(szOpt, "TES"))
+ {
+ WCHAR *pStr = EqualOrColon(argv[i]);
+ if(pStr == NULL) goto InvalidOption;
+ pStr++;
+ WCHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? L"%lx" : L"%ld";
+ if(swscanf_s(pStr,pFmt,&g_dwTestRepeat)!=1) goto InvalidOption;
+ }
+#endif
+ else
+ {
+ InvalidOption:
+ fprintf(stderr, "Error : Invalid Option: %LS\n", argv[i]);
+ goto ErrorExit;
+ }
+ }
+ else
+ {
+ if(wcslen(argv[i]) >= MAX_FILENAME_LENGTH)
+ {
+ printf("\nError: Input file name exceeds %d characters\n",MAX_FILENAME_LENGTH-1);
+ goto ErrorExit;
+ }
+ pwzInputFiles[NumFiles++] = argv[i];
+ if(NumFiles == 1)
+ {
+ MakeProperSourceFileName(argv[i], uCodePage, wzInputFilename, szInputFilename);
+ }
+ }
+
+ }
+ if(NumFiles == 0)
+ {
+ delete pAsm;
+ goto ErrorExit;
+ }
+ if(pAsm->m_dwCeeFileFlags & ICEE_CREATE_FILE_PE64)
+ {
+ if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ ||(pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM))
+ {
+ printf("\nMachine type /ARM64 or /X64 must be specified for 64 bit targets.");
+ if(!pAsm->OnErrGo)
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_MACHINE_AMD64;
+ printf(" Type set to X64.");
+ }
+ printf("\n");
+ }
+ }
+ else
+ {
+ if((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM64)
+ ||(pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_AMD64))
+ {
+ printf("\n64 bit target must be specified for machine type /ARM64 or /X64.");
+ if(!pAsm->OnErrGo)
+ {
+ pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_FILE_PE32;
+ pAsm->m_dwCeeFileFlags |= ICEE_CREATE_FILE_PE64;
+ printf(" Target set to 64 bit.");
+ }
+ printf("\n");
+ }
+ }
+ if(pAsm->m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32)
+ {
+ if(g_stBaseAddress > 0x80000000)
+ {
+ fprintf(stderr,"Invalid Image Base specified for 32-bit target\n");
+ delete pAsm;
+ goto ErrorExit;
+ }
+ }
+ if (COR_IS_32BIT_PREFERRED(pAsm->m_dwComImageFlags) &&
+ ((pAsm->m_dwCeeFileFlags & ICEE_CREATE_FILE_PE64) ||
+ ((pAsm->m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32) == 0) ||
+ ((pAsm->m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386) == 0) ||
+ ((pAsm->m_dwComImageFlags & COMIMAGE_FLAGS_ILONLY) == 0)))
+ {
+ fprintf(stderr,"/32BITPREFERRED valid only with PE32/X86/ILONLY images\n");
+ delete pAsm;
+ goto ErrorExit;
+ }
+ if (bGeneratePdb && CLASSIC == pdbFormat)
+ {
+ // Classic PDB format is not supported on CoreCLR
+ // https://github.com/dotnet/runtime/issues/5051
+
+ printf("WARNING: Classic PDB format is not supported on CoreCLR.\n");
+ printf("Use '/PDBFMT=PORTABLE' option in order to generate portable PDB format. \n");
+ }
+ if (!pAsm->Init(bGeneratePdb, pdbFormat))
+ {
+ fprintf(stderr,"Failed to initialize Assembler\n");
+ delete pAsm;
+ goto ErrorExit;
+ }
+ if(g_dwTestRepeat)
+ MakeTestFile(szInputFilename);
+
+ if(wzOutputFilename[0] == 0)
+ {
+ wcscpy_s(wzOutputFilename,MAX_FILENAME_LENGTH,pwzInputFiles[0]);
+ size_t j = wcslen(wzOutputFilename);
+ do
+ {
+ j--;
+ if(wzOutputFilename[j] == L'.')
+ {
+ wzOutputFilename[j] = 0;
+ break;
+ }
+ }
+ while(j);
+ wcscat_s(wzOutputFilename, MAX_FILENAME_LENGTH,(IsDLL ? W(".dll") : (IsOBJ ? W(".obj") : W(".exe"))));
+ }
+ if (pAsm->m_fGeneratePDB)
+ {
+ wcscpy_s(wzPdbFilename, MAX_FILENAME_LENGTH, wzOutputFilename);
+ WCHAR* extPos = wcsrchr(wzPdbFilename, L'.');
+ if (extPos != NULL)
+ *extPos = 0;
+ wcscat_s(wzPdbFilename, MAX_FILENAME_LENGTH, W(".pdb"));
+ char* pszPdbFilename = FullFileName(wzPdbFilename, uCodePage);
+ pAsm->SetPdbFileName(pszPdbFilename);
+ delete[] pszPdbFilename;
+ }
+ if(wzIncludePath == NULL)
+ {
+ PathString wzIncludePathBuffer;
+ if (0 != WszGetEnvironmentVariable(W("ILASM_INCLUDE"), wzIncludePathBuffer))
+ {
+ wzIncludePath = wzIncludePathBuffer.GetCopyOfUnicodeString();
+
+ }
+ }
+ //------------ Assembler initialization done. Now, to business -----------------------
+ if((pParser = new AsmParse(NULL, pAsm)))
+ {
+ uCodePage = CP_UTF8;
+ pAsm->SetCodePage(uCodePage);
+ pParser->SetIncludePath(wzIncludePath);
+ //======================================================================
+ if(bLogo)
+ {
+ printf("\nMicrosoft (R) .NET IL Assembler. Version " CLR_PRODUCT_VERSION);
+ printf("\n%S", VER_LEGALCOPYRIGHT_LOGO_STR_L);
+ }
+
+ pAsm->SetDLL(IsDLL);
+ pAsm->SetOBJ(IsOBJ);
+ wcscpy_s(pAsm->m_wzOutputFileName,MAX_FILENAME_LENGTH,wzOutputFilename);
+ strcpy_s(pAsm->m_szSourceFileName,MAX_FILENAME_LENGTH*3+1,szInputFilename);
+
+ if (SUCCEEDED(pAsm->InitMetaData()))
+ {
+ int iFile;
+ BOOL fAllFilesPresent = TRUE;
+ if(bClock) cw.cParsBegin = GetTickCount();
+ for(iFile = 0; iFile < NumFiles; iFile++)
+ {
+ uCodePage = CP_UTF8;
+ pAsm->SetCodePage(uCodePage);
+ if(iFile) // for the first file, it's already done
+ {
+ MakeProperSourceFileName(pwzInputFiles[iFile], uCodePage, wzInputFilename, szInputFilename);
+ }
+ if(pAsm->m_fReportProgress)
+ {
+ pParser->msg("\nAssembling '%s' ", szInputFilename);
+ if(pAsm->m_fCPlusPlus) pParser->msg(" C++");
+ if(pAsm->m_fWindowsCE) pParser->msg(" WINCE");
+ if(!pAsm->m_fAutoInheritFromObject) pParser->msg(" NOAUTOINHERIT");
+ pParser->msg(IsDLL ? " to DLL" : (IsOBJ? " to OBJ" : " to EXE"));
+ //======================================================================
+ if (pAsm->m_fStdMapping == FALSE)
+ pParser->msg(", with REFERENCE mapping");
+
+ {
+ char szOutputFilename[MAX_FILENAME_LENGTH*3];
+ memset(szOutputFilename,0,sizeof(szOutputFilename));
+ WszWideCharToMultiByte(uCodePage,0,wzOutputFilename,-1,szOutputFilename,MAX_FILENAME_LENGTH*3-1,NULL,NULL);
+ pParser->msg(" --> '%s'\n", szOutputFilename);
+ }
+ }
+
+ pIn = new MappedFileStream(wzInputFilename);
+
+ if ((!pIn) || !(pIn->IsValid()))
+ {
+ pParser->msg("Could not open %s\n", szInputFilename);
+ fAllFilesPresent = FALSE;
+ }
+ else
+ {
+#ifndef TARGET_UNIX
+ DWORD dwBinType;
+ if(GetBinaryTypeA(szInputFilename,&dwBinType))
+ {
+ pParser->msg("%s is not a text file\n",szInputFilename);
+ fAllFilesPresent = FALSE;
+ }
+ else
+#endif
+ {
+ pAsm->SetSourceFileName(FullFileName(wzInputFilename,uCodePage)); // deletes the argument!
+
+ pParser->ParseFile(pIn);
+ }
+ }
+ if(pIn)
+ {
+ pIn->set_namew(NULL);
+ delete pIn;
+ }
+ } // end for(iFile)
+ if(bClock) cw.cParsEnd = GetTickCount();
+ if ((pParser->Success() && fAllFilesPresent) || pAsm->OnErrGo)
+ {
+ HRESULT hr;
+ if(g_dwSubsystem != (DWORD)-1) pAsm->m_dwSubsystem = g_dwSubsystem;
+ if(g_dwComImageFlags != (DWORD)-1) pAsm->m_dwComImageFlags = g_dwComImageFlags;
+ if(g_dwFileAlignment) pAsm->m_dwFileAlignment = g_dwFileAlignment;
+ if(g_stBaseAddress) pAsm->m_stBaseAddress = g_stBaseAddress;
+ if(g_stSizeOfStackReserve) pAsm->m_stSizeOfStackReserve = g_stSizeOfStackReserve;
+ if(FAILED(hr=pAsm->CreatePEFile(wzOutputFilename)))
+ pParser->msg("Could not create output file, error code=0x%08X\n",hr);
+ else
+ {
+ if(pAsm->m_fFoldCode && pAsm->m_fReportProgress)
+ pParser->msg("%d methods folded\n",pAsm->m_dwMethodsFolded);
+ if(pParser->Success() && fAllFilesPresent) exitval = 0;
+ else
+ {
+ pParser->msg("Output file contains errors\n");
+ if(pAsm->OnErrGo) exitval = 0;
+ }
+ if(exitval == 0) // Write the output file
+ {
+ if(bClock) cw.cFilegenEnd = GetTickCount();
+ if(pAsm->m_fReportProgress) pParser->msg("Writing %s file\n", pAsm->m_fOBJ ? "COFF" : "PE");
+ // Generate the file
+ if (FAILED(hr = pAsm->m_pCeeFileGen->GenerateCeeFile(pAsm->m_pCeeFile)))
+ {
+ exitval = 1;
+ pParser->msg("Failed to write output file, error code=0x%08X\n",hr);
+ }
+ // Generate PDB file
+ if (pAsm->m_fGeneratePDB)
+ {
+ if (pAsm->m_fReportProgress) pParser->msg("Writing PDB file: %s\n", pAsm->m_szPdbFileName);
+ if (FAILED(hr = pAsm->SavePdbFile()))
+ {
+ exitval = 1;
+ pParser->msg("Failed to write PDB file, error code=0x%08X\n", hr);
+ }
+ }
+ if(bClock) cw.cEnd = GetTickCount();
+#define ENC_ENABLED
+ if(exitval==0)
+ {
+ pAsm->m_fENCMode = TRUE;
+ WCHAR wzNewOutputFilename[MAX_FILENAME_LENGTH+16];
+ for(iFile = 0; iFile < NumDeltaFiles; iFile++)
+ {
+ wcscpy_s(wzNewOutputFilename,MAX_FILENAME_LENGTH+16,wzOutputFilename);
+ exitval = _snwprintf_s(&wzNewOutputFilename[wcslen(wzNewOutputFilename)], 32, _TRUNCATE,
+ W(".%d"),iFile+1);
+ MakeProperSourceFileName(pwzDeltaFiles[iFile], uCodePage, wzInputFilename, szInputFilename);
+ if(pAsm->m_fReportProgress)
+ {
+ pParser->msg("\nAssembling delta '%s' ", szInputFilename);
+ if(pAsm->m_fCPlusPlus) pParser->msg(" C++");
+ if(pAsm->m_fWindowsCE) pParser->msg(" WINCE");
+ if(!pAsm->m_fAutoInheritFromObject) pParser->msg(" NOAUTOINHERIT");
+ pParser->msg(" to DMETA,DIL");
+ //======================================================================
+ if (pAsm->m_fStdMapping == FALSE)
+ pParser->msg(", with REFERENCE mapping");
+
+ pParser->msg(" --> '%S.*'\n", wzNewOutputFilename);
+ }
+ exitval = 0;
+ pIn = new MappedFileStream(wzInputFilename);
+
+ if ((!pIn) || !(pIn->IsValid()))
+ {
+ pParser->msg("Could not open %s\n", szInputFilename);
+ fAllFilesPresent = FALSE;
+ }
+ else
+ {
+#ifndef TARGET_UNIX
+ DWORD dwBinType;
+ if(GetBinaryTypeA(szInputFilename,&dwBinType))
+ {
+ pParser->msg("%s is not a text file\n",szInputFilename);
+ fAllFilesPresent = FALSE;
+ }
+ else
+#endif
+ if (SUCCEEDED(pAsm->InitMetaDataForENC(wzNewOutputFilename, bGeneratePdb, pdbFormat)))
+ {
+ pAsm->SetSourceFileName(FullFileName(wzInputFilename,uCodePage)); // deletes the argument!
+
+ pParser->ParseFile(pIn);
+ if (pParser->Success() || pAsm->OnErrGo)
+ {
+ exitval = 1;
+ if(FAILED(hr=pAsm->CreateDeltaFiles(wzNewOutputFilename)))
+ pParser->msg("Could not create output delta files, error code=0x%08X\n",hr);
+ else
+ {
+ if(pAsm->m_fFoldCode && pAsm->m_fReportProgress)
+ pParser->msg("%d methods folded\n",pAsm->m_dwMethodsFolded);
+ if(pParser->Success()) exitval = 0;
+ else pParser->msg("Output delta files contain errors\n");
+
+#ifdef GENERATE_SUMMARY_PE_FILE
+ if(pAsm->OnErrGo) exitval = 0;
+
+ //if(FAILED(hr=pAsm->CreatePEFile(wzOutputFilename)))
+ // pParser->msg("Could not create output file, error code=0x%08X\n",hr);
+ //else
+ {
+ if(pAsm->m_fReportProgress) pParser->msg("Writing %s file\n", pAsm->m_fOBJ ? "COFF" : "PE");
+ // Generate the file
+ if (FAILED(hr = pAsm->m_pCeeFileGen->GenerateCeeFile(pAsm->m_pCeeFile)))
+ {
+ exitval = 1;
+ pParser->msg("Failed to write output file, error code=0x%08X\n",hr);
+ }
+ else if (pAsm->m_pManifest->m_sStrongName.m_fFullSign)
+ {
+ // Strong name sign the resultant assembly.
+ if(pAsm->m_fReportProgress) pParser->msg("Signing file with strong name\n");
+ if (FAILED(hr=pAsm->StrongNameSign()))
+ {
+ exitval = 1;
+ pParser->msg("Failed to strong name sign output file, error code=0x%08X\n",hr);
+ }
+ }
+ }
+#endif
+ }
+ } // end if (pParser->Success() || pAsm->OnErrGo)
+ } //end if (SUCCEEDED(pAsm->InitMetaDataForENC()))
+ } // end if ((!pIn) || !(pIn->IsValid())) -- else
+ if(pIn)
+ {
+ pIn->set_namew(NULL);
+ delete pIn;
+ }
+ } // end for(iFile)
+ } // end if(exitval==0)
+ }
+
+ }
+ }
+ }
+ else pParser->msg("Failed to initialize Meta Data\n");
+ delete pParser;
+ }
+ else printf("Could not create parser\n");
+ }
+ //else printf("Failed to initialize Assembler\n");
+ delete pAsm;
+ }
+ else printf("Insufficient memory\n");
+
+ WszSetEnvironmentVariable(W("COMP_ENC_OPENSCOPE"), W(""));
+ WszSetEnvironmentVariable(W("COMP_ENC_EMIT"), W(""));
+
+ if (exitval || !bGeneratePdb)
+ {
+ // PE file was not created, or no debug info required. Kill PDB if any
+ WCHAR* pc = wcsrchr(wzOutputFilename,L'.');
+ if(pc==NULL)
+ {
+ pc = &wzOutputFilename[wcslen(wzOutputFilename)];
+ *pc = L'.';
+ }
+ wcscpy_s(pc+1,4,W("PDB"));
+#undef DeleteFileW
+ DeleteFileW(wzOutputFilename);
+ }
+ if (exitval == 0)
+ {
+ if(bReportProgress) printf("Operation completed successfully\n");
+ if(bClock)
+ {
+ printf("Timing (msec): Total run %d\n",(cw.cEnd-cw.cBegin));
+ printf(" Startup %d\n",(cw.cParsBegin-cw.cBegin));
+ printf(" - MD initialization %d\n",(cw.cMDInitEnd - cw.cMDInitBegin));
+ printf(" Parsing %d\n",(cw.cParsEnd - cw.cParsBegin));
+ printf(" Emitting MD %d\n",(cw.cMDEmitEnd - cw.cRef2DefEnd)+(cw.cRef2DefBegin - cw.cMDEmitBegin));
+ //printf(" - global fixups %d\n",(cw.cMDEmit1 - cw.cMDEmitBegin));
+ printf(" - SN sig alloc %d\n",(cw.cMDEmit2 - cw.cMDEmitBegin));
+ printf(" - Classes,Methods,Fields %d\n",(cw.cRef2DefBegin - cw.cMDEmit2));
+ printf(" - Events,Properties %d\n",(cw.cMDEmit3 - cw.cRef2DefEnd));
+ printf(" - MethodImpls %d\n",(cw.cMDEmit4 - cw.cMDEmit3));
+ printf(" - Manifest,CAs %d\n",(cw.cMDEmitEnd - cw.cMDEmit4));
+ printf(" Ref to Def resolution %d\n",(cw.cRef2DefEnd - cw.cRef2DefBegin));
+ printf(" Fixup and linking %d\n",(cw.cFilegenBegin - cw.cMDEmitEnd));
+ printf(" CEE file generation %d\n",(cw.cFilegenEnd - cw.cFilegenBegin));
+ printf(" PE file writing %d\n",(cw.cEnd - cw.cFilegenEnd));
+ }
+ }
+ else
+ {
+ printf("\n***** FAILURE ***** \n");
+ }
+ exit(exitval);
+ return exitval;
+}
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+
+#ifdef TARGET_UNIX
+int main(int argc, char* str[])
+{
+ g_pszExeFile = str[0];
+ if (0 != PAL_Initialize(argc, str))
+ {
+ fprintf(stderr,"Error: Fail to PAL_Initialize\n");
+ exit(1);
+ }
+
+ WCHAR **argv = new WCHAR*[argc];
+ for (int i = 0; i < argc; i++) {
+ int length = MultiByteToWideChar(CP_ACP, 0, str[i], -1, NULL, 0);
+ ASSERTE_ALL_BUILDS(length != 0);
+
+ LPWSTR result = new (nothrow) WCHAR[length];
+ ASSERTE_ALL_BUILDS(result != NULL);
+
+ length = MultiByteToWideChar(CP_ACP, 0, str[i], -1, result, length);
+ ASSERTE_ALL_BUILDS (length != 0);
+
+ argv[i] = result;
+ }
+
+ int ret = wmain(argc, argv);
+
+ for (int i = 0 ; i < argc; i++) {
+ delete[] argv[i];
+ }
+ delete[] argv;
+
+ return ret;
+}
+#endif // TARGET_UNIX
+
diff --git a/src/coreclr/ilasm/method.cpp b/src/coreclr/ilasm/method.cpp
new file mode 100644
index 00000000000..10fd7537f32
--- /dev/null
+++ b/src/coreclr/ilasm/method.cpp
@@ -0,0 +1,176 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// file: method.cpp
+//
+
+//
+#include "ilasmpch.h"
+#include "assembler.h"
+
+Method::Method(Assembler *pAssembler, Class *pClass, __in __nullterminated char *pszName, BinStr* pbsSig, DWORD Attr)
+{
+
+ // default values
+ m_pClass = pClass;
+ m_MaxStack = 8;
+ m_Flags = 0;
+ m_LocalsSig = 0;
+ m_dwNumExceptions = 0;
+ m_dwNumEndfilters = 0;
+ m_firstArgName = NULL;
+ m_firstVarName = NULL;
+ m_pMethodSig = NULL;
+ m_wImplAttr = miIL; //default, if native or optil are not specified
+ m_wVTEntry = 0;
+ m_wVTSlot = 0;
+ m_pAssembler = pAssembler;
+ m_pCurrScope = &m_MainScope;
+ m_pRetMarshal = NULL;
+ m_pRetValue = NULL;
+ m_szExportAlias = NULL;
+ m_dwExportOrdinal = 0xFFFFFFFF;
+ m_ulLines[0]=m_ulLines[1]=0;
+ m_ulColumns[0]=m_ulColumns[1]=0;
+ m_pbsBody = NULL;
+ m_fNewBody = TRUE;
+ m_fNew = TRUE;
+
+ // move the PInvoke descriptor (if any) from Assembler
+ // (Assembler gets the descriptor BEFORE it calls new Method)
+ m_pPInvoke = pAssembler->m_pPInvoke;
+ pAssembler->m_pPInvoke = NULL;
+
+ _ASSERTE(pszName);
+ if (!pszName) return;
+
+ m_szName = pszName;
+ m_dwName = (DWORD)strlen(pszName);
+
+ m_ExceptionList = new COR_ILMETHOD_SECT_EH_CLAUSE_FAT[MAX_EXCEPTIONS];
+ m_EndfilterOffsetList = new DWORD[MAX_EXCEPTIONS];
+ if((m_ExceptionList==NULL)||(m_EndfilterOffsetList==NULL))
+ {
+ fprintf(stderr,"\nOutOfMemory!\n");
+ return;
+ }
+ m_dwMaxNumExceptions = MAX_EXCEPTIONS;
+ m_dwMaxNumEndfilters = MAX_EXCEPTIONS;
+
+ m_Attr = Attr;
+ if((!strcmp(pszName,COR_CCTOR_METHOD_NAME))||(!strcmp(pszName,COR_CTOR_METHOD_NAME)))
+ m_Attr |= mdSpecialName;
+ m_fEntryPoint = FALSE;
+ m_fGlobalMethod = FALSE;
+
+ if(pbsSig)
+ {
+ m_dwMethodCSig = pbsSig->length();
+ m_pMethodSig = (COR_SIGNATURE*)(pbsSig->ptr());
+ m_pbsMethodSig = pbsSig;
+ }
+
+ m_firstArgName = pAssembler->getArgNameList();
+ if(pClass == NULL) pClass = pAssembler->m_pModuleClass; // fake "class" <Module>
+ pClass->m_MethodList.PUSH(this);
+ pClass->m_fNewMembers = TRUE;
+
+
+ m_pPermissions = NULL;
+ m_pPermissionSets = NULL;
+
+ m_TyPars = NULL;
+ m_NumTyPars = 0;
+}
+
+
+// lexical scope handling
+void Method::OpenScope()
+{
+ Scope* psc = new Scope;
+ if(psc)
+ {
+ psc->dwStart = m_pAssembler->m_CurPC;
+ psc->pSuperScope = m_pCurrScope;
+ m_pCurrScope->SubScope.PUSH(psc);
+ m_pCurrScope = psc;
+ }
+}
+void Method::CloseScope()
+{
+ VarDescr* pVD;
+ ARG_NAME_LIST* pAN;
+ for(pAN=m_pCurrScope->pLocals; pAN; pAN = pAN->pNext)
+ {
+ if((pVD = m_Locals.PEEK(pAN->dwAttr))) pVD->bInScope = FALSE;
+ }
+ m_pCurrScope->dwEnd = m_pAssembler->m_CurPC;
+ m_pCurrScope = m_pCurrScope->pSuperScope;
+}
+
+Label *Method::FindLabel(LPCUTF8 pszName)
+{
+ Label lSearch(pszName,0), *pL;
+ lSearch.m_szName = pszName;
+ //pL = m_lstLabel.FIND(&lSearch);
+ pL = m_pAssembler->m_lstLabel.FIND(&lSearch);
+ lSearch.m_szName = NULL;
+ return pL;
+ //return m_lstLabel.FIND(pszName);
+}
+
+
+Label *Method::FindLabel(DWORD PC)
+{
+ Label *pSearch;
+
+ //for (int i = 0; (pSearch = m_lstLabel.PEEK(i)); i++)
+ for (int i = 0; (pSearch = m_pAssembler->m_lstLabel.PEEK(i)); i++)
+ {
+ if (pSearch->m_PC == PC)
+ return pSearch;
+ }
+
+ return NULL;
+}
+
+// Method::AddGenericParamConstraint is called when we have a .param constraint directive after a method definition
+//
+void Method::AddGenericParamConstraint(int index, char * pStrGenericParam, mdToken tkTypeConstraint)
+{
+ if (index > 0)
+ {
+ if (pStrGenericParam != 0)
+ {
+ m_pAssembler->report->error("LOGIC ERROR - we have both an index and a pStrGenericParam");
+ return;
+ }
+ if (index > (int)m_NumTyPars)
+ {
+ m_pAssembler->report->error("Type parameter index out of range: 1.. %d\n", m_NumTyPars);
+ return;
+ }
+ index = index - 1;
+ }
+ else // index was 0, so a name must be supplied by pStrGenericParam
+ {
+ if (pStrGenericParam == 0)
+ {
+ m_pAssembler->report->error("LOGIC ERROR - we have neither an index or a pStrGenericParam");
+ return;
+ }
+ index = FindTyPar(pStrGenericParam);
+ if (index == -1)
+ {
+ m_pAssembler->report->error("Type parameter '%s' undefined\n", pStrGenericParam);
+ return;
+ }
+ }
+
+ // pass true for isParamDirective, we are parsing a .param directive for a method here
+ //
+ m_pAssembler->CheckAddGenericParamConstraint(&m_GPCList, index, tkTypeConstraint, true);
+}
+
+
+
diff --git a/src/coreclr/ilasm/method.hpp b/src/coreclr/ilasm/method.hpp
new file mode 100644
index 00000000000..c52a3a41e81
--- /dev/null
+++ b/src/coreclr/ilasm/method.hpp
@@ -0,0 +1,385 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// method.hpp
+//
+#ifndef _METHOD_HPP
+#define _METHOD_HPP
+
+class Assembler;
+class PermissionDecl;
+class PermissionSetDecl;
+
+#define MAX_EXCEPTIONS 16 // init.number; increased by 16 when needed
+
+extern unsigned int g_uCodePage;
+extern WCHAR wzUniBuf[];
+
+/**************************************************************************/
+struct LinePC
+{
+ ULONG Line;
+ ULONG Column;
+ ULONG LineEnd;
+ ULONG ColumnEnd;
+ ULONG PC;
+ ISymUnmanagedDocumentWriter* pWriter;
+ Document* pOwnerDocument;
+ BOOL IsHidden;
+};
+typedef FIFO<LinePC> LinePCList;
+
+
+struct PInvokeDescriptor
+{
+ mdModuleRef mrDll;
+ char* szAlias;
+ DWORD dwAttrs;
+};
+
+struct TokenRelocDescr // for OBJ generation only!
+{
+ DWORD offset;
+ mdToken token;
+ TokenRelocDescr(DWORD off, mdToken tk) { offset = off; token = tk; };
+};
+typedef FIFO<TokenRelocDescr> TRDList;
+/* structure - element of [local] signature name list */
+
+struct ARG_NAME_LIST
+{
+ LPCUTF8 szName; //szName[1024];
+ DWORD dwName;
+ BinStr* pSig; // argument's signature ptr
+ BinStr* pMarshal;
+ BinStr* pValue;
+ int nNum;
+ DWORD dwAttr;
+ CustomDescrList CustDList;
+ ARG_NAME_LIST *pNext;
+ __forceinline ARG_NAME_LIST(int i, LPCUTF8 sz, BinStr *pbSig, BinStr *pbMarsh, DWORD attr)
+ {
+ nNum = i;
+ //dwName = (DWORD)strlen(sz);
+ //strcpy(szName,sz);
+ szName = sz;
+ dwName = (sz == NULL) ? 0 : (DWORD)strlen(sz);
+ pNext = NULL;
+ pSig=pbSig;
+ pMarshal = pbMarsh;
+ dwAttr = attr;
+ pValue=NULL;
+ };
+ inline ~ARG_NAME_LIST()
+ {
+ if(pSig) delete pSig;
+ if(pMarshal) delete pMarshal;
+ if(pValue) delete pValue;
+ if(szName) delete [] szName;
+ }
+};
+
+class Scope;
+typedef FIFO<Scope> ScopeList;
+class Scope
+{
+public:
+ DWORD dwStart;
+ DWORD dwEnd;
+ ARG_NAME_LIST* pLocals;
+ ScopeList SubScope;
+ Scope* pSuperScope;
+ Scope() { dwStart = dwEnd = 0; pLocals = NULL; pSuperScope = NULL; };
+ ~Scope() { Reset(); };
+ void Reset()
+ {
+ ARG_NAME_LIST* pNext;
+ while(pLocals) { pNext = pLocals->pNext; delete pLocals; pLocals = pNext; }
+ Scope* pS;
+ while((pS = SubScope.POP()) != NULL) delete pS;
+ pSuperScope = NULL;
+ dwStart = dwEnd = 0;
+ };
+};
+struct VarDescr
+{
+ DWORD dwSlot;
+ BinStr* pbsSig;
+ BOOL bInScope;
+ VarDescr() { dwSlot = (DWORD) -1; pbsSig = NULL; bInScope = FALSE; };
+};
+typedef FIFO<VarDescr> VarDescrList;
+
+
+struct Label
+{
+//public:
+ LPCUTF8 m_szName;
+ DWORD m_PC;
+
+ Label() :m_szName(NULL),m_PC(0){};
+ Label(LPCUTF8 pszName, DWORD PC):m_szName(pszName),m_PC(PC){};
+ ~Label(){ delete [] m_szName; };
+ int ComparedTo(Label* L) { return strcmp(m_szName,L->m_szName); };
+ //int Compare(char* L) { return strcmp(L,m_szName); };
+ LPCUTF8 NameOf() { return m_szName; };
+};
+//typedef SORTEDARRAY<Label> LabelList;
+typedef FIFO_INDEXED<Label> LabelList;
+
+class GlobalFixup
+{
+public:
+ LPCUTF8 m_szLabel;
+ BYTE * m_pReference; // The place to fix up
+
+ GlobalFixup(LPCUTF8 pszName, BYTE* pReference)
+ {
+ m_pReference = pReference;
+ m_szLabel = pszName;
+ }
+ ~GlobalFixup(){ delete [] m_szLabel; }
+};
+typedef FIFO<GlobalFixup> GlobalFixupList;
+
+
+class Fixup
+{
+public:
+ LPCUTF8 m_szLabel;
+ BYTE * m_pBytes; // where to make the fixup
+ DWORD m_RelativeToPC;
+ BYTE m_FixupSize;
+
+ Fixup(LPCUTF8 pszName, BYTE *pBytes, DWORD RelativeToPC, BYTE FixupSize)
+ {
+ m_pBytes = pBytes;
+ m_RelativeToPC = RelativeToPC;
+ m_FixupSize = FixupSize;
+ m_szLabel = pszName;
+ }
+ ~Fixup(){ delete [] m_szLabel; }
+};
+typedef FIFO<Fixup> FixupList;
+
+typedef enum { ilRVA, ilToken, ilGlobal} ILFixupType;
+
+class ILFixup
+{
+public:
+ ILFixupType m_Kind;
+ DWORD m_OffsetInMethod;
+ GlobalFixup * m_Fixup;
+
+ ILFixup(DWORD Offset, ILFixupType Kind, GlobalFixup *Fix)
+ {
+ m_Kind = Kind;
+ m_OffsetInMethod = Offset;
+ m_Fixup = Fix;
+ }
+};
+typedef FIFO<ILFixup> ILFixupList;
+
+class Method
+{
+public:
+ Class *m_pClass;
+ //BinStr **m_TyParBounds;
+ //LPCWSTR *m_TyParNames;
+ TyParDescr* m_TyPars;
+ DWORD m_NumTyPars;
+ GenericParamConstraintList m_GPCList;
+
+ DWORD m_SigInfoCount;
+ USHORT m_MaxStack;
+ mdSignature m_LocalsSig;
+ DWORD m_Flags;
+ char* m_szName;
+ DWORD m_dwName;
+ char* m_szExportAlias;
+ DWORD m_dwExportOrdinal;
+ COR_ILMETHOD_SECT_EH_CLAUSE_FAT *m_ExceptionList;
+ DWORD m_dwNumExceptions;
+ DWORD m_dwMaxNumExceptions;
+ DWORD* m_EndfilterOffsetList;
+ DWORD m_dwNumEndfilters;
+ DWORD m_dwMaxNumEndfilters;
+ DWORD m_Attr;
+ BOOL m_fEntryPoint;
+ BOOL m_fGlobalMethod;
+ BOOL m_fNewBody;
+ BOOL m_fNew;
+ DWORD m_methodOffset;
+ DWORD m_headerOffset;
+ BYTE * m_pCode;
+ DWORD m_CodeSize;
+ WORD m_wImplAttr;
+ ULONG m_ulLines[2];
+ ULONG m_ulColumns[2];
+ // PInvoke attributes
+ PInvokeDescriptor* m_pPInvoke;
+ // Security attributes
+ PermissionDecl* m_pPermissions;
+ PermissionSetDecl* m_pPermissionSets;
+ // VTable attributes
+ WORD m_wVTEntry;
+ WORD m_wVTSlot;
+ // Return marshaling
+ BinStr* m_pRetMarshal;
+ BinStr* m_pRetValue;
+ DWORD m_dwRetAttr;
+ CustomDescrList m_RetCustDList;
+ ILFixupList m_lstILFixup;
+ FixupList m_lstFixup;
+// LabelList m_lstLabel;
+ // Member ref fixups
+ LocalMemberRefFixupList m_LocalMemberRefFixupList;
+ // Method body (header+code+EH)
+ BinStr* m_pbsBody;
+ mdToken m_Tok;
+ Method(Assembler *pAssembler, Class *pClass, __in __nullterminated char *pszName, BinStr* pbsSig, DWORD Attr);
+ ~Method()
+ {
+ m_lstFixup.RESET(true);
+ //m_lstLabel.RESET(true);
+ delete [] m_szName;
+ if(m_szExportAlias) delete [] m_szExportAlias;
+ delArgNameList(m_firstArgName);
+ delArgNameList(m_firstVarName);
+ delete m_pbsMethodSig;
+ delete [] m_ExceptionList;
+ delete [] m_EndfilterOffsetList;
+ if(m_pRetMarshal) delete m_pRetMarshal;
+ if(m_pRetValue) delete m_pRetValue;
+ while(m_MethodImplDList.POP()); // ptrs in m_MethodImplDList are dups of those in Assembler
+ if(m_pbsBody) delete m_pbsBody;
+ if(m_TyPars) delete [] m_TyPars;
+ };
+
+ BOOL IsGlobalMethod()
+ {
+ return m_fGlobalMethod;
+ };
+
+ void SetIsGlobalMethod()
+ {
+ m_fGlobalMethod = TRUE;
+ };
+
+ void delArgNameList(ARG_NAME_LIST *pFirst)
+ {
+ ARG_NAME_LIST *pArgList=pFirst, *pArgListNext;
+ for(; pArgList; pArgListNext=pArgList->pNext,
+ delete pArgList,
+ pArgList=pArgListNext);
+ };
+
+ ARG_NAME_LIST *catArgNameList(ARG_NAME_LIST *pBase, ARG_NAME_LIST *pAdd)
+ {
+ if(pAdd) //even if nothing to concatenate, result == head
+ {
+ ARG_NAME_LIST *pAN = pBase;
+ if(pBase)
+ {
+ int i;
+ for(; pAN->pNext; pAN = pAN->pNext) ;
+ pAN->pNext = pAdd;
+ i = pAN->nNum;
+ for(pAN = pAdd; pAN; pAN->nNum = ++i, pAN = pAN->pNext);
+ }
+ else pBase = pAdd; //nothing to concatenate to, result == tail
+ }
+ return pBase;
+ };
+
+ int findArgNum(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName)
+ {
+ int ret=-1;
+ if(dwArgName)
+ {
+ ARG_NAME_LIST *pAN;
+ for(pAN=pFirst; pAN; pAN = pAN->pNext)
+ {
+ if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName))))
+ {
+ ret = pAN->nNum;
+ break;
+ }
+ }
+ }
+ return ret;
+ };
+
+ int findLocSlot(ARG_NAME_LIST *pFirst, LPCUTF8 szArgName, DWORD dwArgName)
+ {
+ int ret=-1;
+ if(dwArgName)
+ {
+ ARG_NAME_LIST *pAN;
+ for(pAN=pFirst; pAN; pAN = pAN->pNext)
+ {
+ if((pAN->dwName == dwArgName)&& ((dwArgName==0)||(!strcmp(pAN->szName,szArgName))))
+ {
+ ret = (int)(pAN->dwAttr);
+ break;
+ }
+ }
+ }
+ return ret;
+ };
+
+ BinStr *m_pbsMethodSig;
+ COR_SIGNATURE* m_pMethodSig;
+ DWORD m_dwMethodCSig;
+ ARG_NAME_LIST *m_firstArgName;
+ ARG_NAME_LIST *m_firstVarName;
+ // to call error() from Method:
+ const char* m_FileName;
+ unsigned m_LineNum;
+ // debug info
+ LinePCList m_LinePCList;
+ // custom values
+ CustomDescrList m_CustomDescrList;
+ // token relocs (used for OBJ generation only)
+ TRDList m_TRDList;
+ // method's own list of method impls
+ MethodImplDList m_MethodImplDList;
+ // lexical scope handling
+ Assembler* m_pAssembler;
+ Scope m_MainScope;
+ Scope* m_pCurrScope;
+ VarDescrList m_Locals;
+ void OpenScope();
+ void CloseScope();
+
+ Label *FindLabel(LPCUTF8 pszName);
+ Label *FindLabel(DWORD PC);
+
+ int FindTyPar(__in __nullterminated WCHAR* wz)
+ {
+ int i,retval=-1;
+ for(i=0; i < (int)m_NumTyPars; i++)
+ {
+ if(!wcscmp(wz,m_TyPars[i].Name()))
+ {
+ retval = i;
+ }
+ }
+ return retval;
+ };
+ int FindTyPar(__in __nullterminated char* sz)
+ {
+ if(sz)
+ {
+ wzUniBuf[0] = 0;
+ WszMultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf);
+ return FindTyPar(wzUniBuf);
+ }
+ else return -1;
+ };
+
+ void AddGenericParamConstraint(int index, char * pStrGenericParam, mdToken tkTypeConstraint);
+};
+
+#endif /* _METHOD_HPP */
+
diff --git a/src/coreclr/ilasm/nvpair.h b/src/coreclr/ilasm/nvpair.h
new file mode 100644
index 00000000000..158df000aa4
--- /dev/null
+++ b/src/coreclr/ilasm/nvpair.h
@@ -0,0 +1,45 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/***************************************************************************/
+/* Name value pair (both strings) which can be linked into a list of pairs */
+
+#ifndef NVPAIR_H
+#define NVPAIR_H
+
+#include "binstr.h"
+
+class NVPair
+{
+public:
+
+ NVPair(BinStr *name, BinStr *value)
+ {
+ m_Name = name;
+ m_Value = value;
+ m_Tail = NULL;
+ }
+
+ ~NVPair()
+ {
+ delete m_Name;
+ delete m_Value;
+ delete m_Tail;
+ }
+
+ NVPair *Concat(NVPair *list)
+ {
+ m_Tail = list;
+ return this;
+ }
+
+ BinStr *Name() { return m_Name; }
+ BinStr *Value() { return m_Value; }
+ NVPair *Next() { return m_Tail; }
+
+private:
+ BinStr *m_Name;
+ BinStr *m_Value;
+ NVPair *m_Tail;
+};
+
+#endif
diff --git a/src/coreclr/ilasm/portable_pdb.cpp b/src/coreclr/ilasm/portable_pdb.cpp
new file mode 100644
index 00000000000..8da13f2e5d8
--- /dev/null
+++ b/src/coreclr/ilasm/portable_pdb.cpp
@@ -0,0 +1,398 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "portable_pdb.h"
+#include <time.h>
+#include "assembler.h"
+
+//*****************************************************************************
+// Document
+//*****************************************************************************
+Document::Document()
+{
+ m_name = NULL;
+ m_token = mdDocumentNil;
+}
+
+Document::~Document()
+{
+ if (m_name)
+ {
+ delete[] m_name;
+ m_name = NULL;
+ }
+ m_token = mdDocumentNil;
+};
+
+char* Document::GetName()
+{
+ return m_name;
+}
+
+void Document::SetName(char* name)
+{
+ m_name = new char[strlen(name) + 1];
+ strcpy_s(m_name, strlen(name) + 1, name);
+}
+
+mdDocument Document::GetToken()
+{
+ return m_token;
+}
+
+void Document::SetToken(mdDocument token)
+{
+ m_token = token;
+}
+
+
+//*****************************************************************************
+// PortablePdbWriter
+//*****************************************************************************
+PortablePdbWriter::PortablePdbWriter()
+{
+ m_pdbStream.id.pdbGuid = { 0 };
+ m_pdbStream.id.pdbTimeStamp = 0;
+ m_pdbStream.entryPoint = mdMethodDefNil;
+ m_pdbStream.referencedTypeSystemTables = 0UL;
+ m_pdbStream.typeSystemTableRows = new ULONG[TBL_COUNT];
+ m_pdbStream.typeSystemTableRowsSize = 0;
+ m_currentDocument = NULL;
+ m_pdbEmitter = NULL;
+}
+
+PortablePdbWriter::~PortablePdbWriter()
+{
+ if (m_pdbEmitter != NULL)
+ {
+ m_pdbEmitter->Release();
+ m_pdbEmitter = NULL;
+ }
+ if (m_pdbStream.typeSystemTableRows != NULL)
+ {
+ delete[] m_pdbStream.typeSystemTableRows;
+ m_pdbStream.typeSystemTableRows = NULL;
+ }
+
+ m_documentList.RESET(true);
+}
+
+HRESULT PortablePdbWriter::Init(IMetaDataDispenserEx2* mdDispenser)
+{
+ HRESULT hr = S_OK;
+ if (m_pdbEmitter != NULL)
+ {
+ m_pdbEmitter->Release();
+ m_pdbEmitter = NULL;
+ }
+ m_currentDocument = NULL;
+ m_documentList.RESET(true);
+
+ memset(m_pdbStream.typeSystemTableRows, 0, sizeof(ULONG) * TBL_COUNT);
+ time_t now;
+ time(&now);
+ m_pdbStream.id.pdbTimeStamp = (ULONG)now;
+ hr = CoCreateGuid(&m_pdbStream.id.pdbGuid);
+
+ if (FAILED(hr)) goto exit;
+
+ hr = mdDispenser->DefinePortablePdbScope(
+ CLSID_CorMetaDataRuntime,
+ 0,
+ IID_IMetaDataEmit3,
+ (IUnknown**)&m_pdbEmitter);
+exit:
+ return hr;
+}
+
+IMetaDataEmit3* PortablePdbWriter::GetEmitter()
+{
+ return m_pdbEmitter;
+}
+
+GUID* PortablePdbWriter::GetGuid()
+{
+ return &m_pdbStream.id.pdbGuid;
+}
+
+ULONG PortablePdbWriter::GetTimestamp()
+{
+ return m_pdbStream.id.pdbTimeStamp;
+}
+
+Document* PortablePdbWriter::GetCurrentDocument()
+{
+ return m_currentDocument;
+}
+
+HRESULT PortablePdbWriter::BuildPdbStream(IMetaDataEmit3* peEmitter, mdMethodDef entryPoint)
+{
+ HRESULT hr = S_OK;
+
+ m_pdbStream.entryPoint = entryPoint;
+
+ if (FAILED(hr = peEmitter->GetReferencedTypeSysTables(
+ &m_pdbStream.referencedTypeSystemTables,
+ m_pdbStream.typeSystemTableRows,
+ TBL_COUNT,
+ &m_pdbStream.typeSystemTableRowsSize))) goto exit;
+
+ if (FAILED(hr = m_pdbEmitter->DefinePdbStream(&m_pdbStream))) goto exit;
+
+exit:
+ return hr;
+}
+
+HRESULT PortablePdbWriter::DefineDocument(char* name, GUID* language)
+{
+ HRESULT hr = S_OK;
+ Document* document = NULL;
+ unsigned i = 0;
+
+ // did we already add a document with this name
+ while ((document = m_documentList.PEEK(i++)) != NULL)
+ {
+ if (!strcmp(name, document->GetName()))
+ break;
+ }
+
+ if (document)
+ {
+ // found one in the list
+ // set it as current
+ m_currentDocument = document;
+ }
+ else
+ {
+ // define a new document
+ document = new Document();
+ // save the document name, the 'name' parameter will be overriten - tokenized
+ document->SetName(name);
+
+ // TODO: make use of hash algorithm and hash value
+ GUID hashAlgorithmUnknown = { 0 };
+ BYTE* hashValue = NULL;
+ ULONG cbHashValue = 0;
+ mdDocument docToken = mdDocumentNil;
+
+ if (FAILED(hr = m_pdbEmitter->DefineDocument(
+ name, // will be tokenized
+ &hashAlgorithmUnknown,
+ hashValue,
+ cbHashValue,
+ language,
+ &docToken)))
+ {
+ delete document;
+ m_currentDocument = NULL;
+ hr = E_FAIL;
+ }
+ else
+ {
+ document->SetToken(docToken);
+ m_currentDocument = document;
+ m_documentList.PUSH(document);
+ }
+ }
+
+ return hr;
+}
+
+HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
+{
+ HRESULT hr = S_OK;
+ BinStr* blob = new BinStr();
+
+ // Blob ::= header SequencePointRecord (SequencePointRecord | document-record)*
+ // SequencePointRecord :: = sequence-point-record | hidden-sequence-point-record
+
+ // header ::= {LocalSignature, InitialDocument}
+ // LocalSignature
+ ULONG localSigRid = RidFromToken(method->m_LocalsSig);
+ CompressUnsignedLong(localSigRid, blob);
+ // InitialDocument TODO: skip this for now
+
+ // SequencePointRecord
+ ULONG offset = 0;
+ ULONG deltaLines = 0;
+ LONG deltaColumns = 0;
+ LONG deltaStartLine = 0;
+ LONG deltaStartColumn = 0;
+ LinePC* currSeqPoint = NULL;
+ LinePC* prevSeqPoint = NULL;
+ LinePC* prevNonHiddenSeqPoint = NULL;
+ LinePC* nextSeqPoint = NULL;
+ BOOL isValid = TRUE;
+
+ for (UINT32 i = 0; i < method->m_LinePCList.COUNT(); i++)
+ {
+ currSeqPoint = method->m_LinePCList.PEEK(i);
+ if (i < (method->m_LinePCList.COUNT() - 1))
+ nextSeqPoint = method->m_LinePCList.PEEK(i + 1);
+ else
+ nextSeqPoint = NULL;
+
+ isValid = VerifySequencePoint(currSeqPoint, nextSeqPoint);
+ if (!isValid)
+ {
+ method->m_pAssembler->report->warn("Sequence point at line: [0x%x] and offset: [0x%x] in method '%s' is not valid!\n",
+ currSeqPoint->Line,
+ currSeqPoint->PC,
+ method->m_szName);
+ hr = E_FAIL;
+ break; // TODO: break or ignore?
+ }
+
+ if (!currSeqPoint->IsHidden)
+ {
+ //offset
+ offset = (i == 0) ? currSeqPoint->PC : currSeqPoint->PC - prevSeqPoint->PC;
+ CompressUnsignedLong(offset, blob);
+
+ //delta lines
+ deltaLines = currSeqPoint->LineEnd - currSeqPoint->Line;
+ CompressUnsignedLong(deltaLines, blob);
+
+ //delta columns
+ deltaColumns = currSeqPoint->ColumnEnd - currSeqPoint->Column;
+ if (deltaLines == 0)
+ CompressUnsignedLong(deltaColumns, blob);
+ else
+ CompressSignedLong(deltaColumns, blob);
+
+ //delta start line
+ if (prevNonHiddenSeqPoint == NULL)
+ {
+ deltaStartLine = currSeqPoint->Line;
+ CompressUnsignedLong(deltaStartLine, blob);
+ }
+ else
+ {
+ deltaStartLine = currSeqPoint->Line - prevNonHiddenSeqPoint->Line;
+ CompressSignedLong(deltaStartLine, blob);
+ }
+
+ //delta start column
+ if (prevNonHiddenSeqPoint == NULL)
+ {
+ deltaStartColumn = currSeqPoint->Column;
+ CompressUnsignedLong(deltaStartColumn, blob);
+ }
+ else
+ {
+ deltaStartColumn = currSeqPoint->Column - prevNonHiddenSeqPoint->Column;
+ CompressSignedLong(deltaStartColumn, blob);
+ }
+
+ prevNonHiddenSeqPoint = currSeqPoint;
+ }
+ else
+ {
+ //offset
+ offset = (i == 0) ? currSeqPoint->PC : currSeqPoint->PC - prevSeqPoint->PC;
+ CompressUnsignedLong(offset, blob);
+
+ //delta lines
+ deltaLines = 0;
+ CompressUnsignedLong(deltaLines, blob);
+
+ //delta lines
+ deltaColumns = 0;
+ CompressUnsignedLong(deltaColumns, blob);
+ }
+ prevSeqPoint = currSeqPoint;
+ }
+
+ // finally define sequence points for the method
+ if (isValid && currSeqPoint != NULL)
+ {
+ ULONG documentRid = RidFromToken(currSeqPoint->pOwnerDocument->GetToken());
+ hr = m_pdbEmitter->DefineSequencePoints(documentRid, blob->ptr(), blob->length());
+ }
+
+ delete blob;
+ return hr;
+}
+
+HRESULT PortablePdbWriter::DefineLocalScope(Method* method)
+{
+ if (!_DefineLocalScope(method->m_Tok, &method->m_MainScope))
+ return E_FAIL;
+ else
+ return S_OK;
+}
+
+BOOL PortablePdbWriter::_DefineLocalScope(mdMethodDef methodDefToken, Scope* currScope)
+{
+ BOOL fSuccess = FALSE;
+ ARG_NAME_LIST* pLocalVar = currScope->pLocals;
+ ULONG methodRid = RidFromToken(methodDefToken);
+ ULONG importScopeRid = RidFromToken(mdImportScopeNil); // TODO: not supported for now
+ ULONG firstLocalVarRid = 0;
+ ULONG firstLocalConstRid = RidFromToken(mdLocalConstantNil); // TODO: not supported for now
+ ULONG start = 0;
+ ULONG length = 0;
+ mdLocalVariable firstLocVarToken = mdLocalScopeNil;
+
+ while (pLocalVar != NULL)
+ {
+ mdLocalVariable locVarToken = mdLocalScopeNil;
+ USHORT attribute = 0; // TODO: not supported for now
+ USHORT index = pLocalVar->dwAttr & 0xffff; // slot
+ if (FAILED(m_pdbEmitter->DefineLocalVariable(attribute, index, (char*)pLocalVar->szName, &locVarToken))) goto exit;
+
+ if (firstLocVarToken == mdLocalScopeNil)
+ firstLocVarToken = locVarToken;
+
+ pLocalVar = pLocalVar->pNext;
+ }
+
+ if (firstLocVarToken != mdLocalScopeNil)
+ {
+ firstLocalVarRid = RidFromToken(firstLocVarToken);
+ start = currScope->dwStart;
+ length = currScope->dwEnd - currScope->dwStart;
+ if (FAILED(m_pdbEmitter->DefineLocalScope(methodRid, importScopeRid, firstLocalVarRid, firstLocalConstRid, start, length))) goto exit;
+ }
+
+ fSuccess = TRUE;
+ for (ULONG i = 0; i < currScope->SubScope.COUNT(); i++)
+ fSuccess &= _DefineLocalScope(methodDefToken, currScope->SubScope.PEEK(i));
+
+exit:
+ return fSuccess;
+}
+
+BOOL PortablePdbWriter::VerifySequencePoint(LinePC* curr, LinePC* next)
+{
+ if (!curr->IsHidden)
+ {
+ if ((curr->PC >= 0 && curr->PC < 0x20000000) &&
+ (next == NULL || (next != NULL && curr->PC < next->PC)) &&
+ (curr->Line >= 0 && curr->Line < 0x20000000 && curr->Line != 0xfeefee) &&
+ (curr->LineEnd >= 0 && curr->LineEnd < 0x20000000 && curr->LineEnd != 0xfeefee) &&
+ (curr->Column >= 0 && curr->Column < 0x10000) &&
+ (curr->ColumnEnd >= 0 && curr->ColumnEnd < 0x10000) &&
+ (curr->LineEnd > curr->Line || (curr->Line == curr->LineEnd && curr->ColumnEnd > curr->Column)))
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void PortablePdbWriter::CompressUnsignedLong(ULONG srcData, BinStr* dstBuffer)
+{
+ ULONG cnt = CorSigCompressData(srcData, dstBuffer->getBuff(sizeof(ULONG) + 1));
+ dstBuffer->remove((sizeof(ULONG) + 1) - cnt);
+}
+
+void PortablePdbWriter::CompressSignedLong(LONG srcData, BinStr* dstBuffer)
+{
+ ULONG cnt = CorSigCompressSignedInt(srcData, dstBuffer->getBuff(sizeof(LONG) + 1));
+ dstBuffer->remove((sizeof(LONG) + 1) - cnt);
+}
diff --git a/src/coreclr/ilasm/portable_pdb.h b/src/coreclr/ilasm/portable_pdb.h
new file mode 100644
index 00000000000..46bd1f14920
--- /dev/null
+++ b/src/coreclr/ilasm/portable_pdb.h
@@ -0,0 +1,68 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef PORTABLE_PDB_H
+#define PORTABLE_PDB_H
+
+#include "ilasmpch.h"
+#include "asmtemplates.h"
+#include "portablepdbmdds.h"
+#include "portablepdbmdi.h"
+
+//*****************************************************************************
+// Document
+//*****************************************************************************
+class Document
+{
+public:
+ Document();
+ ~Document();
+ char* GetName();
+ void SetName(char* name);
+ mdDocument GetToken();
+ void SetToken(mdDocument token);
+
+private:
+ char* m_name;
+ mdDocument m_token;
+};
+
+typedef FIFO<Document> DocumentList;
+
+class BinStr;
+class Method;
+class Scope;
+struct LinePC;
+
+//*****************************************************************************
+// PortablePdbWriter
+//*****************************************************************************
+class PortablePdbWriter
+{
+public:
+ PortablePdbWriter();
+ ~PortablePdbWriter();
+ HRESULT Init(IMetaDataDispenserEx2* mdDispenser);
+ IMetaDataEmit3* GetEmitter();
+ GUID* GetGuid();
+ ULONG GetTimestamp();
+ Document* GetCurrentDocument();
+ HRESULT BuildPdbStream(IMetaDataEmit3* peEmitter, mdMethodDef entryPoint);
+ HRESULT DefineDocument(char* name, GUID* language);
+ HRESULT DefineSequencePoints(Method* method);
+ HRESULT DefineLocalScope(Method* method);
+
+private:
+ BOOL VerifySequencePoint(LinePC* curr, LinePC* next);
+ void CompressUnsignedLong(ULONG srcData, BinStr* dstBuffer);
+ void CompressSignedLong(LONG srcData, BinStr* dstBuffer);
+ BOOL _DefineLocalScope(mdMethodDef methodDefToken, Scope* currScope);
+
+private:
+ IMetaDataEmit3* m_pdbEmitter;
+ PORT_PDB_STREAM m_pdbStream;
+ DocumentList m_documentList;
+ Document* m_currentDocument;
+};
+
+#endif
diff --git a/src/coreclr/ilasm/prebuilt/asmparse.cpp b/src/coreclr/ilasm/prebuilt/asmparse.cpp
new file mode 100644
index 00000000000..4e7131a90a7
--- /dev/null
+++ b/src/coreclr/ilasm/prebuilt/asmparse.cpp
@@ -0,0 +1,4949 @@
+/*
+ * Created by Microsoft VCBU Internal YACC from "asmparse.y"
+ */
+
+#line 2 "asmparse.y"
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+//
+// File asmparse.y
+//
+#include "ilasmpch.h"
+
+#include "grammar_before.cpp"
+
+
+#line 16 "asmparse.y"
+
+#define UNION 1
+typedef union {
+ CorRegTypeAttr classAttr;
+ CorMethodAttr methAttr;
+ CorFieldAttr fieldAttr;
+ CorMethodImpl implAttr;
+ CorEventAttr eventAttr;
+ CorPropertyAttr propAttr;
+ CorPinvokeMap pinvAttr;
+ CorDeclSecurity secAct;
+ CorFileFlags fileAttr;
+ CorAssemblyFlags asmAttr;
+ CorAssemblyFlags asmRefAttr;
+ CorTypeAttr exptAttr;
+ CorManifestResourceFlags manresAttr;
+ double* float64;
+ __int64* int64;
+ __int32 int32;
+ char* string;
+ BinStr* binstr;
+ Labels* labels;
+ Instr* instr; // instruction opcode
+ NVPair* pair;
+ pTyParList typarlist;
+ mdToken token;
+ TypeDefDescr* tdd;
+ CustomDescr* cad;
+ unsigned short opcode;
+} YYSTYPE;
+# define ERROR_ 257
+# define BAD_COMMENT_ 258
+# define BAD_LITERAL_ 259
+# define ID 260
+# define DOTTEDNAME 261
+# define QSTRING 262
+# define SQSTRING 263
+# define INT32 264
+# define INT64 265
+# define FLOAT64 266
+# define HEXBYTE 267
+# define TYPEDEF_T 268
+# define TYPEDEF_M 269
+# define TYPEDEF_F 270
+# define TYPEDEF_TS 271
+# define TYPEDEF_MR 272
+# define TYPEDEF_CA 273
+# define DCOLON 274
+# define ELIPSIS 275
+# define VOID_ 276
+# define BOOL_ 277
+# define CHAR_ 278
+# define UNSIGNED_ 279
+# define INT_ 280
+# define INT8_ 281
+# define INT16_ 282
+# define INT32_ 283
+# define INT64_ 284
+# define FLOAT_ 285
+# define FLOAT32_ 286
+# define FLOAT64_ 287
+# define BYTEARRAY_ 288
+# define UINT_ 289
+# define UINT8_ 290
+# define UINT16_ 291
+# define UINT32_ 292
+# define UINT64_ 293
+# define FLAGS_ 294
+# define CALLCONV_ 295
+# define MDTOKEN_ 296
+# define OBJECT_ 297
+# define STRING_ 298
+# define NULLREF_ 299
+# define DEFAULT_ 300
+# define CDECL_ 301
+# define VARARG_ 302
+# define STDCALL_ 303
+# define THISCALL_ 304
+# define FASTCALL_ 305
+# define CLASS_ 306
+# define TYPEDREF_ 307
+# define UNMANAGED_ 308
+# define FINALLY_ 309
+# define HANDLER_ 310
+# define CATCH_ 311
+# define FILTER_ 312
+# define FAULT_ 313
+# define EXTENDS_ 314
+# define IMPLEMENTS_ 315
+# define TO_ 316
+# define AT_ 317
+# define TLS_ 318
+# define TRUE_ 319
+# define FALSE_ 320
+# define _INTERFACEIMPL 321
+# define VALUE_ 322
+# define VALUETYPE_ 323
+# define NATIVE_ 324
+# define INSTANCE_ 325
+# define SPECIALNAME_ 326
+# define FORWARDER_ 327
+# define STATIC_ 328
+# define PUBLIC_ 329
+# define PRIVATE_ 330
+# define FAMILY_ 331
+# define FINAL_ 332
+# define SYNCHRONIZED_ 333
+# define INTERFACE_ 334
+# define SEALED_ 335
+# define NESTED_ 336
+# define ABSTRACT_ 337
+# define AUTO_ 338
+# define SEQUENTIAL_ 339
+# define EXPLICIT_ 340
+# define ANSI_ 341
+# define UNICODE_ 342
+# define AUTOCHAR_ 343
+# define IMPORT_ 344
+# define ENUM_ 345
+# define VIRTUAL_ 346
+# define NOINLINING_ 347
+# define AGGRESSIVEINLINING_ 348
+# define NOOPTIMIZATION_ 349
+# define AGGRESSIVEOPTIMIZATION_ 350
+# define UNMANAGEDEXP_ 351
+# define BEFOREFIELDINIT_ 352
+# define STRICT_ 353
+# define RETARGETABLE_ 354
+# define WINDOWSRUNTIME_ 355
+# define NOPLATFORM_ 356
+# define METHOD_ 357
+# define FIELD_ 358
+# define PINNED_ 359
+# define MODREQ_ 360
+# define MODOPT_ 361
+# define SERIALIZABLE_ 362
+# define PROPERTY_ 363
+# define TYPE_ 364
+# define ASSEMBLY_ 365
+# define FAMANDASSEM_ 366
+# define FAMORASSEM_ 367
+# define PRIVATESCOPE_ 368
+# define HIDEBYSIG_ 369
+# define NEWSLOT_ 370
+# define RTSPECIALNAME_ 371
+# define PINVOKEIMPL_ 372
+# define _CTOR 373
+# define _CCTOR 374
+# define LITERAL_ 375
+# define NOTSERIALIZED_ 376
+# define INITONLY_ 377
+# define REQSECOBJ_ 378
+# define CIL_ 379
+# define OPTIL_ 380
+# define MANAGED_ 381
+# define FORWARDREF_ 382
+# define PRESERVESIG_ 383
+# define RUNTIME_ 384
+# define INTERNALCALL_ 385
+# define _IMPORT 386
+# define NOMANGLE_ 387
+# define LASTERR_ 388
+# define WINAPI_ 389
+# define AS_ 390
+# define BESTFIT_ 391
+# define ON_ 392
+# define OFF_ 393
+# define CHARMAPERROR_ 394
+# define INSTR_NONE 395
+# define INSTR_VAR 396
+# define INSTR_I 397
+# define INSTR_I8 398
+# define INSTR_R 399
+# define INSTR_BRTARGET 400
+# define INSTR_METHOD 401
+# define INSTR_FIELD 402
+# define INSTR_TYPE 403
+# define INSTR_STRING 404
+# define INSTR_SIG 405
+# define INSTR_TOK 406
+# define INSTR_SWITCH 407
+# define _CLASS 408
+# define _NAMESPACE 409
+# define _METHOD 410
+# define _FIELD 411
+# define _DATA 412
+# define _THIS 413
+# define _BASE 414
+# define _NESTER 415
+# define _EMITBYTE 416
+# define _TRY 417
+# define _MAXSTACK 418
+# define _LOCALS 419
+# define _ENTRYPOINT 420
+# define _ZEROINIT 421
+# define _EVENT 422
+# define _ADDON 423
+# define _REMOVEON 424
+# define _FIRE 425
+# define _OTHER 426
+# define _PROPERTY 427
+# define _SET 428
+# define _GET 429
+# define _PERMISSION 430
+# define _PERMISSIONSET 431
+# define REQUEST_ 432
+# define DEMAND_ 433
+# define ASSERT_ 434
+# define DENY_ 435
+# define PERMITONLY_ 436
+# define LINKCHECK_ 437
+# define INHERITCHECK_ 438
+# define REQMIN_ 439
+# define REQOPT_ 440
+# define REQREFUSE_ 441
+# define PREJITGRANT_ 442
+# define PREJITDENY_ 443
+# define NONCASDEMAND_ 444
+# define NONCASLINKDEMAND_ 445
+# define NONCASINHERITANCE_ 446
+# define _LINE 447
+# define P_LINE 448
+# define _LANGUAGE 449
+# define _CUSTOM 450
+# define INIT_ 451
+# define _SIZE 452
+# define _PACK 453
+# define _VTABLE 454
+# define _VTFIXUP 455
+# define FROMUNMANAGED_ 456
+# define CALLMOSTDERIVED_ 457
+# define _VTENTRY 458
+# define RETAINAPPDOMAIN_ 459
+# define _FILE 460
+# define NOMETADATA_ 461
+# define _HASH 462
+# define _ASSEMBLY 463
+# define _PUBLICKEY 464
+# define _PUBLICKEYTOKEN 465
+# define ALGORITHM_ 466
+# define _VER 467
+# define _LOCALE 468
+# define EXTERN_ 469
+# define _MRESOURCE 470
+# define _MODULE 471
+# define _EXPORT 472
+# define LEGACY_ 473
+# define LIBRARY_ 474
+# define X86_ 475
+# define AMD64_ 476
+# define ARM_ 477
+# define ARM64_ 478
+# define MARSHAL_ 479
+# define CUSTOM_ 480
+# define SYSSTRING_ 481
+# define FIXED_ 482
+# define VARIANT_ 483
+# define CURRENCY_ 484
+# define SYSCHAR_ 485
+# define DECIMAL_ 486
+# define DATE_ 487
+# define BSTR_ 488
+# define TBSTR_ 489
+# define LPSTR_ 490
+# define LPWSTR_ 491
+# define LPTSTR_ 492
+# define OBJECTREF_ 493
+# define IUNKNOWN_ 494
+# define IDISPATCH_ 495
+# define STRUCT_ 496
+# define SAFEARRAY_ 497
+# define BYVALSTR_ 498
+# define LPVOID_ 499
+# define ANY_ 500
+# define ARRAY_ 501
+# define LPSTRUCT_ 502
+# define IIDPARAM_ 503
+# define IN_ 504
+# define OUT_ 505
+# define OPT_ 506
+# define _PARAM 507
+# define _OVERRIDE 508
+# define WITH_ 509
+# define NULL_ 510
+# define HRESULT_ 511
+# define CARRAY_ 512
+# define USERDEFINED_ 513
+# define RECORD_ 514
+# define FILETIME_ 515
+# define BLOB_ 516
+# define STREAM_ 517
+# define STORAGE_ 518
+# define STREAMED_OBJECT_ 519
+# define STORED_OBJECT_ 520
+# define BLOB_OBJECT_ 521
+# define CF_ 522
+# define CLSID_ 523
+# define VECTOR_ 524
+# define _SUBSYSTEM 525
+# define _CORFLAGS 526
+# define ALIGNMENT_ 527
+# define _IMAGEBASE 528
+# define _STACKRESERVE 529
+# define _TYPEDEF 530
+# define _TEMPLATE 531
+# define _TYPELIST 532
+# define _MSCORLIB 533
+# define P_DEFINE 534
+# define P_UNDEF 535
+# define P_IFDEF 536
+# define P_IFNDEF 537
+# define P_ELSE 538
+# define P_ENDIF 539
+# define P_INCLUDE 540
+# define CONSTRAINT_ 541
+#define yyclearin yychar = -1
+#define yyerrok yyerrflag = 0
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 150
+#endif
+YYSTYPE yylval, yyval;
+#ifndef YYFARDATA
+#define YYFARDATA /*nothing*/
+#endif
+#if ! defined YYSTATIC
+#define YYSTATIC /*nothing*/
+#endif
+#if ! defined YYCONST
+#define YYCONST /*nothing*/
+#endif
+#ifndef YYACT
+#define YYACT yyact
+#endif
+#ifndef YYPACT
+#define YYPACT yypact
+#endif
+#ifndef YYPGO
+#define YYPGO yypgo
+#endif
+#ifndef YYR1
+#define YYR1 yyr1
+#endif
+#ifndef YYR2
+#define YYR2 yyr2
+#endif
+#ifndef YYCHK
+#define YYCHK yychk
+#endif
+#ifndef YYDEF
+#define YYDEF yydef
+#endif
+#ifndef YYV
+#define YYV yyv
+#endif
+#ifndef YYS
+#define YYS yys
+#endif
+#ifndef YYLOCAL
+#define YYLOCAL
+#endif
+#ifndef YYR_T
+#define YYR_T int
+#endif
+typedef YYR_T yyr_t;
+#ifndef YYEXIND_T
+#define YYEXIND_T unsigned int
+#endif
+typedef YYEXIND_T yyexind_t;
+#ifndef YYOPTTIME
+#define YYOPTTIME 0
+#endif
+# define YYERRCODE 256
+
+#line 2062 "asmparse.y"
+
+
+#include "grammar_after.cpp"
+YYSTATIC YYCONST short yyexca[] = {
+#if !(YYOPTTIME)
+-1, 1,
+#endif
+ 0, -1,
+ -2, 0,
+#if !(YYOPTTIME)
+-1, 452,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 622,
+#endif
+ 274, 555,
+ 47, 555,
+ -2, 230,
+#if !(YYOPTTIME)
+-1, 643,
+#endif
+ 40, 310,
+ 60, 310,
+ -2, 555,
+#if !(YYOPTTIME)
+-1, 665,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 690,
+#endif
+ 274, 555,
+ 47, 555,
+ -2, 516,
+#if !(YYOPTTIME)
+-1, 809,
+#endif
+ 123, 235,
+ -2, 555,
+#if !(YYOPTTIME)
+-1, 836,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 961,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 994,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 995,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1323,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1324,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1331,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1339,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1465,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1497,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1564,
+#endif
+ 41, 538,
+ -2, 311,
+#if !(YYOPTTIME)
+-1, 1581,
+#endif
+ 41, 538,
+ -2, 311,
+
+};
+
+# define YYNPROD 844
+#if YYOPTTIME
+YYSTATIC YYCONST yyexind_t yyexcaind[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 20, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 42, 46, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 50, 54, 0, 0, 0, 0, 0,
+ 0, 58, 0, 0, 0, 0, 0, 0, 0, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 70, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 78
+};
+#endif
+# define YYLAST 3922
+
+YYSTATIC YYCONST short YYFARDATA YYACT[] = {
+ 703, 1484, 414, 1416, 1133, 640, 660, 191, 1482, 1485,
+ 886, 1036, 971, 1483, 702, 788, 779, 885, 974, 729,
+ 73, 75, 150, 625, 1521, 536, 1417, 792, 755, 190,
+ 760, 757, 478, 176, 107, 972, 1146, 110, 106, 694,
+ 1077, 275, 860, 604, 662, 599, 273, 78, 81, 219,
+ 44, 24, 780, 262, 516, 214, 204, 7, 301, 188,
+ 654, 76, 6, 991, 85, 5, 1569, 3, 1206, 1253,
+ 220, 1125, 18, 1257, 115, 677, 1069, 264, 153, 1254,
+ 307, 133, 74, 178, 179, 180, 181, 272, 1123, 218,
+ 136, 10, 221, 300, 26, 137, 1070, 98, 278, 139,
+ 217, 1124, 17, 202, 203, 581, 269, 74, 719, 716,
+ 322, 265, 461, 113, 112, 700, 520, 939, 940, 352,
+ 343, 88, 87, 353, 89, 462, 1255, 452, 1025, 268,
+ 676, 338, 56, 537, 68, 1243, 1244, 305, 591, 88,
+ 87, 357, 89, 277, 225, 327, 277, 368, 339, 1031,
+ 342, 938, 361, 366, 185, 154, 1241, 1242, 98, 360,
+ 359, 358, 277, 56, 88, 87, 345, 89, 656, 1573,
+ 192, 782, 351, 783, 348, 365, 1537, 277, 86, 1039,
+ 369, 310, 312, 314, 316, 318, 374, 277, 362, 198,
+ 1038, 364, 699, 373, 199, 271, 200, 698, 1432, 84,
+ 105, 379, 201, 417, 418, 363, 376, 1138, 1139, 450,
+ 387, 451, 615, 88, 87, 186, 89, 388, 480, 195,
+ 814, 1071, 663, 1505, 456, 767, 1279, 457, 1578, 999,
+ 258, 473, 475, 416, 196, 1496, 484, 655, 481, 482,
+ 470, 491, 468, 472, 471, 501, 346, 216, 495, 1329,
+ 597, 1214, 192, 493, 441, 24, 833, 476, 479, 375,
+ 433, 7, 1278, 56, 801, 813, 486, 432, 664, 74,
+ 428, 492, 429, 483, 541, 436, 18, 641, 642, 487,
+ 586, 376, 585, 584, 544, 56, 1354, 1355, 1356, 587,
+ 941, 942, 267, 943, 435, 10, 154, 442, 26, 1337,
+ 1336, 1335, 1334, 494, 791, 434, 17, 777, 542, 572,
+ 74, 545, 714, 668, 575, 268, 576, 1249, 577, 1517,
+ 499, 600, 862, 863, 864, 579, 580, 371, 370, 1009,
+ 116, 511, 511, 528, 534, 108, 574, 372, 258, 571,
+ 266, 549, 573, 192, 488, 367, 88, 87, 154, 89,
+ 321, 1559, 601, 512, 512, 529, 535, 80, 79, 480,
+ 198, 505, 152, 410, 1435, 199, 74, 200, 613, 1560,
+ 348, 582, 583, 201, 74, 1130, 480, 46, 498, 481,
+ 482, 375, 621, 88, 596, 459, 89, 624, 80, 79,
+ 195, 1563, 607, 608, 609, 610, 481, 482, 1562, 606,
+ 420, 614, 421, 422, 423, 196, 745, 1368, 612, 474,
+ 611, 619, 620, 622, 485, 340, 341, 678, 1352, 639,
+ 644, 74, 1561, 500, 88, 87, 1248, 89, 1128, 955,
+ 56, 1153, 600, 595, 784, 135, 1154, 759, 649, 650,
+ 354, 355, 356, 652, 635, 1507, 1536, 348, 884, 182,
+ 643, 785, 56, 704, 1138, 1139, 666, 1408, 855, 321,
+ 177, 88, 674, 1140, 89, 74, 669, 1531, 970, 1514,
+ 685, 682, 951, 347, 566, 88, 1246, 46, 89, 74,
+ 538, 1506, 1267, 569, 1528, 867, 1362, 747, 88, 87,
+ 689, 89, 74, 671, 673, 1192, 1358, 1142, 696, 88,
+ 87, 786, 89, 990, 989, 988, 588, 983, 982, 981,
+ 980, 758, 978, 979, 105, 706, 987, 986, 985, 984,
+ 537, 690, 1468, 977, 975, 651, 715, 1001, 1002, 1003,
+ 1004, 88, 87, 692, 954, 177, 376, 693, 453, 155,
+ 648, 705, 80, 79, 480, 683, 701, 546, 727, 707,
+ 805, 61, 62, 47, 63, 709, 803, 710, 713, 1256,
+ 861, 539, 460, 645, 481, 482, 718, 177, 1520, 647,
+ 56, 1530, 88, 87, 225, 89, 74, 723, 1191, 659,
+ 728, 646, 967, 730, 277, 1529, 724, 597, 725, 675,
+ 976, 720, 80, 79, 1129, 762, 679, 680, 681, 413,
+ 734, 82, 506, 1526, 56, 768, 769, 49, 50, 51,
+ 52, 53, 54, 55, 74, 639, 1262, 1258, 1259, 1260,
+ 1261, 74, 754, 1524, 601, 744, 733, 748, 749, 750,
+ 1013, 98, 1011, 1012, 787, 543, 502, 72, 49, 50,
+ 51, 52, 53, 54, 55, 74, 643, 74, 684, 1522,
+ 477, 61, 62, 47, 63, 88, 87, 542, 89, 807,
+ 808, 802, 71, 751, 752, 753, 812, 793, 821, 74,
+ 514, 825, 819, 826, 822, 74, 695, 216, 70, 830,
+ 1184, 1183, 1182, 1181, 156, 157, 158, 831, 804, 806,
+ 74, 809, 74, 815, 480, 773, 774, 775, 790, 325,
+ 841, 842, 823, 797, 69, 800, 818, 80, 79, 67,
+ 377, 824, 832, 324, 481, 482, 348, 348, 854, 88,
+ 87, 225, 89, 834, 858, 88, 87, 865, 89, 1153,
+ 375, 672, 66, 930, 1154, 627, 628, 629, 49, 50,
+ 51, 52, 53, 54, 55, 192, 944, 945, 868, 56,
+ 853, 1153, 277, 856, 88, 87, 1154, 89, 74, 857,
+ 49, 50, 51, 52, 53, 54, 55, 601, 957, 600,
+ 1457, 630, 631, 632, 950, 1076, 1072, 1073, 1074, 1075,
+ 1455, 946, 152, 1344, 46, 382, 383, 384, 385, 111,
+ 177, 80, 79, 852, 74, 88, 87, 993, 89, 859,
+ 348, 773, 88, 87, 1021, 89, 1022, 1019, 74, 1453,
+ 362, 963, 956, 960, 966, 1018, 1451, 932, 46, 933,
+ 934, 935, 936, 937, 216, 823, 74, 1032, 1434, 593,
+ 1035, 637, 276, 1343, 968, 823, 606, 766, 997, 696,
+ 696, 496, 1026, 1044, 1020, 1425, 74, 441, 1007, 1016,
+ 1424, 1422, 1407, 433, 1027, 962, 1049, 829, 1024, 1047,
+ 432, 1029, 1028, 428, 517, 429, 1051, 1042, 436, 1006,
+ 1014, 528, 74, 1405, 80, 79, 480, 840, 1045, 1046,
+ 1395, 145, 973, 519, 1411, 670, 765, 435, 1005, 1015,
+ 442, 1008, 1017, 529, 823, 1062, 481, 482, 434, 1057,
+ 88, 87, 337, 89, 1393, 49, 50, 51, 52, 53,
+ 54, 55, 592, 277, 636, 277, 1391, 326, 323, 56,
+ 152, 1389, 1067, 1387, 1385, 277, 1383, 49, 50, 51,
+ 52, 53, 54, 55, 1381, 1379, 1376, 1373, 962, 1371,
+ 1367, 41, 43, 1351, 1327, 1209, 1208, 1056, 996, 1055,
+ 1134, 88, 87, 1315, 89, 762, 1079, 1054, 1080, 155,
+ 776, 63, 722, 46, 1053, 543, 1034, 1033, 1144, 828,
+ 1150, 1252, 616, 504, 820, 513, 737, 1131, 508, 509,
+ 618, 1136, 617, 1141, 578, 522, 527, 177, 565, 1065,
+ 1251, 308, 455, 1313, 109, 63, 1137, 1197, 92, 1145,
+ 1198, 1195, 1196, 964, 1316, 770, 1037, 520, 1311, 513,
+ 521, 1349, 508, 509, 1309, 1187, 1143, 695, 695, 992,
+ 1194, 1193, 145, 1207, 1190, 953, 1210, 1185, 1, 1418,
+ 1189, 1199, 1200, 1201, 1202, 1179, 1177, 1175, 1066, 589,
+ 1234, 1203, 1204, 1205, 1314, 49, 50, 51, 52, 53,
+ 54, 55, 712, 348, 88, 87, 1217, 89, 626, 1312,
+ 590, 1211, 1245, 1063, 1152, 1310, 1188, 1247, 152, 1218,
+ 1239, 1173, 1171, 1169, 145, 1238, 1237, 1240, 1186, 49,
+ 50, 51, 52, 53, 54, 55, 1180, 1178, 1176, 88,
+ 87, 348, 89, 74, 1167, 1165, 205, 155, 525, 352,
+ 1250, 711, 708, 353, 156, 157, 158, 1163, 192, 192,
+ 192, 192, 1135, 634, 277, 1161, 277, 1127, 192, 192,
+ 192, 357, 1174, 1172, 1170, 177, 591, 412, 378, 1433,
+ 626, 1263, 192, 46, 1159, 187, 794, 97, 88, 87,
+ 63, 89, 1157, 1430, 949, 1168, 1166, 1508, 1138, 1139,
+ 524, 1155, 351, 526, 317, 1266, 527, 1280, 1164, 1284,
+ 315, 1286, 1288, 1289, 1270, 1292, 1162, 1294, 1295, 1296,
+ 1297, 1298, 1299, 1300, 1274, 1302, 1303, 1304, 1305, 1306,
+ 1307, 1308, 1269, 1429, 313, 1160, 1317, 1318, 1291, 1320,
+ 1293, 1428, 1319, 1158, 1287, 1285, 1290, 152, 1301, 311,
+ 1419, 1236, 1156, 309, 1282, 308, 1060, 1322, 1212, 306,
+ 1213, 308, 1059, 844, 1328, 746, 667, 1233, 1333, 352,
+ 1332, 45, 94, 353, 49, 50, 51, 52, 53, 54,
+ 55, 454, 328, 329, 330, 308, 415, 88, 87, 277,
+ 89, 357, 156, 157, 158, 155, 591, 1558, 823, 1345,
+ 308, 1338, 1347, 1348, 308, 352, 1331, 332, 1330, 353,
+ 308, 56, 277, 152, 1272, 1353, 1357, 1147, 525, 277,
+ 140, 1215, 351, 177, 952, 1360, 1283, 357, 948, 1023,
+ 1359, 277, 827, 1281, 277, 138, 1350, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+ 131, 132, 1470, 839, 591, 1469, 838, 1361, 351, 817,
+ 63, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 591, 1346,
+ 524, 771, 764, 526, 1364, 258, 721, 796, 567, 117,
+ 1409, 1410, 349, 1414, 1396, 1413, 352, 1571, 1415, 591,
+ 772, 1043, 591, 591, 56, 1421, 1420, 931, 1583, 591,
+ 1426, 331, 303, 333, 334, 335, 336, 1574, 357, 1152,
+ 1572, 1565, 1541, 823, 1504, 1503, 88, 87, 1502, 89,
+ 1412, 1472, 1467, 134, 155, 1464, 1341, 96, 1423, 1461,
+ 104, 103, 102, 101, 1460, 99, 100, 105, 1456, 351,
+ 156, 157, 158, 1454, 49, 50, 51, 52, 53, 54,
+ 55, 1452, 177, 1450, 1437, 1509, 1431, 1427, 258, 1581,
+ 697, 1406, 1510, 1404, 1394, 1462, 1392, 1463, 1390, 1388,
+ 354, 355, 356, 97, 352, 1386, 836, 56, 353, 1473,
+ 1474, 1475, 88, 87, 1466, 89, 1471, 1384, 531, 1382,
+ 155, 88, 87, 1380, 89, 1378, 357, 1377, 1375, 1374,
+ 1488, 350, 1152, 1372, 1370, 1486, 56, 1369, 1366, 1489,
+ 1494, 1487, 88, 1365, 1566, 89, 1342, 1340, 177, 1476,
+ 1326, 1325, 1499, 1321, 1271, 46, 1498, 351, 1363, 1268,
+ 1235, 1516, 56, 1126, 1523, 1525, 1527, 1064, 1523, 1525,
+ 1527, 258, 1050, 206, 1534, 1525, 1048, 1041, 1040, 1532,
+ 1538, 1501, 1539, 1535, 1540, 1533, 1519, 1030, 969, 959,
+ 958, 947, 866, 1515, 1518, 1513, 849, 848, 846, 156,
+ 157, 158, 449, 843, 193, 1511, 837, 194, 835, 816,
+ 823, 795, 778, 742, 1523, 1525, 1527, 741, 740, 739,
+ 354, 355, 356, 738, 736, 88, 735, 688, 89, 638,
+ 198, 177, 570, 425, 424, 199, 344, 200, 46, 320,
+ 1564, 1497, 1493, 201, 1492, 1491, 1490, 1570, 1465, 1459,
+ 1458, 1568, 1449, 1448, 1447, 1446, 354, 355, 356, 1577,
+ 195, 1575, 1445, 1580, 1579, 156, 157, 158, 1582, 1444,
+ 1567, 1443, 1442, 1441, 1440, 196, 1439, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
+ 1438, 1436, 823, 1315, 59, 523, 1313, 1576, 208, 259,
+ 210, 228, 212, 213, 1311, 1309, 1339, 56, 88, 882,
+ 1187, 89, 41, 43, 56, 1185, 876, 1179, 877, 878,
+ 879, 46, 1177, 1175, 1173, 1171, 515, 1169, 1167, 61,
+ 62, 47, 63, 1165, 1163, 1161, 1324, 354, 355, 356,
+ 223, 1323, 1265, 96, 1264, 56, 104, 103, 102, 101,
+ 46, 99, 100, 105, 222, 1078, 871, 872, 873, 1068,
+ 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255, 256, 257, 998, 1061, 1052, 46, 59, 995, 994,
+ 426, 208, 259, 210, 228, 212, 213, 961, 851, 226,
+ 224, 1058, 850, 847, 845, 41, 43, 732, 731, 717,
+ 691, 687, 870, 874, 875, 686, 880, 665, 633, 881,
+ 603, 530, 61, 62, 47, 63, 49, 50, 51, 52,
+ 53, 54, 55, 223, 602, 354, 355, 356, 594, 568,
+ 548, 547, 497, 419, 411, 386, 319, 222, 304, 518,
+ 302, 510, 507, 245, 246, 247, 248, 249, 250, 251,
+ 252, 253, 254, 255, 256, 257, 503, 36, 184, 93,
+ 59, 33, 469, 467, 208, 259, 210, 228, 212, 213,
+ 466, 465, 226, 224, 95, 464, 244, 463, 41, 43,
+ 227, 243, 215, 209, 1098, 38, 30, 58, 32, 59,
+ 207, 211, 887, 31, 1010, 61, 62, 47, 63, 49,
+ 50, 51, 52, 53, 54, 55, 223, 41, 43, 1000,
+ 439, 38, 30, 58, 32, 59, 869, 799, 431, 798,
+ 222, 46, 430, 427, 61, 62, 47, 63, 46, 540,
+ 270, 60, 35, 41, 43, 83, 29, 21, 57, 34,
+ 37, 25, 16, 263, 15, 189, 14, 39, 40, 261,
+ 61, 62, 47, 63, 13, 226, 224, 60, 35, 46,
+ 260, 12, 11, 21, 9, 8, 37, 4, 2, 444,
+ 234, 242, 241, 39, 40, 240, 444, 239, 238, 237,
+ 236, 235, 49, 50, 51, 52, 53, 54, 55, 233,
+ 232, 231, 230, 229, 114, 77, 42, 756, 658, 657,
+ 1500, 299, 19, 20, 90, 22, 23, 48, 183, 27,
+ 28, 49, 50, 51, 52, 53, 54, 55, 1151, 761,
+ 789, 1273, 965, 1149, 1148, 605, 1479, 1478, 19, 20,
+ 1477, 22, 23, 48, 1495, 27, 28, 49, 50, 51,
+ 52, 53, 54, 55, 882, 1481, 1480, 1216, 1132, 598,
+ 661, 876, 781, 877, 878, 879, 448, 91, 58, 32,
+ 59, 1081, 743, 448, 65, 58, 32, 59, 64, 197,
+ 445, 883, 0, 0, 0, 446, 0, 445, 41, 43,
+ 929, 0, 446, 0, 0, 41, 43, 0, 0, 0,
+ 0, 871, 872, 873, 0, 61, 62, 47, 63, 1109,
+ 437, 438, 61, 62, 47, 63, 0, 437, 438, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1085, 1086,
+ 447, 1093, 1107, 1087, 1088, 1089, 1090, 447, 1091, 1092,
+ 0, 1108, 1094, 1095, 1096, 1097, 63, 870, 874, 875,
+ 0, 880, 0, 0, 881, 0, 532, 0, 0, 533,
+ 0, 0, 0, 0, 0, 443, 440, 0, 0, 0,
+ 0, 0, 443, 440, 0, 0, 0, 0, 0, 882,
+ 0, 0, 0, 0, 193, 0, 876, 194, 877, 878,
+ 879, 0, 49, 50, 51, 52, 53, 54, 55, 49,
+ 50, 51, 52, 53, 54, 55, 0, 0, 0, 0,
+ 198, 177, 0, 0, 0, 199, 0, 200, 0, 0,
+ 0, 0, 0, 201, 901, 0, 871, 872, 873, 0,
+ 49, 50, 51, 52, 53, 54, 55, 146, 928, 0,
+ 195, 0, 0, 893, 894, 0, 902, 919, 895, 896,
+ 897, 898, 0, 899, 900, 196, 920, 903, 904, 905,
+ 906, 0, 0, 0, 0, 348, 0, 0, 0, 0,
+ 0, 0, 870, 874, 875, 0, 880, 0, 0, 881,
+ 1232, 1231, 1226, 0, 1225, 1224, 1223, 1222, 0, 1220,
+ 1221, 105, 0, 1230, 1229, 1228, 1227, 0, 0, 0,
+ 0, 917, 1219, 921, 0, 990, 989, 988, 923, 983,
+ 982, 981, 980, 0, 978, 979, 105, 0, 987, 986,
+ 985, 984, 0, 0, 925, 977, 975, 0, 1542, 0,
+ 0, 0, 0, 0, 0, 1083, 1084, 0, 1099, 1100,
+ 1101, 0, 1102, 1103, 0, 0, 1104, 1105, 0, 1106,
+ 0, 0, 0, 0, 0, 0, 0, 926, 0, 0,
+ 0, 0, 1082, 1110, 1111, 1112, 1113, 1114, 1115, 1116,
+ 1117, 1118, 1119, 1120, 1121, 1122, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 901,
+ 0, 0, 976, 0, 0, 1512, 0, 0, 0, 0,
+ 0, 0, 0, 928, 0, 0, 0, 0, 893, 894,
+ 0, 902, 919, 895, 896, 897, 898, 0, 899, 900,
+ 0, 920, 903, 904, 905, 906, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 146, 0, 0, 0, 0, 888, 0, 889,
+ 890, 891, 892, 907, 908, 909, 924, 910, 911, 912,
+ 913, 914, 915, 916, 918, 922, 917, 0, 921, 927,
+ 0, 0, 0, 923, 0, 175, 0, 0, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 925,
+ 168, 169, 0, 0, 171, 172, 173, 174, 564, 1557,
+ 152, 142, 162, 0, 0, 0, 0, 0, 0, 0,
+ 141, 147, 0, 1547, 0, 0, 0, 0, 0, 0,
+ 0, 0, 926, 0, 0, 0, 143, 144, 149, 1543,
+ 556, 0, 550, 551, 552, 553, 0, 0, 1552, 0,
+ 0, 146, 0, 0, 0, 0, 352, 0, 0, 0,
+ 772, 0, 1553, 1554, 1555, 1556, 0, 0, 0, 0,
+ 0, 160, 0, 0, 0, 0, 0, 0, 357, 558,
+ 559, 560, 561, 0, 0, 555, 0, 0, 0, 562,
+ 563, 554, 0, 0, 1544, 1545, 1546, 1548, 1549, 1550,
+ 1551, 0, 0, 0, 0, 0, 0, 0, 0, 623,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 888, 0, 889, 890, 891, 892, 907, 908,
+ 909, 924, 910, 911, 912, 913, 914, 915, 916, 918,
+ 922, 990, 989, 988, 927, 983, 982, 981, 980, 0,
+ 978, 979, 105, 0, 987, 986, 985, 984, 0, 0,
+ 0, 977, 975, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,
+ 87, 0, 89, 0, 0, 0, 0, 155, 0, 0,
+ 175, 0, 0, 557, 151, 148, 163, 161, 170, 0,
+ 164, 165, 166, 167, 0, 168, 169, 0, 0, 171,
+ 172, 173, 174, 146, 0, 177, 142, 162, 352, 0,
+ 0, 0, 353, 0, 0, 141, 147, 0, 976, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 357, 143, 144, 149, 0, 0, 175, 0, 0, 0,
+ 0, 0, 163, 161, 170, 0, 164, 165, 166, 167,
+ 0, 168, 169, 0, 0, 171, 172, 173, 174, 0,
+ 0, 623, 1276, 162, 0, 0, 160, 159, 88, 87,
+ 0, 89, 0, 0, 0, 0, 155, 0, 0, 175,
+ 0, 0, 0, 151, 148, 163, 161, 170, 0, 164,
+ 165, 166, 167, 0, 168, 169, 0, 0, 171, 172,
+ 173, 174, 0, 0, 177, 142, 162, 0, 0, 0,
+ 1277, 0, 0, 0, 141, 147, 0, 0, 0, 0,
+ 297, 198, 156, 157, 158, 0, 199, 0, 200, 1275,
+ 143, 144, 149, 0, 201, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 146, 0, 0, 0, 0, 352,
+ 0, 195, 284, 353, 279, 280, 281, 282, 283, 63,
+ 0, 0, 0, 287, 0, 160, 196, 354, 355, 356,
+ 0, 357, 285, 0, 0, 0, 0, 295, 0, 286,
+ 0, 641, 642, 0, 0, 0, 0, 0, 0, 0,
+ 0, 288, 289, 290, 291, 292, 293, 294, 298, 0,
+ 0, 0, 623, 0, 296, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 156, 157, 158, 0, 0, 0, 0, 0, 0,
+ 88, 87, 0, 89, 0, 0, 0, 0, 155, 146,
+ 0, 175, 0, 0, 0, 151, 148, 163, 161, 170,
+ 0, 164, 165, 166, 167, 0, 168, 169, 0, 0,
+ 171, 172, 173, 174, 0, 0, 177, 142, 162, 0,
+ 0, 0, 0, 0, 0, 0, 141, 147, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 143, 144, 149, 0, 0, 274, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 146, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 160, 0, 354,
+ 355, 356, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 641, 642, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 274, 0, 0, 0, 0,
+ 0, 88, 87, 0, 89, 0, 0, 0, 0, 155,
+ 0, 0, 175, 156, 157, 158, 151, 148, 163, 161,
+ 170, 0, 164, 165, 166, 167, 0, 168, 169, 0,
+ 0, 171, 172, 173, 174, 0, 146, 177, 142, 162,
+ 0, 0, 0, 0, 0, 0, 0, 141, 147, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 143, 144, 149, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 274, 0, 88, 87, 160, 89,
+ 354, 355, 356, 0, 155, 146, 0, 175, 0, 0,
+ 0, 151, 148, 163, 161, 170, 0, 164, 165, 166,
+ 167, 0, 168, 169, 0, 0, 171, 172, 173, 174,
+ 0, 0, 177, 142, 162, 0, 0, 0, 0, 0,
+ 0, 0, 141, 147, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 156, 157, 158, 0, 143, 144,
+ 149, 0, 811, 274, 88, 87, 0, 89, 0, 0,
+ 0, 0, 155, 0, 0, 175, 0, 146, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 0, 160, 171, 172, 173, 174, 0, 0,
+ 177, 142, 162, 0, 0, 0, 0, 810, 0, 0,
+ 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
+ 0, 0, 0, 0, 0, 274, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 146, 0, 0, 156,
+ 157, 158, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 160, 159, 88, 87, 0, 89, 0, 0, 0,
+ 0, 155, 0, 0, 175, 0, 0, 0, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 0, 0, 171, 172, 173, 174, 0, 0, 177,
+ 142, 162, 0, 0, 274, 0, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 156, 157, 158,
+ 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
+ 0, 0, 88, 87, 0, 89, 0, 0, 0, 0,
+ 155, 0, 0, 175, 0, 0, 0, 151, 148, 163,
+ 161, 170, 0, 164, 165, 166, 167, 0, 168, 169,
+ 160, 0, 171, 172, 173, 174, 0, 0, 177, 142,
+ 162, 0, 0, 0, 0, 0, 0, 0, 763, 147,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 146, 0, 143, 144, 149, 0, 0, 0,
+ 0, 0, 0, 0, 88, 87, 0, 89, 0, 0,
+ 0, 0, 155, 0, 0, 175, 156, 157, 158, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 160,
+ 168, 169, 0, 0, 171, 172, 173, 174, 0, 0,
+ 177, 142, 162, 0, 0, 0, 0, 146, 0, 0,
+ 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
+ 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
+ 0, 155, 0, 0, 175, 156, 157, 158, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 653, 146, 171, 172, 173, 174, 0, 0, 177,
+ 142, 162, 88, 87, 0, 89, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
+ 0, 0, 0, 0, 0, 0, 409, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 156, 157, 158,
+ 996, 0, 0, 146, 0, 0, 0, 0, 0, 0,
+ 458, 0, 0, 0, 391, 0, 0, 0, 407, 0,
+ 0, 389, 390, 0, 0, 0, 393, 394, 405, 395,
+ 396, 397, 398, 399, 400, 401, 402, 392, 0, 0,
+ 0, 0, 0, 0, 406, 0, 0, 404, 0, 0,
+ 0, 0, 0, 0, 403, 0, 0, 146, 0, 0,
+ 0, 726, 0, 408, 0, 0, 156, 157, 158, 489,
+ 175, 490, 0, 0, 151, 148, 163, 161, 170, 0,
+ 164, 165, 166, 167, 0, 168, 169, 0, 0, 171,
+ 172, 173, 174, 0, 0, 177, 142, 162, 0, 0,
+ 0, 0, 0, 0, 0, 141, 147, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 143, 144, 149, 380, 175, 381, 0, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 0, 0, 171, 172, 173, 174, 0, 0,
+ 0, 142, 162, 0, 0, 0, 160, 0, 0, 0,
+ 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
+ 175, 0, 0, 0, 151, 148, 163, 161, 170, 0,
+ 164, 165, 166, 167, 0, 168, 169, 0, 0, 171,
+ 172, 173, 174, 0, 0, 0, 142, 162, 0, 0,
+ 0, 160, 0, 0, 0, 141, 147, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 143, 144, 149, 0, 0, 0, 0, 0, 0,
+ 0, 175, 0, 0, 0, 151, 148, 163, 161, 170,
+ 0, 164, 165, 166, 167, 0, 168, 169, 0, 0,
+ 171, 172, 173, 174, 0, 0, 160, 142, 162, 0,
+ 0, 0, 0, 0, 0, 0, 141, 147, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 143, 144, 149, 175, 0, 0, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 0, 0, 171, 172, 173, 174, 0, 0,
+ 0, 142, 162, 0, 0, 0, 0, 160, 0, 0,
+ 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 160
+};
+
+YYSTATIC YYCONST short YYFARDATA YYPACT[] = {
+-1000, 1423,-1000, 609, 586,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 581, 555, 539, 514,-1000,-1000,-1000, 102,
+ 102, -466, 124, 124,-1000,-1000,-1000, 478,-1000, -115,
+ 535,-1000, 907, 1099, 68, 903, 102, -355, -356,-1000,
+ -139, 855, 68, 855,-1000,-1000,-1000, 172, 2319, 535,
+ 535, 535, 535,-1000,-1000, 187,-1000,-1000,-1000, -164,
+ 1074,-1000,-1000, 1825, 68, 68,-1000,-1000, 1368,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 102, -121,-1000,-1000,
+-1000,-1000, 691, -120, 2983, 1193,-1000,-1000,-1000,-1000,
+ 2436,-1000, 102,-1000, 1385,-1000, 1310, 1718, 68, 1169,
+ 1163, 1159, 1144, 1120, 1114, 1716, 1518, 83,-1000, 102,
+ 655, 878,-1000,-1000, 86, 1193, 535, 2983,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000, 1515, 185, 1288, 1061, -229, -230, -231,
+ -238, 691,-1000, -101, 691, 1255, 312,-1000,-1000, 48,
+-1000, 3564, 239, 1081,-1000,-1000,-1000,-1000,-1000, 3394,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 504,-1000,-1000,-1000,-1000,-1000, 1193, 1715, 538, 1193,
+ 1193, 1193,-1000, 3232, 123,-1000,-1000, 1714, 1066, 2884,
+-1000, 3564,-1000,-1000,-1000, 65, 65,-1000, 1713,-1000,
+-1000, 99, 1513, 1512, 1575, 1397,-1000,-1000, 102,-1000,
+ 102, 87,-1000,-1000,-1000,-1000, 1173,-1000,-1000,-1000,
+-1000,-1000, 901, 102, 3193,-1000, 21, -69,-1000,-1000,
+ 201, 102, 124, 610, 68, 201, 1255, 3339, 2983, -88,
+ 65, 2884, 1712,-1000, 215,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 511, 545, 860, 1606,-1000, 100,-1000, 355, 691,-1000,
+-1000, 2983,-1000,-1000, 164, 1217, 65, 535,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1711, 1710, 2114,
+ 895, 349, 1284, 1709, 123, 1511, -48,-1000, 102, -48,
+-1000, 124,-1000, 102,-1000, 102,-1000, 102,-1000,-1000,
+-1000,-1000, 891,-1000, 102, 102,-1000, 1193,-1000,-1000,
+-1000, -369,-1000,-1000,-1000,-1000,-1000, 878, -47, 116,
+-1000,-1000, 1193, 999,-1000, 1299, 789, 1708,-1000, 170,
+ 535, 157,-1000,-1000,-1000, 1704, 1690, 3564, 535, 535,
+ 535, 535,-1000, 691,-1000,-1000, 3564, 228,-1000, 1193,
+-1000, -68,-1000, 1217, 879, 889, 887, 535, 535, 2721,
+-1000,-1000,-1000,-1000,-1000,-1000, 102, 1299, 1070,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000, 406,-1000,-1000,-1000, 1688,
+ 1052,-1000, 791, 1508,-1000,-1000, 2580,-1000,-1000, 102,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 458,
+ 446, 417,-1000,-1000,-1000,-1000,-1000, 102, 102, 402,
+ 3124,-1000,-1000, -304, -196,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, -53, 1687,-1000, 102, 1158, 39, 65, 794,
+ 640, 102,-1000, -69, 107, 107, 107, 107, 2983, 215,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000, 1685, 1681, 1506,-1000,-1000,-1000, 2721,-1000,-1000,
+-1000,-1000, 1299, 1680, 68, 3564,-1000, 201, 1285,-1000,
+ -119, -124,-1000,-1000, -351,-1000,-1000, 68, 411, 454,
+ 68,-1000,-1000, 1041,-1000,-1000, 68,-1000, 68,-1000,
+ 1040, 991,-1000,-1000, 535, -157, -360, 1679,-1000,-1000,
+-1000,-1000, 535, -361,-1000,-1000, -346,-1000,-1000,-1000,
+ 1282,-1000, 869, 535, 3564, 1193, 3510, 102, 108, 1181,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1678,-1000,-1000,
+-1000,-1000,-1000,-1000, 1677,-1000,-1000, 1385, 108, 1505,
+-1000, 1503, 883, 1502, 1498, 1497, 1496, 1492,-1000, 362,
+ 1157,-1000, 97, 1193,-1000,-1000,-1000, 298, 535, 108,
+ 388, 175, 3052,-1000,-1000, 1278, 1193,-1000, 793,-1000,
+-1000, -50, 2983, 2983, 943, 1277, 1217, 1193, 1193, 1193,
+ 1193,-1000, 2418,-1000, 1193,-1000, 535, 535, 535, 867,
+ 1193, 33, 1193, 494, 1491,-1000, 128,-1000,-1000,-1000,
+-1000,-1000,-1000, 102,-1000, 1299,-1000,-1000, 1255, 30,
+ 1076,-1000,-1000, 1193, 1490, 1202,-1000,-1000,-1000,-1000,
+-1000,-1000, -10, 65, 465, 459, 2983, 2816, -106, -47,
+ 1488, 1265,-1000,-1000, 3510, -53, 881, 102, -96, 3564,
+ 102, 1193, 102, 1238, 876,-1000,-1000,-1000, 201,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 102, 124,-1000, -18,
+ 1193, 108, 1487, 1386, 1485, 1262, 1259,-1000, 123, 102,
+ 102, 1482, 1155,-1000,-1000, 1299, 1674, 1477, 1673, 1476,
+ 1475, 1672, 1668, 1193, 535,-1000, 535, 102, 141, 535,
+ 68, 2983, 535, 706, 1298, 81, -182, 1471, 95, 1795,
+ 131, 1877, 102,-1000, 1306,-1000, 900,-1000, 900, 900,
+ 900, 900, 900, -166,-1000, 102, 102, 535,-1000,-1000,
+-1000,-1000,-1000,-1000, 1193, 1470, 1234, 1083,-1000,-1000,
+ 347, 1230, 964, 271, 166,-1000, 46, 102, 1469, 1468,
+-1000, 3564, 1667, 1081, 1081, 1081, 535, 535,-1000, 941,
+ 542, 128,-1000,-1000,-1000,-1000,-1000, 1467, 343, 226,
+ 958, -96, 1659, 1658, 3449,-1000,-1000, 1568, 104, 204,
+ 690, -96, 3564, 102, 1193, 102, 1235, -322, 535, 1193,
+-1000,-1000, 3564,-1000,-1000, 1193,-1000, -53, 81, 1466,
+ -241,-1000,-1000, 1193, 2721, 874, 873, 2983, 945, -126,
+ -137, 1457, 1456, 535, 1300,-1000, -53,-1000, 201, 201,
+-1000,-1000,-1000,-1000, 411,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 1081, 1193, 1455, 102, 1193, 1451,-1000, 535,
+ -96, 1655, 871, 864, 856, 854,-1000, 108, 1670,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 1154, 1148, 1654, 945, 123, 1446, 947, 68, 1639, -405,
+ -56,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 495,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000, 1635, 1635,-1000, 1635, 1762,-1000,
+-1000, -408,-1000, -387,-1000,-1000, -429,-1000,-1000,-1000,
+ 1442,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 123,-1000,
+-1000,-1000,-1000,-1000, 165, 331, 1193,-1000, 108, 829,
+ 338,-1000, 3052, 374, 955,-1000,-1000,-1000,-1000,-1000,
+ 1217, -53, 1081, 1193,-1000, 535, 1223, 2983,-1000,-1000,
+-1000, 393,-1000,-1000,-1000, 1111, 1102, 1094, 1075, 1067,
+ 1055, 1054, 1033, 1032, 1031, 997, 996, 995, 399, 987,
+ 975, 68, 455, 1076, -53, -53, 102, 938,-1000,-1000,
+-1000, 1255, 1255, 1255, 1255,-1000,-1000,-1000,-1000,-1000,
+-1000, 1255, 1255, 1255,-1000,-1000,-1000,-1000,-1000, -441,
+ 2721, 853, 852, 2983,-1000, 1255, 1193, 1181,-1000, 123,
+-1000, 123, -23,-1000, 1227,-1000,-1000, 1913, 123, 102,
+-1000,-1000, 1193,-1000, 1439,-1000,-1000, 1143,-1000,-1000,
+ -287, 998, 1877,-1000,-1000,-1000,-1000, 1299,-1000, -236,
+ -257, 102,-1000,-1000,-1000,-1000, 383, 192, 108, 899,
+ 880,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -434,-1000,
+-1000, 35,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000, 336,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 102,-1000,-1000,-1000,-1000, 1624, 1299, 1622,-1000,-1000,
+-1000,-1000,-1000, 359, 1438, 1223,-1000, 128, 1433, 1220,
+-1000, 2375,-1000,-1000,-1000, -37, 102, 977, 102, 1938,
+ 102, 110, 102, 93, 102, 124, 102, 102, 102, 102,
+ 102, 102, 102, 124, 102, 102, 102, 102, 102, 102,
+ 102, 974, 968, 953, 913, 102, 102, -112, 102, 1432,
+ 1299,-1000,-1000, 1621, 1616, 1430, 1429, 851,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 65, -25,-1000, 1214,
+-1000, 1216,-1000,-1000, -96, 2983,-1000,-1000, 1299,-1000,
+ 1615, 1614, 1613, 1608, 1607, 1605, 18, 1604, 1603, 1602,
+ 1597, 1595, 1590,-1000,-1000,-1000, 411,-1000, 1586, 1426,
+ 1335,-1000,-1000,-1000,-1000, 1425,-1000, 740, 102,-1000,
+ 1275, 102, 102, 950, 108, 850,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000, 155, 102, 5, 371,-1000,-1000,-1000,
+-1000,-1000, 2983, 395,-1000,-1000,-1000, 1172, 1422, 1417,
+ 847, 144, 1416, 1413, 846, 1412, 844, 1408, 1407, 843,
+ 1406, 1404, 842, 1402, 841, 1398, 833, 1396, 831, 1384,
+ 830, 1378, 828, 1377, 823, 1375, 811, 1373, 787, 124,
+ 102, 102, 102, 102, 102, 102, 102, 1372, 780, 1370,
+ 759,-1000, 332, -53, -53,-1000,-1000, 822, 3564, -96,
+ 2983, -53, 969,-1000, 1585, 1584, 1576, 1573, 1142, -53,
+-1000,-1000,-1000,-1000, 102, 758, 108, 757, 752, 102,
+ 1299,-1000,-1000, 1366, 1133, 1125, 1085, 1365,-1000, 73,
+-1000, 1068, 735, 101,-1000,-1000,-1000, 1571, 1363,-1000,
+-1000, 1570,-1000, 1556,-1000,-1000, 1554,-1000,-1000, 1553,
+-1000, 1552,-1000, 1551,-1000, 1549,-1000, 1542,-1000, 1535,
+-1000, 1534,-1000, 1533,-1000, 1532, 1362, 723, 1360, 716,
+ 1352, 687, 1347, 677,-1000, 1530,-1000, 1529,-1000, 1343,
+ 1338,-1000, 2721, 969,-1000, 1334, 1528,-1000, 857, 411,
+ 1331, 429,-1000, 1261,-1000, 2042, 1330,-1000, 102, 102,
+ 102,-1000,-1000, 1938,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000, 1526,-1000, 1525,-1000, 1524,-1000, 1522,-1000,-1000,
+-1000,-1000, -39, 1521, 945, -53,-1000,-1000,-1000, 108,
+-1000, 947,-1000, 1327, 1324, 1323,-1000, 182, 1106, 2264,
+ 428, 278, 527, 608, 582, 562, 443, 544, 530, 426,
+-1000,-1000,-1000,-1000, 405, 135, -96, -53,-1000, 1321,
+ 2115, 1203,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 88,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 328, 381, 357, 350,-1000,-1000,-1000, 1520,
+ 1320,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1424, 108,-1000,
+-1000,-1000,-1000,-1000, -53, -443, 102, 1296, 1319, -188,
+ 1316,-1000,-1000, 65,-1000, 3564, 2721, -46, -96, 969,
+ 1369, -53, 1307,-1000
+};
+
+YYSTATIC YYCONST short YYFARDATA YYPGO[] = {
+ 0, 33, 178, 5, 1991, 78, 39, 7, 1989, 0,
+ 1988, 1984, 1982, 268, 80, 1981, 1977, 4, 1972, 52,
+ 40, 3, 26, 32, 24, 6, 1970, 44, 41, 45,
+ 1969, 38, 34, 10, 17, 11, 31, 1968, 42, 1967,
+ 35, 18, 1966, 1965, 9, 1, 13, 8, 1954, 1950,
+ 1947, 1946, 22, 27, 43, 1945, 1944, 1943, 1942, 15,
+ 1941, 1940, 12, 1939, 30, 1938, 14, 36, 16, 23,
+ 46, 2, 599, 59, 1236, 29, 106, 1928, 1924, 1921,
+ 1920, 1919, 1918, 19, 28, 1917, 1329, 1916, 1915, 25,
+ 789, 131, 1914, 50, 1221, 1913, 1912, 1911, 1910, 1909,
+ 1901, 1900, 1899, 1898, 1897, 1895, 1892, 1891, 1890, 1028,
+ 1888, 67, 56, 1887, 65, 134, 62, 55, 1885, 1884,
+ 89, 1882, 1881, 1880, 1874, 1869, 1866, 53, 1864, 1863,
+ 1862, 100, 70, 49, 1861, 92, 292, 1859, 1858, 1856,
+ 1855, 1850, 1849, 1843, 1842, 1839, 1838, 1837, 1830, 832,
+ 1829, 1814, 1813, 1812, 1811, 1810, 1803, 1802, 75, 1801,
+ 1800, 125, 1797, 1796, 1795, 130, 1791, 1790, 1783, 1782,
+ 1781, 1779, 1778, 58, 1760, 63, 1777, 54, 1776, 602,
+ 1762, 1761, 1759, 1646, 1615, 1438
+};
+YYSTATIC YYCONST yyr_t YYFARDATA YYR1[]={
+
+ 0, 109, 109, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 136,
+ 136, 36, 36, 133, 133, 133, 2, 2, 1, 1,
+ 1, 9, 24, 24, 23, 23, 23, 134, 134, 134,
+ 134, 134, 135, 135, 135, 135, 135, 135, 135, 135,
+ 135, 93, 93, 93, 93, 94, 94, 94, 94, 10,
+ 11, 73, 72, 72, 59, 61, 61, 61, 62, 62,
+ 62, 65, 65, 132, 132, 132, 60, 60, 60, 60,
+ 60, 60, 130, 130, 130, 119, 12, 12, 12, 12,
+ 12, 12, 118, 137, 113, 138, 139, 111, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 140, 140, 141, 141, 112,
+ 112, 142, 142, 56, 56, 57, 57, 69, 69, 18,
+ 18, 18, 18, 18, 19, 19, 68, 68, 67, 67,
+ 58, 21, 21, 22, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 116, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 4, 4, 35, 35, 16, 16, 75, 75,
+ 75, 75, 75, 75, 75, 7, 7, 7, 7, 8,
+ 8, 8, 8, 8, 8, 8, 8, 76, 74, 74,
+ 74, 74, 74, 74, 144, 144, 81, 81, 81, 145,
+ 145, 150, 150, 150, 150, 150, 150, 150, 150, 146,
+ 82, 82, 82, 147, 147, 151, 151, 151, 151, 151,
+ 151, 151, 152, 38, 38, 34, 34, 153, 114, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 3, 3,
+ 3, 13, 13, 13, 13, 13, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 154, 115, 115, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 158, 159, 156, 161, 161, 160, 160, 160, 163,
+ 162, 162, 162, 162, 166, 166, 166, 169, 164, 167,
+ 168, 165, 165, 165, 117, 170, 170, 172, 172, 172,
+ 171, 171, 173, 173, 14, 14, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 175, 31, 31, 32, 32, 39, 39, 39, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 42, 42, 42, 43, 43, 43,
+ 47, 47, 46, 46, 45, 45, 44, 44, 48, 48,
+ 49, 49, 49, 50, 50, 50, 50, 51, 51, 149,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 6, 6, 6,
+ 6, 6, 53, 53, 54, 54, 55, 55, 25, 25,
+ 26, 26, 27, 27, 27, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 5, 5, 71, 71, 71,
+ 71, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 20, 20, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 30,
+ 30, 29, 29, 29, 29, 29, 131, 131, 131, 131,
+ 131, 131, 64, 64, 64, 63, 63, 87, 87, 84,
+ 84, 85, 17, 17, 37, 37, 37, 37, 37, 37,
+ 37, 37, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 176, 176, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 121, 121, 88, 88, 89, 89, 177, 122, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 123, 123,
+ 178, 178, 178, 66, 66, 179, 179, 179, 179, 179,
+ 179, 180, 182, 181, 124, 124, 125, 125, 183, 183,
+ 183, 183, 126, 148, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 127, 127, 184, 184, 184, 184,
+ 184, 184, 184, 128, 128, 92, 92, 92, 129, 129,
+ 185, 185, 185, 185 };
+YYSTATIC YYCONST yyr_t YYFARDATA YYR2[]={
+
+ 0, 0, 2, 4, 4, 3, 1, 1, 1, 1,
+ 1, 1, 4, 4, 4, 4, 1, 1, 1, 2,
+ 2, 3, 2, 2, 1, 1, 1, 4, 1, 0,
+ 2, 1, 3, 2, 4, 6, 1, 1, 1, 1,
+ 3, 1, 1, 1, 1, 4, 4, 4, 4, 4,
+ 4, 4, 2, 3, 2, 2, 2, 1, 1, 2,
+ 1, 2, 4, 6, 3, 5, 7, 9, 3, 4,
+ 7, 1, 1, 1, 2, 0, 2, 2, 0, 6,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 2, 3, 1, 2, 3, 7, 0, 2, 2, 2,
+ 2, 2, 3, 3, 2, 1, 4, 3, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 2, 2, 2, 5, 0, 2, 0, 2, 0,
+ 2, 3, 1, 0, 1, 1, 3, 0, 3, 1,
+ 1, 1, 1, 1, 0, 2, 4, 3, 0, 2,
+ 3, 0, 1, 5, 3, 4, 4, 4, 1, 1,
+ 1, 1, 1, 2, 2, 4, 13, 22, 1, 1,
+ 5, 3, 7, 5, 4, 7, 0, 2, 2, 2,
+ 2, 2, 2, 2, 5, 2, 2, 2, 2, 2,
+ 2, 5, 0, 2, 0, 2, 0, 3, 9, 9,
+ 7, 7, 1, 1, 1, 2, 2, 1, 4, 0,
+ 1, 1, 2, 2, 2, 2, 1, 4, 2, 5,
+ 3, 2, 2, 1, 4, 3, 0, 2, 2, 0,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 9,
+ 0, 2, 2, 0, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 0, 4, 1, 3, 1, 13, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 5, 8,
+ 6, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 4, 4, 4, 4, 5, 1, 1,
+ 1, 0, 4, 4, 4, 4, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 5, 1, 0, 2, 2, 1, 2, 4, 5,
+ 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
+ 4, 6, 4, 4, 11, 1, 5, 3, 7, 5,
+ 5, 3, 1, 2, 2, 1, 2, 4, 4, 1,
+ 2, 2, 2, 2, 2, 2, 2, 1, 2, 1,
+ 1, 1, 4, 4, 2, 4, 2, 0, 1, 1,
+ 3, 1, 3, 1, 0, 3, 5, 4, 3, 5,
+ 5, 5, 5, 5, 5, 2, 2, 2, 2, 2,
+ 2, 4, 4, 4, 4, 4, 4, 4, 4, 5,
+ 5, 5, 5, 4, 4, 4, 4, 4, 4, 3,
+ 2, 0, 1, 1, 2, 1, 1, 1, 1, 4,
+ 4, 5, 4, 4, 4, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 8, 8, 8, 8, 7,
+ 7, 7, 7, 7, 0, 2, 2, 0, 2, 2,
+ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
+ 0, 2, 2, 0, 2, 3, 2, 0, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 2, 2, 2, 2, 2,
+ 2, 3, 2, 2, 2, 5, 3, 2, 2, 2,
+ 2, 2, 5, 4, 6, 2, 4, 0, 3, 3,
+ 1, 1, 0, 3, 0, 1, 1, 3, 0, 1,
+ 1, 3, 1, 3, 4, 4, 4, 4, 5, 1,
+ 1, 1, 1, 1, 1, 1, 3, 1, 3, 4,
+ 1, 0, 10, 6, 5, 6, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 1, 1, 1, 1, 2, 3, 4, 6,
+ 5, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 1, 2, 2, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 1, 0, 5, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 3,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 1, 3,
+ 2, 3, 4, 2, 2, 2, 5, 5, 7, 4,
+ 3, 2, 3, 2, 1, 1, 2, 3, 2, 1,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 3, 0, 1, 1, 3, 2, 6, 7, 3, 3,
+ 3, 6, 0, 1, 3, 5, 6, 4, 4, 1,
+ 3, 3, 1, 1, 1, 1, 4, 1, 6, 6,
+ 6, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 2, 5, 4, 7, 6, 7, 6, 9, 8, 3,
+ 8, 4, 0, 2, 0, 1, 3, 3, 0, 2,
+ 2, 2, 3, 2, 2, 2, 2, 2, 0, 2,
+ 3, 1, 1, 1, 1, 3, 8, 2, 3, 1,
+ 1, 3, 3, 3, 4, 6, 0, 2, 3, 1,
+ 3, 1, 4, 3, 0, 2, 2, 2, 3, 3,
+ 3, 3, 3, 3, 0, 2, 2, 3, 3, 4,
+ 2, 1, 1, 3, 5, 0, 2, 2, 0, 2,
+ 4, 3, 1, 1 };
+YYSTATIC YYCONST short YYFARDATA YYCHK[]={
+
+-1000,-109,-110,-111,-113,-114,-116,-117,-118,-119,
+-120,-121,-122,-124,-126,-128,-130,-131,-132, 525,
+ 526, 460, 528, 529,-133,-134,-135, 532, 533,-139,
+ 409,-152, 411,-170,-137, 455,-176, 463, 408, 470,
+ 471, 430, -87, 431, -93, -94, 273, 449, 530, 534,
+ 535, 536, 537, 538, 539, 540, 59,-138, 410, 412,
+ 454, 447, 448, 450, -10, -11, 123, 123,-115, 123,
+ 123, 123, 123, -9, 264, -9, 527, -88, -24, 265,
+ 264, -24, 123,-140, 314, -1, -2, 261, 260, 263,
+ -78, -16, 91,-171, 123,-174, 278, 38,-175, 286,
+ 287, 284, 283, 282, 281, 288, -31, -32, 267, 91,
+ -9, -90, 469, 469, -92, -1, 469, -86, 432, 433,
+ 434, 435, 436, 437, 438, 439, 440, 441, 442, 443,
+ 444, 445, 446, -31, -86, 263, -28, -70, -74, -93,
+ -94, 306, 297, 322, 323,-149, 33, 307, 276, 324,
+ -52, 275, 91, -5, -76, 268, 413, 414, 415, 358,
+ 357, 278, 298, 277, 281, 282, 283, 284, 286, 287,
+ 279, 290, 291, 292, 293, 271, -1, 296, -1, -1,
+ -1, -1, 262, -77,-172, 318, 379, 61, -73, 40,
+ -75, -7, -76, 269, 272, 325, 340, -8, 295, 300,
+ 302, 308, -31, -31,-112,-109, 125,-155, 416,-156,
+ 418,-154, 420, 421,-117,-157, -2,-131,-120,-133,
+-132,-135, 472, 458, 508,-158, 507,-160, 419, -95,
+ -96, -97, -98, -99,-108,-100,-101,-102,-103,-104,
+-105,-106,-107,-159,-163, 395, 396, 397, 398, 399,
+ 400, 401, 402, 403, 404, 405, 406, 407, 123, 417,
+-123,-125,-127,-129, -9, -1, 461,-136, -70, -76,
+-141, 315, -71, -70, 91, -28,-149, 46, -7, 328,
+ 329, 330, 331, 332, 326, 346, 353, 337, 365, 366,
+ 367, 368, 369, 370, 371, 351, 378, 294, 372, -79,
+ -9,-173,-174, 42, 40, -31, 40, -14, 91, 40,
+ -14, 40, -14, 40, -14, 40, -14, 40, -14, 40,
+ 41, 267, -9, 263, 58, 44, 262, -1, 354, 355,
+ 356, 473, 379, 475, 476, 477, 478, -90, -91, -1,
+ 329, 330, -1, -71, 41, -36, 61, 288, 262, 44,
+ 390, 91, 38, 42, 359, 360, 361, 60, 390, 390,
+ 390, 390, -70, 306, -70, -75, -7, 33, -9, -1,
+ 280, 279, 289, -28, -1, -76, 42, 471, 47, -28,
+ 270, 272, 281, 282, 283, 284, 40, -36, -1, 329,
+ 330, 322, 345, 334, 335, 337, 338, 339, 340, 341,
+ 342, 343, 344, 362, 355, 336, 352, 326, 371, 294,
+ -2, 40, 61, -72, -71, -74, -28, -7, -7, 40,
+ 301, 303, 304, 305, 41, 41, 125,-143,-114,-111,
+-144,-146,-116,-117,-131,-120,-132, 452, 453,-148,
+ 508,-133,-135, 507, 321, 422, 427, 472, 408, 125,
+ -9, -9, 40, 451, 58, 91, -9, -71, 357, 364,
+ 541, 91,-161,-162,-164,-166,-167,-168, 311,-169,
+ 309, 313, 312, -9, -2, -9, -24, 40, -23, -24,
+ 266, 286, 287, -31, -9, -2, -75, -28, -76, 270,
+ 272, -71, -36, 341,-175, -7, -72, 40,-115,-158,
+ -2, -9, 125,-178, 462,-131,-179,-180, 467, 468,
+-181,-132,-135, 464, 125,-183,-177,-179,-182, 338,
+ 462, 465, 125,-184, 460, 408, 463, 296,-132,-135,
+ 125,-185, 460, 463,-132,-135, -89, 420, 125,-136,
+-142, -71, -1, 471, -7, -1, -13, 40, 40, -28,
+ 328, 329, 330, 331, 377, 371, 326, 479, 365, 366,
+ 367, 368, 375, 376, 294, 93, 125, 44, 40, -2,
+ 41, -23, -9, -23, -24, -9, -9, -9, 93, -9,
+ -9, 474, -1, -1, 330, 329, 327, 336, 390, 40,
+ 61, 43, 123, 40, 40, 263, -1, 93, -30, -29,
+ 275, -9, 40, 40, -54, -55, -28, -1, -1, -1,
+ -1, -70, -28, -9, -1, 280, 93, 93, 93, -1,
+ -1, -71, -1, 91, -9, -69, 60, 329, 330, 331,
+ 365, 366, 367, 40, 61, -36, 123, 40, 41, -71,
+ -3, 373, 374, -1, -9,-115, 123, 123, 123, -9,
+ -9, 123, -71, 357, 364, 541, 364, -81, -82, -91,
+ -25, -26, -27, 275, -13, 40, -9, 58, 274, -7,
+ 91, -1, 91, -1, -9,-161,-165,-158, 310,-165,
+-165,-165, -71,-158, -2, -9, 40, 40, 41, -71,
+ -1, 40, -31, -28, -6, -2, -9, 125, 316, 316,
+ 466, -31, -66, -9, 42, -36, 61, -31, 61, -31,
+ -31, 61, 61, -1, 469, -9, 469, 40, -1, 469,
+-177, 44, 93, -1, -28, -28, 91, -9, -36, -83,
+ -1, 40, 40,-173, -36, 41, 41, 93, 41, 41,
+ 41, 41, 41, -12, 263, 44, 58, 390, 329, 330,
+ 331, 365, 366, 367, -1, -84, -85, -36, 123, 262,
+ -64, -63, -71, 306, 44, 93, 44, 275, -71, -71,
+ 62, 44, 42, -5, -5, -5, 93, 274, 41, -68,
+ -19, -18, 43, 45, 306, 323, 373, -9, -59, -61,
+ -73, 274, -53, -22, 60, 41, 125,-112,-145,-147,
+-127, 274, -7, 91, -1, 91, -1, -71, -71, -1,
+ 371, 326, -7, 371, 326, -1, 41, 44, -28, -25,
+ 93, -9, -3, -1, -28, -9, -9, 44, 93, -2,
+ -9, -9, -24, 274, -36, 41, 40, 41, 44, 44,
+ -2, -9, -9, 41, 58, 40, 41, 40, 41, 41,
+ 40, 40, -5, -1, -9, 317, -1, -31, -71, 93,
+ -38, 479, 504, 505, 506, -9, 41, 390, -83, 41,
+ 387, 341, 342, 343, 388, 389, 301, 303, 304, 305,
+ 391, 394, 294, -4, 317, -34, -33,-153, 480, 482,
+ 483, 484, 485, 276, 277, 281, 282, 283, 284, 286,
+ 287, 257, 279, 290, 291, 292, 293, 486, 487, 488,
+ 490, 491, 492, 493, 494, 495, 496, 334, 497, 280,
+ 289, 336, 498, 341, 489, 357, 390, 502, 271, 123,
+ -9, 41, -14, -14, -14, -14, -14, -14, 317, 283,
+ 284, 456, 457, 459, -9, -9, -1, 41, 44, 61,
+ -59, 125, 44, 61, 263, 263, -29, -9, 41, 41,
+ -28, 40, -5, -1, 62, -58, -1, 40, -19, 41,
+ 125, -62, -40,-135, -41, 298, 364, 297, 286, 287,
+ 284, 283, 282, 281, 293, 292, 291, 290, 279, 278,
+ 277,-175, 61, -3, 40, 40, 91, -54, 125, 125,
+-150, 423, 424, 425, 426,-120,-132,-133,-135, 125,
+-151, 428, 429, 426,-132,-120,-133,-135, 125, -3,
+ -28, -9, -9, 44, -93, 450, -1, -28, -27, -38,
+ 41, 390, -71, 93, 93, -71, -35, 61, 316, 316,
+ 41, 41, -1, 41, -25, -6, -6, -66, 41, -9,
+ 41, -3, 40, 93, 93, 93, 93, -36, 41, 58,
+ 58, 40, -35, -2, 41, 42, 91, -32, 40, 481,
+ 501, 277, 281, 282, 283, 284, 280, -20, 40, -20,
+ -20, -15, 510, 483, 484, 276, 277, 281, 282, 283,
+ 284, 286, 287, 279, 290, 291, 292, 293, 42, 486,
+ 487, 488, 490, 491, 494, 495, 497, 280, 289, 257,
+ 511, 512, 513, 514, 515, 516, 517, 518, 519, 520,
+ 521, 522, 523, 496, 488, 500, 41, -2, 263, 263,
+ 44, -84, -37, -17, -9, 283, -36, -70, 319, 320,
+ 125, -64, 123, 61, -25, -1, -67, 44, -56, -57,
+ -71, -65,-135, 358, 363, 40, 91, 40, 91, 40,
+ 91, 40, 91, 40, 91, 40, 91, 40, 91, 40,
+ 91, 40, 91, 40, 91, 40, 91, 40, 91, 40,
+ 91, 284, 283, 282, 281, 40, 91, 40, 91, -31,
+ -36, 123, 40, -53, -22, -25, -25, -9, 62, -75,
+ -75, -75, -75, -75, -75, -75, 509, -71, 93, 93,
+ -71, -1, -2, -2, 274, 44, -39, -41, -36, 299,
+ 286, 287, 284, 283, 282, 281, 279, 293, 292, 291,
+ 290, 278, 277, -2, -9, 41, 58, -89, -69, -34,
+ -83, 392, 393, 392, 393, -9, 93, -9, 43, 125,
+ -36, 91, 91, 503, 44, 91, 524, 38, 281, 282,
+ 283, 284, 280, -9, 40, 40, -62, 123, 41, -67,
+ -68, 41, 44, -60, -52, 364, 297, 345, 299, 263,
+ -9, 306, -70, 299, -9, -40, -9, -23, -9, -9,
+ -23, -24, -9, -24, -9, -9, -9, -9, -9, -9,
+ -9, -24, -9, -9, -9, -9, -9, -9, -9, 40,
+ 91, 40, 91, 40, 91, 40, 91, -9, -9, -17,
+ -9, 41, -59, 40, 40, 41, 41, 93, -7, 274,
+ 44, 40, -3, -71, 284, 283, 282, 281, -66, 40,
+ 41, 41, 41, 93, 43, -9, 44, -9, -9, 61,
+ -36, 93, 263, -9, 281, 282, 283, -9, 125, -62,
+ -71, -1, 91, 306, -70, 41, 41, 93, 263, 41,
+ 41, 93, 41, 93, 41, 41, 93, 41, 41, 93,
+ 41, 93, 41, 93, 41, 93, 41, 93, 41, 93,
+ 41, 93, 41, 93, 41, 93, -24, -9, -9, -9,
+ -9, -9, -9, -9, 41, 93, 41, 93, 125, -25,
+ -25, 62, -28, -3, -71, -25, -21, -22, 60, 58,
+ -25, -9, 93, -36, 93, 93, -9, 41, 58, 58,
+ 58, 41, 125, 61, 93, 263, 40, 41, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 41, 93, 41, 93, 41, 93, 41, 93, 40, 40,
+ 41, 41, -71, -21, 41, 40, -66, 41, 93, 44,
+ 41, -33, 41, -9, -9, -9, -40, -49, -50, -51,
+ -42, -43, -47, -46, -45, -44, -47, -46, -45, -44,
+ 40, 40, 40, 40, -45, -48, 274, 40, -35, -25,
+ -80, -36, 41, 41, 41, 41, 299, 263, 41, 299,
+ 306, -70, 41, -40, 41, -23, -9, 41, -23, -24,
+ 41, -24, 41, -9, 41, -9, 41, -9, 41, 41,
+ 41, 41, -47, -46, -45, -44, 41, 41, -17, -3,
+ -25, 41, 123, 324, 379, 380, 381, 308, 382, 383,
+ 384, 385, 333, 347, 348, 349, 350, 294, 44, 263,
+ 41, 41, 41, 41, 40, 41, 40, -36, -25, 509,
+ -9, 41, 41, 357, 41, -7, -28, -71, 274, -3,
+ -21, 40, -25, 41 };
+YYSTATIC YYCONST short YYFARDATA YYDEF[]={
+
+ 1, -2, 2, 0, 0, 333, 6, 7, 8, 9,
+ 10, 11, 0, 0, 0, 0, 16, 17, 18, 0,
+ 0, 772, 0, 0, 24, 25, 26, 0, 28, 135,
+ 0, 269, 206, 0, 431, 0, 0, 778, 105, 835,
+ 92, 0, 431, 0, 83, 84, 85, 0, 0, 0,
+ 0, 0, 0, 57, 58, 0, 60, 108, 262, 387,
+ 0, 757, 758, 219, 431, 431, 139, 1, 0, 788,
+ 806, 824, 838, 19, 41, 20, 0, 0, 22, 42,
+ 43, 23, 29, 137, 0, 104, 38, 39, 36, 37,
+ 219, 186, 0, 384, 0, 391, 0, 0, 431, 394,
+ 394, 394, 394, 394, 394, 0, 0, 432, 433, 0,
+ 760, 0, 778, 814, 0, 93, 0, 0, 742, 743,
+ 744, 745, 746, 747, 748, 749, 750, 751, 752, 753,
+ 754, 755, 756, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 668, 0, 0, 219, 0, 684, 685, 0,
+ 689, 0, 0, 549, 233, 551, 552, 553, 554, 0,
+ 489, 691, 692, 693, 694, 695, 696, 697, 698, 699,
+ 0, 704, 705, 706, 707, 708, 555, 0, 52, 54,
+ 55, 56, 59, 0, 386, 388, 389, 0, 61, 0,
+ 71, 0, 212, 213, 214, 219, 219, 217, 0, 220,
+ 221, 226, 0, 0, 0, 0, 5, 334, 0, 336,
+ 0, 0, 340, 341, 342, 343, 0, 345, 346, 347,
+ 348, 349, 0, 0, 0, 355, 0, 0, 332, 504,
+ 0, 0, 0, 0, 431, 0, 219, 0, 0, 0,
+ 219, 0, 0, 333, 0, 490, 491, 492, 493, 494,
+ 495, 496, 497, 498, 499, 500, 501, 502, 362, 369,
+ 0, 0, 0, 0, 21, 774, 773, 0, 29, 550,
+ 107, 0, 136, 557, 0, 560, 219, 0, 311, 270,
+ 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
+ 281, 282, 283, 284, 285, 286, 287, 0, 0, 0,
+ 0, 0, 393, 0, 0, 0, 0, 405, 0, 0,
+ 406, 0, 407, 0, 408, 0, 409, 0, 410, 430,
+ 102, 434, 0, 759, 0, 0, 769, 777, 779, 780,
+ 781, 0, 783, 784, 785, 786, 787, 0, 0, 833,
+ 836, 837, 94, 718, 719, 720, 0, 0, 31, 0,
+ 0, 711, 673, 674, 675, 0, 0, 534, 0, 0,
+ 0, 0, 667, 0, 670, 228, 0, 0, 681, 683,
+ 686, 0, 688, 690, 0, 0, 0, 0, 0, 0,
+ 231, 232, 700, 701, 702, 703, 0, 53, 147, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 0, 131, 132, 133, 0,
+ 0, 103, 0, 0, 72, 73, 0, 215, 216, 0,
+ 222, 223, 224, 225, 64, 68, 3, 140, 333, 0,
+ 0, 0, 168, 169, 170, 171, 172, 0, 0, 0,
+ 0, 178, 179, 0, 0, 236, 250, 814, 105, 4,
+ 335, 337, -2, 0, 344, 0, 0, 0, 219, 0,
+ 0, 0, 363, 365, 0, 0, 0, 0, 0, 0,
+ 379, 380, 377, 505, 506, 507, 508, 503, 509, 510,
+ 44, 0, 0, 0, 512, 513, 514, 0, 517, 518,
+ 519, 520, 521, 0, 431, 0, 525, 527, 0, 366,
+ 0, 0, 12, 789, 0, 791, 792, 431, 0, 0,
+ 431, 799, 800, 0, 13, 807, 431, 809, 431, 811,
+ 0, 0, 14, 825, 0, 0, 0, 0, 831, 832,
+ 15, 839, 0, 0, 842, 843, 771, 775, 27, 30,
+ 138, 142, 0, 0, 0, 40, 0, 0, 292, 0,
+ 187, 188, 189, 190, 191, 192, 193, 0, 195, 196,
+ 197, 198, 199, 200, 0, 207, 390, 0, 0, 0,
+ 398, 0, 0, 0, 0, 0, 0, 0, 96, 762,
+ 0, 782, 804, 812, 815, 816, 817, 0, 0, 0,
+ 0, 0, 722, 727, 728, 34, 47, 671, 0, 709,
+ 712, 713, 0, 0, 0, 535, 536, 48, 49, 50,
+ 51, 669, 0, 680, 682, 687, 0, 0, 0, 0,
+ 556, 0, -2, 711, 0, 106, 154, 125, 126, 127,
+ 128, 129, 130, 0, 385, 62, 75, 69, 219, 0,
+ 532, 308, 309, -2, 0, 0, 139, 239, 253, 173,
+ 174, 824, 0, 219, 0, 0, 0, 0, 219, 0,
+ 0, 539, 540, 542, 0, -2, 0, 0, 0, 0,
+ 0, 357, 0, 0, 0, 364, 370, 381, 0, 371,
+ 372, 373, 378, 374, 375, 376, 0, 0, 511, 0,
+ -2, 0, 0, 0, 0, 530, 531, 361, 0, 0,
+ 0, 0, 0, 793, 794, 797, 0, 0, 0, 0,
+ 0, 0, 0, 826, 0, 830, 0, 0, 0, 0,
+ 431, 0, 558, 0, 0, 263, 0, 0, 292, 0,
+ 202, 561, 0, 392, 0, 397, 394, 395, 394, 394,
+ 394, 394, 394, 0, 761, 0, 0, 0, 818, 819,
+ 820, 821, 822, 823, 834, 0, 729, 0, 75, 32,
+ 0, 723, 0, 0, 0, 672, 711, 715, 0, 0,
+ 679, 0, 674, 545, 546, 547, 0, 0, 227, 0,
+ 0, 154, 149, 150, 151, 152, 153, 0, 0, 78,
+ 65, 0, 0, 0, 534, 218, 164, 0, 0, 0,
+ 0, 0, 0, 0, 181, 0, 0, 0, 0, -2,
+ 237, 238, 0, 251, 252, 813, 338, 311, 263, 0,
+ 350, 352, 353, 310, 0, 0, 0, 0, 204, 0,
+ 0, 0, 0, 0, 0, 523, -2, 526, 527, 527,
+ 367, 368, 790, 795, 0, 803, 798, 801, 808, 810,
+ 776, 802, 827, 828, 0, 0, 841, 0, 141, 559,
+ 0, 0, 0, 0, 0, 0, 288, 0, 0, 291,
+ 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+ 0, 0, 0, 204, 0, 0, 265, 0, 0, 0,
+ 566, 567, 568, 569, 570, 571, 572, 573, 574, 575,
+ 576, 577, 0, 582, 583, 584, 585, 591, 592, 593,
+ 594, 595, 596, 597, 616, 616, 600, 616, 618, 604,
+ 606, 0, 608, 0, 610, 612, 0, 614, 615, 267,
+ 0, 396, 399, 400, 401, 402, 403, 404, 0, 97,
+ 98, 99, 100, 101, 764, 766, 805, 716, 0, 0,
+ 0, 721, 722, 0, 37, 35, 710, 714, 676, 677,
+ 537, -2, 548, 229, 148, 0, 158, 143, 155, 134,
+ 63, 74, 76, 77, 438, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 431, 0, 532, -2, -2, 0, 0, 165, 166,
+ 240, 219, 219, 219, 219, 245, 246, 247, 248, 167,
+ 254, 219, 219, 219, 258, 259, 260, 261, 175, 0,
+ 0, 0, 0, 0, 184, 219, 234, 0, 541, 543,
+ 339, 0, 0, 356, 0, 359, 360, 0, 0, 0,
+ 45, 46, 515, 522, 0, 528, 529, 0, 829, 840,
+ 774, 147, 561, 312, 313, 314, 315, 292, 290, 0,
+ 0, 0, 185, 203, 194, 586, 0, 0, 0, 0,
+ 0, 611, 578, 579, 580, 581, 605, 598, 0, 599,
+ 601, 602, 619, 620, 621, 622, 623, 624, 625, 626,
+ 627, 628, 629, 0, 634, 635, 636, 637, 638, 642,
+ 643, 644, 645, 646, 647, 648, 649, 650, 652, 653,
+ 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
+ 664, 665, 666, 607, 609, 613, 201, 95, 763, 765,
+ 0, 730, 731, 734, 735, 0, 737, 0, 732, 733,
+ 717, 724, 78, 0, 0, 158, 157, 154, 0, 144,
+ 145, 0, 80, 81, 82, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 66, 75, 70, 0, 0, 0, 0, 0, 533, 241,
+ 242, 243, 244, 255, 256, 257, 219, 0, 180, 0,
+ 183, 0, 544, 351, 0, 0, 205, 435, 436, 437,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 382, 383, 524, 0, 770, 0, 0,
+ 0, 303, 304, 305, 306, 0, 587, 0, 0, 266,
+ 0, 0, 0, 0, 0, 0, 640, 641, 630, 631,
+ 632, 633, 651, 768, 0, 0, 0, 78, 678, 156,
+ 159, 160, 0, 0, 86, 87, 88, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 429, 0, -2, -2, 210, 211, 0, 0, 0,
+ 0, -2, 161, 358, 0, 0, 0, 0, 0, -2,
+ 264, 289, 307, 588, 0, 0, 0, 0, 0, 0,
+ 603, 639, 767, 0, 0, 0, 0, 0, 725, 0,
+ 146, 0, 0, 0, 90, 439, 440, 0, 0, 442,
+ 443, 0, 444, 0, 411, 413, 0, 412, 414, 0,
+ 415, 0, 416, 0, 417, 0, 418, 0, 423, 0,
+ 424, 0, 425, 0, 426, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 427, 0, 428, 0, 67, 0,
+ 0, 163, 0, 161, 182, 0, 0, 162, 0, 0,
+ 0, 0, 590, 0, 564, 561, 0, 736, 0, 0,
+ 0, 741, 726, 0, 91, 89, 480, 441, 483, 487,
+ 464, 467, 470, 472, 474, 476, 470, 472, 474, 476,
+ 419, 0, 420, 0, 421, 0, 422, 0, 474, 478,
+ 208, 209, 0, 0, 204, -2, 796, 316, 589, 0,
+ 563, 565, 617, 0, 0, 0, 79, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 470, 472, 474, 476, 0, 0, 0, -2, 249, 0,
+ 0, 0, 738, 739, 740, 461, 481, 482, 462, 484,
+ 0, 486, 463, 488, 445, 465, 466, 446, 468, 469,
+ 447, 471, 448, 473, 449, 475, 450, 477, 451, 452,
+ 453, 454, 0, 0, 0, 0, 459, 460, 479, 0,
+ 0, 354, 268, 317, 318, 319, 320, 321, 322, 323,
+ 324, 325, 326, 327, 328, 329, 330, 0, 0, 485,
+ 455, 456, 457, 458, -2, 0, 0, 0, 0, 0,
+ 0, 562, 176, 219, 331, 0, 0, 0, 0, 161,
+ 0, -2, 0, 177 };
+#ifdef YYRECOVER
+YYSTATIC YYCONST short yyrecover[] = {
+-1000
+};
+#endif
+
+/* SCCSWHAT( "@(#)yypars.c 3.1 88/11/16 22:00:49 " ) */
+#line 3 "F:\\NetFXDev1\\src\\tools\\devdiv\\amd64\\yypars.c"
+#if ! defined(YYAPI_PACKAGE)
+/*
+** YYAPI_TOKENNAME : name used for return value of yylex
+** YYAPI_TOKENTYPE : type of the token
+** YYAPI_TOKENEME(t) : the value of the token that the parser should see
+** YYAPI_TOKENNONE : the representation when there is no token
+** YYAPI_VALUENAME : the name of the value of the token
+** YYAPI_VALUETYPE : the type of the value of the token (if null, then the value is derivable from the token itself)
+** YYAPI_VALUEOF(v) : how to get the value of the token.
+*/
+#define YYAPI_TOKENNAME yychar
+#define YYAPI_TOKENTYPE int
+#define YYAPI_TOKENEME(t) (t)
+#define YYAPI_TOKENNONE -1
+#define YYAPI_TOKENSTR(t) (sprintf_s(yytokbuf, _countof(yytokbuf), "%d", t), yytokbuf)
+#define YYAPI_VALUENAME yylval
+#define YYAPI_VALUETYPE YYSTYPE
+#define YYAPI_VALUEOF(v) (v)
+#endif
+#if ! defined(YYAPI_CALLAFTERYYLEX)
+#define YYAPI_CALLAFTERYYLEX
+#endif
+
+# define YYFLAG -1000
+# define YYERROR goto yyerrlab
+# define YYACCEPT return(0)
+# define YYABORT return(1)
+
+#ifdef YYDEBUG /* RRR - 10/9/85 */
+char yytokbuf[20];
+# ifndef YYDBFLG
+# define YYDBFLG (yydebug)
+# endif
+# define yyprintf(a, b, c, d) if (YYDBFLG) YYPRINT(a, b, c, d)
+#else
+# define yyprintf(a, b, c, d)
+#endif
+
+#ifndef YYPRINT
+#define YYPRINT printf
+#endif
+
+/* parser for yacc output */
+
+#ifdef YYDUMP
+int yydump = 1; /* 1 for dumping */
+void yydumpinfo(void);
+#endif
+#ifdef YYDEBUG
+YYSTATIC int yydebug = 0; /* 1 for debugging */
+#endif
+YYSTATIC YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
+YYSTATIC short yys[YYMAXDEPTH]; /* the parse stack */
+
+#if ! defined(YYRECURSIVE)
+YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+#if defined(YYAPI_VALUETYPE)
+// YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME; FIX
+#endif
+YYSTATIC int yynerrs = 0; /* number of errors */
+YYSTATIC short yyerrflag = 0; /* error recovery flag */
+#endif
+
+#ifdef YYRECOVER
+/*
+** yyscpy : copy f onto t and return a ptr to the null terminator at the
+** end of t.
+*/
+YYSTATIC char *yyscpy(register char*t, register char*f)
+ {
+ while(*t = *f++)
+ t++;
+ return(t); /* ptr to the null char */
+ }
+#endif
+
+#ifndef YYNEAR
+#define YYNEAR
+#endif
+#ifndef YYPASCAL
+#define YYPASCAL
+#endif
+#ifndef YYLOCAL
+#define YYLOCAL
+#endif
+#if ! defined YYPARSER
+#define YYPARSER yyparse
+#endif
+#if ! defined YYLEX
+#define YYLEX yylex
+#endif
+
+#if defined(YYRECURSIVE)
+
+ YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ #if defined(YYAPI_VALUETYPE)
+ YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME;
+ #endif
+ YYSTATIC int yynerrs = 0; /* number of errors */
+ YYSTATIC short yyerrflag = 0; /* error recovery flag */
+
+ YYSTATIC short yyn;
+ YYSTATIC short yystate = 0;
+ YYSTATIC short *yyps= &yys[-1];
+ YYSTATIC YYSTYPE *yypv= &yyv[-1];
+ YYSTATIC short yyj;
+ YYSTATIC short yym;
+
+#endif
+
+#pragma warning(disable:102)
+YYLOCAL YYNEAR YYPASCAL YYPARSER()
+{
+#if ! defined(YYRECURSIVE)
+
+ register short yyn;
+ short yystate, *yyps;
+ YYSTYPE *yypv;
+ short yyj, yym;
+
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ yystate = 0;
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:6200) // Index '-1' is out of valid index range...for non-stack buffer...
+#endif
+ yyps= &yys[-1];
+ yypv= &yyv[-1];
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+
+#endif
+
+#ifdef YYDUMP
+ yydumpinfo();
+#endif
+ yystack: /* put a state and value onto the stack */
+
+#ifdef YYDEBUG
+ if(YYAPI_TOKENNAME == YYAPI_TOKENNONE) {
+ yyprintf( "state %d, token # '%d'\n", yystate, -1, 0 );
+ }
+ else {
+ yyprintf( "state %d, token # '%s'\n", yystate, YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0 );
+ }
+#endif
+ if( ++yyps > &yys[YYMAXDEPTH] ) {
+ yyerror( "yacc stack overflow" );
+ return(1);
+ }
+ *yyps = yystate;
+ ++yypv;
+
+ *yypv = yyval;
+
+yynewstate:
+
+ yyn = YYPACT[yystate];
+
+ if( yyn <= YYFLAG ) { /* simple state, no lookahead */
+ goto yydefault;
+ }
+ if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) { /* need a lookahead */
+ YYAPI_TOKENNAME = YYLEX();
+ YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
+ }
+ if( ((yyn += YYAPI_TOKENEME(YYAPI_TOKENNAME)) < 0) || (yyn >= YYLAST) ) {
+ goto yydefault;
+ }
+ if( YYCHK[ yyn = YYACT[ yyn ] ] == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) { /* valid shift */
+ yyval = YYAPI_VALUEOF(YYAPI_VALUENAME);
+ yystate = yyn;
+ yyprintf( "SHIFT: saw token '%s', now in state %4d\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), yystate, 0 );
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ if( yyerrflag > 0 ) {
+ --yyerrflag;
+ }
+ goto yystack;
+ }
+
+ yydefault:
+ /* default state action */
+
+ if( (yyn = YYDEF[yystate]) == -2 ) {
+ register YYCONST short *yyxi;
+
+ if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) {
+ YYAPI_TOKENNAME = YYLEX();
+ YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
+ yyprintf("LOOKAHEAD: token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0);
+ }
+/*
+** search exception table, we find a -1 followed by the current state.
+** if we find one, we'll look through terminal,state pairs. if we find
+** a terminal which matches the current one, we have a match.
+** the exception table is when we have a reduce on a terminal.
+*/
+
+#if YYOPTTIME
+ yyxi = yyexca + yyexcaind[yystate];
+ while(( *yyxi != YYAPI_TOKENEME(YYAPI_TOKENNAME) ) && ( *yyxi >= 0 )){
+ yyxi += 2;
+ }
+#else
+ for(yyxi = yyexca;
+ (*yyxi != (-1)) || (yyxi[1] != yystate);
+ yyxi += 2
+ ) {
+ ; /* VOID */
+ }
+
+ while( *(yyxi += 2) >= 0 ){
+ if( *yyxi == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) {
+ break;
+ }
+ }
+#endif
+ if( (yyn = yyxi[1]) < 0 ) {
+ return(0); /* accept */
+ }
+ }
+
+ if( yyn == 0 ){ /* error */
+ /* error ... attempt to resume parsing */
+
+ switch( yyerrflag ){
+
+ case 0: /* brand new error */
+#ifdef YYRECOVER
+ {
+ register int i,j;
+
+ for(i = 0;
+ (yyrecover[i] != -1000) && (yystate > yyrecover[i]);
+ i += 3
+ ) {
+ ;
+ }
+ if(yystate == yyrecover[i]) {
+ yyprintf("recovered, from state %d to state %d on token # %d\n",
+ yystate,yyrecover[i+2],yyrecover[i+1]
+ );
+ j = yyrecover[i + 1];
+ if(j < 0) {
+ /*
+ ** here we have one of the injection set, so we're not quite
+ ** sure that the next valid thing will be a shift. so we'll
+ ** count it as an error and continue.
+ ** actually we're not absolutely sure that the next token
+ ** we were supposed to get is the one when j > 0. for example,
+ ** for(+) {;} error recovery with yyerrflag always set, stops
+ ** after inserting one ; before the +. at the point of the +,
+ ** we're pretty sure the caller wants a 'for' loop. without
+ ** setting the flag, when we're almost absolutely sure, we'll
+ ** give them one, since the only thing we can shift on this
+ ** error is after finding an expression followed by a +
+ */
+ yyerrflag++;
+ j = -j;
+ }
+ if(yyerrflag <= 1) { /* only on first insertion */
+ yyrecerr(YYAPI_TOKENNAME, j); /* what was, what should be first */
+ }
+ yyval = yyeval(j);
+ yystate = yyrecover[i + 2];
+ goto yystack;
+ }
+ }
+#endif
+ yyerror("syntax error");
+
+ yyerrlab:
+ ++yynerrs;
+ FALLTHROUGH;
+
+ case 1:
+ case 2: /* incompletely recovered error ... try again */
+
+ yyerrflag = 3;
+
+ /* find a state where "error" is a legal shift action */
+
+ while ( yyps >= yys ) {
+ yyn = YYPACT[*yyps] + YYERRCODE;
+ if( yyn>= 0 && yyn < YYLAST && YYCHK[YYACT[yyn]] == YYERRCODE ){
+ yystate = YYACT[yyn]; /* simulate a shift of "error" */
+ yyprintf( "SHIFT 'error': now in state %4d\n", yystate, 0, 0 );
+ goto yystack;
+ }
+ yyn = YYPACT[*yyps];
+
+ /* the current yyps has no shift onn "error", pop stack */
+
+ yyprintf( "error recovery pops state %4d, uncovers %4d\n", *yyps, yyps[-1], 0 );
+ --yyps;
+ --yypv;
+ }
+
+ /* there is no state on the stack with an error shift ... abort */
+
+ yyabort:
+ return(1);
+
+
+ case 3: /* no shift yet; clobber input char */
+
+ yyprintf( "error recovery discards token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0 );
+
+ if( YYAPI_TOKENEME(YYAPI_TOKENNAME) == 0 ) goto yyabort; /* don't discard EOF, quit */
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ goto yynewstate; /* try again in the same state */
+ }
+ }
+
+ /* reduction by production yyn */
+yyreduce:
+ {
+ register YYSTYPE *yypvt;
+ yypvt = yypv;
+ yyps -= YYR2[yyn];
+ yypv -= YYR2[yyn];
+ yyval = yypv[1];
+ yyprintf("REDUCE: rule %4d, popped %2d tokens, uncovered state %4d, ",yyn, YYR2[yyn], *yyps);
+ yym = yyn;
+ yyn = YYR1[yyn]; /* consult goto table to find next state */
+ yyj = YYPGO[yyn] + *yyps + 1;
+ if( (yyj >= YYLAST) || (YYCHK[ yystate = YYACT[yyj] ] != -yyn) ) {
+ yystate = YYACT[YYPGO[yyn]];
+ }
+ yyprintf("goto state %4d\n", yystate, 0, 0);
+#ifdef YYDUMP
+ yydumpinfo();
+#endif
+ switch(yym){
+
+case 3:
+#line 194 "asmparse.y"
+{ PASM->EndClass(); } break;
+case 4:
+#line 195 "asmparse.y"
+{ PASM->EndNameSpace(); } break;
+case 5:
+#line 196 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); } break;
+case 12:
+#line 206 "asmparse.y"
+{ PASMM->EndAssembly(); } break;
+case 13:
+#line 207 "asmparse.y"
+{ PASMM->EndAssembly(); } break;
+case 14:
+#line 208 "asmparse.y"
+{ PASMM->EndComType(); } break;
+case 15:
+#line 209 "asmparse.y"
+{ PASMM->EndManifestRes(); } break;
+case 19:
+#line 213 "asmparse.y"
+{
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22011) // Suppress PREFast warning about integer overflow/underflow
+#endif
+ PASM->m_dwSubsystem = yypvt[-0].int32;
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+ } break;
+case 20:
+#line 223 "asmparse.y"
+{ PASM->m_dwComImageFlags = yypvt[-0].int32; } break;
+case 21:
+#line 224 "asmparse.y"
+{ PASM->m_dwFileAlignment = yypvt[-0].int32;
+ if((yypvt[-0].int32 & (yypvt[-0].int32 - 1))||(yypvt[-0].int32 < 0x200)||(yypvt[-0].int32 > 0x10000))
+ PASM->report->error("Invalid file alignment, must be power of 2 from 0x200 to 0x10000\n");} break;
+case 22:
+#line 227 "asmparse.y"
+{ PASM->m_stBaseAddress = (ULONGLONG)(*(yypvt[-0].int64)); delete yypvt[-0].int64;
+ if(PASM->m_stBaseAddress & 0xFFFF)
+ PASM->report->error("Invalid image base, must be 0x10000-aligned\n");} break;
+case 23:
+#line 230 "asmparse.y"
+{ PASM->m_stSizeOfStackReserve = (size_t)(*(yypvt[-0].int64)); delete yypvt[-0].int64; } break;
+case 28:
+#line 235 "asmparse.y"
+{ PASM->m_fIsMscorlib = TRUE; } break;
+case 31:
+#line 242 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 32:
+#line 243 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 33:
+#line 246 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLang)); } break;
+case 34:
+#line 247 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLang));
+ LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLangVendor));} break;
+case 35:
+#line 249 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-4].string,&(PASM->m_guidLang));
+ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLangVendor));
+ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidDoc));} break;
+case 36:
+#line 254 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 37:
+#line 255 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 38:
+#line 258 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 39:
+#line 259 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 40:
+#line 260 "asmparse.y"
+{ yyval.string = newStringWDel(yypvt[-2].string, '.', yypvt[-0].string); } break;
+case 41:
+#line 263 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 42:
+#line 266 "asmparse.y"
+{ yyval.int64 = yypvt[-0].int64; } break;
+case 43:
+#line 267 "asmparse.y"
+{ yyval.int64 = neg ? new __int64(yypvt[-0].int32) : new __int64((unsigned)yypvt[-0].int32); } break;
+case 44:
+#line 270 "asmparse.y"
+{ yyval.float64 = yypvt[-0].float64; } break;
+case 45:
+#line 271 "asmparse.y"
+{ float f; *((__int32*) (&f)) = yypvt[-1].int32; yyval.float64 = new double(f); } break;
+case 46:
+#line 272 "asmparse.y"
+{ yyval.float64 = (double*) yypvt[-1].int64; } break;
+case 47:
+#line 276 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].binstr,yypvt[-0].string); } break;
+case 48:
+#line 277 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
+case 49:
+#line 278 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
+case 50:
+#line 279 "asmparse.y"
+{ yypvt[-2].cad->tkOwner = 0; PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
+case 51:
+#line 280 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
+case 52:
+#line 285 "asmparse.y"
+{ DefineVar(yypvt[-0].string, NULL); } break;
+case 53:
+#line 286 "asmparse.y"
+{ DefineVar(yypvt[-1].string, yypvt[-0].binstr); } break;
+case 54:
+#line 287 "asmparse.y"
+{ UndefVar(yypvt[-0].string); } break;
+case 55:
+#line 288 "asmparse.y"
+{ SkipToken = !IsVarDefined(yypvt[-0].string);
+ IfEndif++;
+ } break;
+case 56:
+#line 291 "asmparse.y"
+{ SkipToken = IsVarDefined(yypvt[-0].string);
+ IfEndif++;
+ } break;
+case 57:
+#line 294 "asmparse.y"
+{ if(IfEndif == 1) SkipToken = !SkipToken;} break;
+case 58:
+#line 295 "asmparse.y"
+{ if(IfEndif == 0)
+ PASM->report->error("Unmatched #endif\n");
+ else IfEndif--;
+ } break;
+case 59:
+#line 299 "asmparse.y"
+{ _ASSERTE(!"yylex should have dealt with this"); } break;
+case 60:
+#line 300 "asmparse.y"
+{ } break;
+case 61:
+#line 304 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-0].token, NULL); } break;
+case 62:
+#line 305 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].token, yypvt[-0].binstr); } break;
+case 63:
+#line 306 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 64:
+#line 307 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
+case 65:
+#line 310 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-2].token, yypvt[-0].token, NULL); } break;
+case 66:
+#line 311 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-4].token, yypvt[-2].token, yypvt[-0].binstr); } break;
+case 67:
+#line 313 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-6].token, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 68:
+#line 314 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
+case 69:
+#line 317 "asmparse.y"
+{ yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
+case 70:
+#line 321 "asmparse.y"
+{ PASM->m_pCustomDescrList = NULL;
+ PASM->m_tkCurrentCVOwner = yypvt[-4].token;
+ yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
+case 71:
+#line 326 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 72:
+#line 329 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 73:
+#line 330 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 74:
+#line 334 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt16(nCustomBlobNVPairs);
+ yyval.binstr->append(yypvt[-0].binstr);
+ nCustomBlobNVPairs = 0; } break;
+case 75:
+#line 340 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt16(VAL16(0x0001)); } break;
+case 76:
+#line 341 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); } break;
+case 77:
+#line 343 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 78:
+#line 346 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 79:
+#line 348 "asmparse.y"
+{ yyval.binstr = yypvt[-5].binstr; yyval.binstr->appendInt8(yypvt[-4].int32);
+ yyval.binstr->append(yypvt[-3].binstr);
+ AppendStringWithLength(yyval.binstr,yypvt[-2].string);
+ yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1);
+ nCustomBlobNVPairs++; } break;
+case 80:
+#line 353 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 81:
+#line 356 "asmparse.y"
+{ yyval.int32 = SERIALIZATION_TYPE_FIELD; } break;
+case 82:
+#line 357 "asmparse.y"
+{ yyval.int32 = SERIALIZATION_TYPE_PROPERTY; } break;
+case 83:
+#line 360 "asmparse.y"
+{ if(yypvt[-0].cad->tkOwner && !yypvt[-0].cad->tkInterfacePair)
+ PASM->DefineCV(yypvt[-0].cad);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad); } break;
+case 84:
+#line 364 "asmparse.y"
+{ PASM->DefineCV(yypvt[-0].cad); } break;
+case 85:
+#line 365 "asmparse.y"
+{ CustomDescr* pNew = new CustomDescr(yypvt[-0].tdd->m_pCA);
+ if(pNew->tkOwner == 0) pNew->tkOwner = PASM->m_tkCurrentCVOwner;
+ if(pNew->tkOwner)
+ PASM->DefineCV(pNew);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(pNew); } break;
+case 86:
+#line 373 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 87:
+#line 374 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); } break;
+case 88:
+#line 375 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TAGGED_OBJECT); } break;
+case 89:
+#line 376 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); } break;
+case 90:
+#line 378 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token)); } break;
+case 91:
+#line 380 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 92:
+#line 385 "asmparse.y"
+{ PASMM->SetModuleName(NULL); PASM->m_tkCurrentCVOwner=1; } break;
+case 93:
+#line 386 "asmparse.y"
+{ PASMM->SetModuleName(yypvt[-0].string); PASM->m_tkCurrentCVOwner=1; } break;
+case 94:
+#line 387 "asmparse.y"
+{ BinStr* pbs = new BinStr();
+ unsigned L = (unsigned)strlen(yypvt[-0].string);
+ memcpy((char*)(pbs->getBuff(L)),yypvt[-0].string,L);
+ PASM->EmitImport(pbs); delete pbs;} break;
+case 95:
+#line 394 "asmparse.y"
+{ /*PASM->SetDataSection(); PASM->EmitDataLabel($7);*/
+ PASM->m_VTFList.PUSH(new VTFEntry((USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, yypvt[-0].string)); } break;
+case 96:
+#line 398 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 97:
+#line 399 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_32BIT; } break;
+case 98:
+#line 400 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_64BIT; } break;
+case 99:
+#line 401 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED; } break;
+case 100:
+#line 402 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_CALL_MOST_DERIVED; } break;
+case 101:
+#line 403 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN; } break;
+case 102:
+#line 406 "asmparse.y"
+{ PASM->m_pVTable = yypvt[-1].binstr; } break;
+case 103:
+#line 409 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 104:
+#line 413 "asmparse.y"
+{ PASM->StartNameSpace(yypvt[-0].string); } break;
+case 105:
+#line 416 "asmparse.y"
+{ newclass = TRUE; } break;
+case 106:
+#line 419 "asmparse.y"
+{ if(yypvt[-0].typarlist) FixupConstraints();
+ PASM->StartClass(yypvt[-1].string, yypvt[-2].classAttr, yypvt[-0].typarlist);
+ TyParFixupList.RESET(false);
+ newclass = FALSE;
+ } break;
+case 107:
+#line 425 "asmparse.y"
+{ PASM->AddClass(); } break;
+case 108:
+#line 428 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) 0; } break;
+case 109:
+#line 429 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdPublic); } break;
+case 110:
+#line 430 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdNotPublic); } break;
+case 111:
+#line 431 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x80000000 | tdSealed); } break;
+case 112:
+#line 432 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x40000000); } break;
+case 113:
+#line 433 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdInterface | tdAbstract); } break;
+case 114:
+#line 434 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSealed); } break;
+case 115:
+#line 435 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdAbstract); } break;
+case 116:
+#line 436 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdAutoLayout); } break;
+case 117:
+#line 437 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdSequentialLayout); } break;
+case 118:
+#line 438 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdExplicitLayout); } break;
+case 119:
+#line 439 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAnsiClass); } break;
+case 120:
+#line 440 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdUnicodeClass); } break;
+case 121:
+#line 441 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAutoClass); } break;
+case 122:
+#line 442 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdImport); } break;
+case 123:
+#line 443 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSerializable); } break;
+case 124:
+#line 444 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdWindowsRuntime); } break;
+case 125:
+#line 445 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPublic); } break;
+case 126:
+#line 446 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPrivate); } break;
+case 127:
+#line 447 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamily); } break;
+case 128:
+#line 448 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedAssembly); } break;
+case 129:
+#line 449 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamANDAssem); } break;
+case 130:
+#line 450 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamORAssem); } break;
+case 131:
+#line 451 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdBeforeFieldInit); } break;
+case 132:
+#line 452 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSpecialName); } break;
+case 133:
+#line 453 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr); } break;
+case 134:
+#line 454 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].int32); } break;
+case 136:
+#line 458 "asmparse.y"
+{ PASM->m_crExtends = yypvt[-0].token; } break;
+case 141:
+#line 469 "asmparse.y"
+{ PASM->AddToImplList(yypvt[-0].token); } break;
+case 142:
+#line 470 "asmparse.y"
+{ PASM->AddToImplList(yypvt[-0].token); } break;
+case 143:
+#line 474 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 144:
+#line 475 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 145:
+#line 478 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-0].token); } break;
+case 146:
+#line 479 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->appendInt32(yypvt[-0].token); } break;
+case 147:
+#line 482 "asmparse.y"
+{ yyval.typarlist = NULL; PASM->m_TyParList = NULL;} break;
+case 148:
+#line 483 "asmparse.y"
+{ yyval.typarlist = yypvt[-1].typarlist; PASM->m_TyParList = yypvt[-1].typarlist;} break;
+case 149:
+#line 486 "asmparse.y"
+{ yyval.int32 = gpCovariant; } break;
+case 150:
+#line 487 "asmparse.y"
+{ yyval.int32 = gpContravariant; } break;
+case 151:
+#line 488 "asmparse.y"
+{ yyval.int32 = gpReferenceTypeConstraint; } break;
+case 152:
+#line 489 "asmparse.y"
+{ yyval.int32 = gpNotNullableValueTypeConstraint; } break;
+case 153:
+#line 490 "asmparse.y"
+{ yyval.int32 = gpDefaultConstructorConstraint; } break;
+case 154:
+#line 493 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 155:
+#line 494 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | yypvt[-0].int32; } break;
+case 156:
+#line 497 "asmparse.y"
+{yyval.typarlist = new TyParList(yypvt[-3].int32, yypvt[-2].binstr, yypvt[-1].string, yypvt[-0].typarlist);} break;
+case 157:
+#line 498 "asmparse.y"
+{yyval.typarlist = new TyParList(yypvt[-2].int32, NULL, yypvt[-1].string, yypvt[-0].typarlist);} break;
+case 158:
+#line 501 "asmparse.y"
+{ yyval.typarlist = NULL; } break;
+case 159:
+#line 502 "asmparse.y"
+{ yyval.typarlist = yypvt[-0].typarlist; } break;
+case 160:
+#line 505 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 161:
+#line 508 "asmparse.y"
+{ yyval.int32= 0; } break;
+case 162:
+#line 509 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 163:
+#line 512 "asmparse.y"
+{ yyval.int32 = yypvt[-2].int32; } break;
+case 164:
+#line 516 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); } break;
+case 165:
+#line 520 "asmparse.y"
+{ PASM->EndClass(); } break;
+case 166:
+#line 521 "asmparse.y"
+{ PASM->EndEvent(); } break;
+case 167:
+#line 522 "asmparse.y"
+{ PASM->EndProp(); } break;
+case 173:
+#line 528 "asmparse.y"
+{ PASM->m_pCurClass->m_ulSize = yypvt[-0].int32; } break;
+case 174:
+#line 529 "asmparse.y"
+{ PASM->m_pCurClass->m_ulPack = yypvt[-0].int32; } break;
+case 175:
+#line 530 "asmparse.y"
+{ PASMM->EndComType(); } break;
+case 176:
+#line 532 "asmparse.y"
+{ BinStr *sig1 = parser->MakeSig(yypvt[-7].int32, yypvt[-6].binstr, yypvt[-1].binstr);
+ BinStr *sig2 = new BinStr(); sig2->append(sig1);
+ PASM->AddMethodImpl(yypvt[-11].token,yypvt[-9].string,sig1,yypvt[-5].token,yypvt[-3].string,sig2);
+ PASM->ResetArgNameList();
+ } break;
+case 177:
+#line 538 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-17].token,yypvt[-15].string,
+ (yypvt[-14].int32==0 ? parser->MakeSig(yypvt[-19].int32,yypvt[-18].binstr,yypvt[-12].binstr) :
+ parser->MakeSig(yypvt[-19].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-18].binstr,yypvt[-12].binstr,yypvt[-14].int32)),
+ yypvt[-6].token,yypvt[-4].string,
+ (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
+ parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32)));
+ PASM->ResetArgNameList();
+ } break;
+case 180:
+#line 548 "asmparse.y"
+{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurClass->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[yypvt[-1].int32-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ } break;
+case 181:
+#line 553 "asmparse.y"
+{ int n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
+ } break;
+case 182:
+#line 559 "asmparse.y"
+{ PASM->AddGenericParamConstraint(yypvt[-3].int32, 0, yypvt[-0].token); } break;
+case 183:
+#line 560 "asmparse.y"
+{ PASM->AddGenericParamConstraint(0, yypvt[-2].string, yypvt[-0].token); } break;
+case 184:
+#line 561 "asmparse.y"
+{ yypvt[-0].cad->tkInterfacePair = yypvt[-1].token;
+ if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad);
+ } break;
+case 185:
+#line 569 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ PASM->AddField(yypvt[-2].string, yypvt[-3].binstr, yypvt[-4].fieldAttr, yypvt[-1].string, yypvt[-0].binstr, yypvt[-5].int32); } break;
+case 186:
+#line 573 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) 0; } break;
+case 187:
+#line 574 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdStatic); } break;
+case 188:
+#line 575 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPublic); } break;
+case 189:
+#line 576 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivate); } break;
+case 190:
+#line 577 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamily); } break;
+case 191:
+#line 578 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdInitOnly); } break;
+case 192:
+#line 579 "asmparse.y"
+{ yyval.fieldAttr = yypvt[-1].fieldAttr; } break;
+case 193:
+#line 580 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdSpecialName); } break;
+case 194:
+#line 593 "asmparse.y"
+{ PASM->m_pMarshal = yypvt[-1].binstr; } break;
+case 195:
+#line 594 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdAssembly); } break;
+case 196:
+#line 595 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamANDAssem); } break;
+case 197:
+#line 596 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamORAssem); } break;
+case 198:
+#line 597 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivateScope); } break;
+case 199:
+#line 598 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdLiteral); } break;
+case 200:
+#line 599 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdNotSerialized); } break;
+case 201:
+#line 600 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].int32); } break;
+case 202:
+#line 603 "asmparse.y"
+{ yyval.string = 0; } break;
+case 203:
+#line 604 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 204:
+#line 607 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 205:
+#line 608 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 206:
+#line 611 "asmparse.y"
+{ yyval.int32 = 0xFFFFFFFF; } break;
+case 207:
+#line 612 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 208:
+#line 617 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if (yypvt[-3].binstr == NULL)
+ {
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string, parser->MakeSig(yypvt[-8].int32|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
+ parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
+ yyval.token = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
+ }
+ } break;
+case 209:
+#line 634 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
+ parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, yypvt[-3].int32));
+ } break;
+case 210:
+#line 640 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if (yypvt[-3].binstr == NULL)
+ {
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
+ yyval.token = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
+ }
+ } break;
+case 211:
+#line 656 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, yypvt[-3].int32));
+ } break;
+case 212:
+#line 660 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 213:
+#line 661 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 214:
+#line 662 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 215:
+#line 665 "asmparse.y"
+{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_HASTHIS); } break;
+case 216:
+#line 666 "asmparse.y"
+{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS); } break;
+case 217:
+#line 667 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 218:
+#line 668 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 219:
+#line 671 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
+case 220:
+#line 672 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
+case 221:
+#line 673 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_VARARG; } break;
+case 222:
+#line 674 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_C; } break;
+case 223:
+#line 675 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_STDCALL; } break;
+case 224:
+#line 676 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_THISCALL; } break;
+case 225:
+#line 677 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_FASTCALL; } break;
+case 226:
+#line 678 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_UNMANAGED; } break;
+case 227:
+#line 681 "asmparse.y"
+{ yyval.token = yypvt[-1].int32; } break;
+case 228:
+#line 684 "asmparse.y"
+{ yyval.token = yypvt[-0].token;
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ PASM->SetMemberRefFixup(yypvt[-0].token,iOpcodeLen); } break;
+case 229:
+#line 690 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ yyval.token = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 230:
+#line 694 "asmparse.y"
+{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ yyval.token = PASM->MakeMemberRef(NULL, yypvt[-0].string, yypvt[-1].binstr);
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 231:
+#line 697 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 232:
+#line 699 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 233:
+#line 701 "asmparse.y"
+{ yyval.token = yypvt[-0].token;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 234:
+#line 706 "asmparse.y"
+{ PASM->ResetEvent(yypvt[-0].string, yypvt[-1].token, yypvt[-2].eventAttr); } break;
+case 235:
+#line 707 "asmparse.y"
+{ PASM->ResetEvent(yypvt[-0].string, mdTypeRefNil, yypvt[-1].eventAttr); } break;
+case 236:
+#line 711 "asmparse.y"
+{ yyval.eventAttr = (CorEventAttr) 0; } break;
+case 237:
+#line 712 "asmparse.y"
+{ yyval.eventAttr = yypvt[-1].eventAttr; } break;
+case 238:
+#line 713 "asmparse.y"
+{ yyval.eventAttr = (CorEventAttr) (yypvt[-1].eventAttr | evSpecialName); } break;
+case 241:
+#line 720 "asmparse.y"
+{ PASM->SetEventMethod(0, yypvt[-0].token); } break;
+case 242:
+#line 721 "asmparse.y"
+{ PASM->SetEventMethod(1, yypvt[-0].token); } break;
+case 243:
+#line 722 "asmparse.y"
+{ PASM->SetEventMethod(2, yypvt[-0].token); } break;
+case 244:
+#line 723 "asmparse.y"
+{ PASM->SetEventMethod(3, yypvt[-0].token); } break;
+case 249:
+#line 732 "asmparse.y"
+{ PASM->ResetProp(yypvt[-4].string,
+ parser->MakeSig((IMAGE_CEE_CS_CALLCONV_PROPERTY |
+ (yypvt[-6].int32 & IMAGE_CEE_CS_CALLCONV_HASTHIS)),yypvt[-5].binstr,yypvt[-2].binstr), yypvt[-7].propAttr, yypvt[-0].binstr);} break;
+case 250:
+#line 737 "asmparse.y"
+{ yyval.propAttr = (CorPropertyAttr) 0; } break;
+case 251:
+#line 738 "asmparse.y"
+{ yyval.propAttr = yypvt[-1].propAttr; } break;
+case 252:
+#line 739 "asmparse.y"
+{ yyval.propAttr = (CorPropertyAttr) (yypvt[-1].propAttr | prSpecialName); } break;
+case 255:
+#line 747 "asmparse.y"
+{ PASM->SetPropMethod(0, yypvt[-0].token); } break;
+case 256:
+#line 748 "asmparse.y"
+{ PASM->SetPropMethod(1, yypvt[-0].token); } break;
+case 257:
+#line 749 "asmparse.y"
+{ PASM->SetPropMethod(2, yypvt[-0].token); } break;
+case 262:
+#line 757 "asmparse.y"
+{ PASM->ResetForNextMethod();
+ uMethodBeginLine = PASM->m_ulCurLine;
+ uMethodBeginColumn=PASM->m_ulCurColumn;
+ } break;
+case 263:
+#line 763 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 264:
+#line 764 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 265:
+#line 767 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 266:
+#line 768 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 267:
+#line 771 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 268:
+#line 775 "asmparse.y"
+{ BinStr* sig;
+ if (yypvt[-5].typarlist == NULL) sig = parser->MakeSig(yypvt[-10].int32, yypvt[-8].binstr, yypvt[-3].binstr);
+ else {
+ FixupTyPars(yypvt[-8].binstr);
+ sig = parser->MakeSig(yypvt[-10].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC, yypvt[-8].binstr, yypvt[-3].binstr, yypvt[-5].typarlist->Count());
+ FixupConstraints();
+ }
+ PASM->StartMethod(yypvt[-6].string, sig, yypvt[-11].methAttr, yypvt[-7].binstr, yypvt[-9].int32, yypvt[-5].typarlist);
+ TyParFixupList.RESET(false);
+ PASM->SetImplAttr((USHORT)yypvt[-1].implAttr);
+ PASM->m_pCurMethod->m_ulLines[0] = uMethodBeginLine;
+ PASM->m_pCurMethod->m_ulColumns[0]=uMethodBeginColumn;
+ } break;
+case 269:
+#line 790 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) 0; } break;
+case 270:
+#line 791 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdStatic); } break;
+case 271:
+#line 792 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPublic); } break;
+case 272:
+#line 793 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivate); } break;
+case 273:
+#line 794 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamily); } break;
+case 274:
+#line 795 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdFinal); } break;
+case 275:
+#line 796 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdSpecialName); } break;
+case 276:
+#line 797 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdVirtual); } break;
+case 277:
+#line 798 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdCheckAccessOnOverride); } break;
+case 278:
+#line 799 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdAbstract); } break;
+case 279:
+#line 800 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdAssem); } break;
+case 280:
+#line 801 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamANDAssem); } break;
+case 281:
+#line 802 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamORAssem); } break;
+case 282:
+#line 803 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivateScope); } break;
+case 283:
+#line 804 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdHideBySig); } break;
+case 284:
+#line 805 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdNewSlot); } break;
+case 285:
+#line 806 "asmparse.y"
+{ yyval.methAttr = yypvt[-1].methAttr; } break;
+case 286:
+#line 807 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdUnmanagedExport); } break;
+case 287:
+#line 808 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdRequireSecObject); } break;
+case 288:
+#line 809 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].int32); } break;
+case 289:
+#line 811 "asmparse.y"
+{ PASM->SetPinvoke(yypvt[-4].binstr,0,yypvt[-2].binstr,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-7].methAttr | mdPinvokeImpl); } break;
+case 290:
+#line 814 "asmparse.y"
+{ PASM->SetPinvoke(yypvt[-2].binstr,0,NULL,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-5].methAttr | mdPinvokeImpl); } break;
+case 291:
+#line 817 "asmparse.y"
+{ PASM->SetPinvoke(new BinStr(),0,NULL,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-4].methAttr | mdPinvokeImpl); } break;
+case 292:
+#line 821 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) 0; } break;
+case 293:
+#line 822 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmNoMangle); } break;
+case 294:
+#line 823 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAnsi); } break;
+case 295:
+#line 824 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetUnicode); } break;
+case 296:
+#line 825 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAuto); } break;
+case 297:
+#line 826 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmSupportsLastError); } break;
+case 298:
+#line 827 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvWinapi); } break;
+case 299:
+#line 828 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvCdecl); } break;
+case 300:
+#line 829 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvStdcall); } break;
+case 301:
+#line 830 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvThiscall); } break;
+case 302:
+#line 831 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvFastcall); } break;
+case 303:
+#line 832 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitEnabled); } break;
+case 304:
+#line 833 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitDisabled); } break;
+case 305:
+#line 834 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharEnabled); } break;
+case 306:
+#line 835 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharDisabled); } break;
+case 307:
+#line 836 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].int32); } break;
+case 308:
+#line 839 "asmparse.y"
+{ yyval.string = newString(COR_CTOR_METHOD_NAME); } break;
+case 309:
+#line 840 "asmparse.y"
+{ yyval.string = newString(COR_CCTOR_METHOD_NAME); } break;
+case 310:
+#line 841 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 311:
+#line 844 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 312:
+#line 845 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdIn; } break;
+case 313:
+#line 846 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdOut; } break;
+case 314:
+#line 847 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdOptional; } break;
+case 315:
+#line 848 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 + 1; } break;
+case 316:
+#line 851 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (miIL | miManaged); } break;
+case 317:
+#line 852 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miNative); } break;
+case 318:
+#line 853 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miIL); } break;
+case 319:
+#line 854 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miOPTIL); } break;
+case 320:
+#line 855 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miManaged); } break;
+case 321:
+#line 856 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miUnmanaged); } break;
+case 322:
+#line 857 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miForwardRef); } break;
+case 323:
+#line 858 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miPreserveSig); } break;
+case 324:
+#line 859 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miRuntime); } break;
+case 325:
+#line 860 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miInternalCall); } break;
+case 326:
+#line 861 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miSynchronized); } break;
+case 327:
+#line 862 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoInlining); } break;
+case 328:
+#line 863 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miAggressiveInlining); } break;
+case 329:
+#line 864 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoOptimization); } break;
+case 330:
+#line 865 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miAggressiveOptimization); } break;
+case 331:
+#line 866 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].int32); } break;
+case 332:
+#line 869 "asmparse.y"
+{ PASM->delArgNameList(PASM->m_firstArgName); PASM->m_firstArgName = NULL;PASM->m_lastArgName = NULL;
+ } break;
+case 335:
+#line 877 "asmparse.y"
+{ PASM->EmitByte(yypvt[-0].int32); } break;
+case 336:
+#line 878 "asmparse.y"
+{ delete PASM->m_SEHD; PASM->m_SEHD = PASM->m_SEHDstack.POP(); } break;
+case 337:
+#line 879 "asmparse.y"
+{ PASM->EmitMaxStack(yypvt[-0].int32); } break;
+case 338:
+#line 880 "asmparse.y"
+{ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
+ } break;
+case 339:
+#line 882 "asmparse.y"
+{ PASM->EmitZeroInit();
+ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
+ } break;
+case 340:
+#line 885 "asmparse.y"
+{ PASM->EmitEntryPoint(); } break;
+case 341:
+#line 886 "asmparse.y"
+{ PASM->EmitZeroInit(); } break;
+case 344:
+#line 889 "asmparse.y"
+{ PASM->AddLabel(PASM->m_CurPC,yypvt[-1].string); /*PASM->EmitLabel($1);*/ } break;
+case 350:
+#line 895 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-1].int32;
+ PASM->m_pCurMethod->m_szExportAlias = NULL;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-1].int32 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ } break;
+case 351:
+#line 905 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-3].int32;
+ PASM->m_pCurMethod->m_szExportAlias = yypvt[-0].string;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-3].int32 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ } break;
+case 352:
+#line 915 "asmparse.y"
+{ PASM->m_pCurMethod->m_wVTEntry = (WORD)yypvt[-2].int32;
+ PASM->m_pCurMethod->m_wVTSlot = (WORD)yypvt[-0].int32; } break;
+case 353:
+#line 918 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-2].token,yypvt[-0].string,NULL,NULL,NULL,NULL); } break;
+case 354:
+#line 921 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-6].token,yypvt[-4].string,
+ (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
+ parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32))
+ ,NULL,NULL,NULL);
+ PASM->ResetArgNameList();
+ } break;
+case 356:
+#line 928 "asmparse.y"
+{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurMethod->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[yypvt[-1].int32-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ } break;
+case 357:
+#line 933 "asmparse.y"
+{ int n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
+ } break;
+case 358:
+#line 939 "asmparse.y"
+{ PASM->m_pCurMethod->AddGenericParamConstraint(yypvt[-3].int32, 0, yypvt[-0].token); } break;
+case 359:
+#line 940 "asmparse.y"
+{ PASM->m_pCurMethod->AddGenericParamConstraint(0, yypvt[-2].string, yypvt[-0].token); } break;
+case 360:
+#line 943 "asmparse.y"
+{ if( yypvt[-2].int32 ) {
+ ARG_NAME_LIST* pAN=PASM->findArg(PASM->m_pCurMethod->m_firstArgName, yypvt[-2].int32 - 1);
+ if(pAN)
+ {
+ PASM->m_pCustomDescrList = &(pAN->CustDList);
+ pAN->pValue = yypvt[-0].binstr;
+ }
+ else
+ {
+ PASM->m_pCustomDescrList = NULL;
+ if(yypvt[-0].binstr) delete yypvt[-0].binstr;
+ }
+ } else {
+ PASM->m_pCustomDescrList = &(PASM->m_pCurMethod->m_RetCustDList);
+ PASM->m_pCurMethod->m_pRetValue = yypvt[-0].binstr;
+ }
+ PASM->m_tkCurrentCVOwner = 0;
+ } break;
+case 361:
+#line 963 "asmparse.y"
+{ PASM->m_pCurMethod->CloseScope(); } break;
+case 362:
+#line 966 "asmparse.y"
+{ PASM->m_pCurMethod->OpenScope(); } break;
+case 366:
+#line 977 "asmparse.y"
+{ PASM->m_SEHD->tryTo = PASM->m_CurPC; } break;
+case 367:
+#line 978 "asmparse.y"
+{ PASM->SetTryLabels(yypvt[-2].string, yypvt[-0].string); } break;
+case 368:
+#line 979 "asmparse.y"
+{ if(PASM->m_SEHD) {PASM->m_SEHD->tryFrom = yypvt[-2].int32;
+ PASM->m_SEHD->tryTo = yypvt[-0].int32;} } break;
+case 369:
+#line 983 "asmparse.y"
+{ PASM->NewSEHDescriptor();
+ PASM->m_SEHD->tryFrom = PASM->m_CurPC; } break;
+case 370:
+#line 988 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 371:
+#line 989 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 372:
+#line 990 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 373:
+#line 991 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 374:
+#line 995 "asmparse.y"
+{ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 375:
+#line 996 "asmparse.y"
+{ PASM->SetFilterLabel(yypvt[-0].string);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 376:
+#line 998 "asmparse.y"
+{ PASM->m_SEHD->sehFilter = yypvt[-0].int32;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 377:
+#line 1002 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FILTER;
+ PASM->m_SEHD->sehFilter = PASM->m_CurPC; } break;
+case 378:
+#line 1006 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_NONE;
+ PASM->SetCatchClass(yypvt[-0].token);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 379:
+#line 1011 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FINALLY;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 380:
+#line 1015 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FAULT;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 381:
+#line 1019 "asmparse.y"
+{ PASM->m_SEHD->sehHandlerTo = PASM->m_CurPC; } break;
+case 382:
+#line 1020 "asmparse.y"
+{ PASM->SetHandlerLabels(yypvt[-2].string, yypvt[-0].string); } break;
+case 383:
+#line 1021 "asmparse.y"
+{ PASM->m_SEHD->sehHandler = yypvt[-2].int32;
+ PASM->m_SEHD->sehHandlerTo = yypvt[-0].int32; } break;
+case 385:
+#line 1029 "asmparse.y"
+{ PASM->EmitDataLabel(yypvt[-1].string); } break;
+case 387:
+#line 1033 "asmparse.y"
+{ PASM->SetDataSection(); } break;
+case 388:
+#line 1034 "asmparse.y"
+{ PASM->SetTLSSection(); } break;
+case 389:
+#line 1035 "asmparse.y"
+{ PASM->SetILSection(); } break;
+case 394:
+#line 1046 "asmparse.y"
+{ yyval.int32 = 1; } break;
+case 395:
+#line 1047 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32;
+ if(yypvt[-1].int32 <= 0) { PASM->report->error("Illegal item count: %d\n",yypvt[-1].int32);
+ if(!PASM->OnErrGo) yyval.int32 = 1; }} break;
+case 396:
+#line 1052 "asmparse.y"
+{ PASM->EmitDataString(yypvt[-1].binstr); } break;
+case 397:
+#line 1053 "asmparse.y"
+{ PASM->EmitDD(yypvt[-1].string); } break;
+case 398:
+#line 1054 "asmparse.y"
+{ PASM->EmitData(yypvt[-1].binstr->ptr(),yypvt[-1].binstr->length()); } break;
+case 399:
+#line 1056 "asmparse.y"
+{ float f = (float) (*yypvt[-2].float64); float* p = new (nothrow) float[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i < yypvt[-0].int32; i++) p[i] = f;
+ PASM->EmitData(p, sizeof(float)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(float)*yypvt[-0].int32); } break;
+case 400:
+#line 1063 "asmparse.y"
+{ double* p = new (nothrow) double[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].float64);
+ PASM->EmitData(p, sizeof(double)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(double)*yypvt[-0].int32); } break;
+case 401:
+#line 1070 "asmparse.y"
+{ __int64* p = new (nothrow) __int64[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].int64);
+ PASM->EmitData(p, sizeof(__int64)*yypvt[-0].int32); delete yypvt[-2].int64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int64)*yypvt[-0].int32); } break;
+case 402:
+#line 1077 "asmparse.y"
+{ __int32* p = new (nothrow) __int32[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = yypvt[-2].int32;
+ PASM->EmitData(p, sizeof(__int32)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int32)*yypvt[-0].int32); } break;
+case 403:
+#line 1084 "asmparse.y"
+{ __int16 i = (__int16) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
+ __int16* p = new (nothrow) __int16[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int16)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int16)*yypvt[-0].int32); } break;
+case 404:
+#line 1092 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
+ __int8* p = new (nothrow) __int8[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int8)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int8)*yypvt[-0].int32); } break;
+case 405:
+#line 1099 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(float)*yypvt[-0].int32); } break;
+case 406:
+#line 1100 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(double)*yypvt[-0].int32); } break;
+case 407:
+#line 1101 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int64)*yypvt[-0].int32); } break;
+case 408:
+#line 1102 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int32)*yypvt[-0].int32); } break;
+case 409:
+#line 1103 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int16)*yypvt[-0].int32); } break;
+case 410:
+#line 1104 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int8)*yypvt[-0].int32); } break;
+case 411:
+#line 1108 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
+ float f = (float)(*yypvt[-1].float64);
+ yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-1].float64; } break;
+case 412:
+#line 1111 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].float64); delete yypvt[-1].float64; } break;
+case 413:
+#line 1113 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 414:
+#line 1115 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 415:
+#line 1117 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 416:
+#line 1119 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 417:
+#line 1121 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 418:
+#line 1123 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 419:
+#line 1125 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 420:
+#line 1127 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 421:
+#line 1129 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 422:
+#line 1131 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 423:
+#line 1133 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 424:
+#line 1135 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 425:
+#line 1137 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 426:
+#line 1139 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 427:
+#line 1141 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 428:
+#line 1143 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN);
+ yyval.binstr->appendInt8(yypvt[-1].int32);} break;
+case 429:
+#line 1145 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
+ yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-1].binstr;} break;
+case 430:
+#line 1149 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 431:
+#line 1152 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 432:
+#line 1153 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 433:
+#line 1156 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = new BinStr(); yyval.binstr->appendInt8(i); } break;
+case 434:
+#line 1157 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(i); } break;
+case 435:
+#line 1161 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 436:
+#line 1162 "asmparse.y"
+{ yyval.binstr = BinStrToUnicode(yypvt[-0].binstr,true); yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);} break;
+case 437:
+#line 1163 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CLASS);
+ yyval.binstr->appendInt32(0); } break;
+case 438:
+#line 1168 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 439:
+#line 1169 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); yyval.binstr->appendInt8(0xFF); } break;
+case 440:
+#line 1170 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
+ AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
+case 441:
+#line 1172 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
+case 442:
+#line 1174 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-1].token));} break;
+case 443:
+#line 1176 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); yyval.binstr->appendInt8(0xFF); } break;
+case 444:
+#line 1177 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);} break;
+case 445:
+#line 1179 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_R4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 446:
+#line 1183 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 447:
+#line 1187 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 448:
+#line 1191 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 449:
+#line 1195 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 450:
+#line 1199 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 451:
+#line 1203 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 452:
+#line 1207 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 453:
+#line 1211 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 454:
+#line 1215 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 455:
+#line 1219 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 456:
+#line 1223 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 457:
+#line 1227 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 458:
+#line 1231 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 459:
+#line 1235 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_CHAR);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 460:
+#line 1239 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_BOOLEAN);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 461:
+#line 1243 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 462:
+#line 1247 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(SERIALIZATION_TYPE_TYPE);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 463:
+#line 1251 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 464:
+#line 1257 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 465:
+#line 1258 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ float f = (float) (*yypvt[-0].float64); yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-0].float64; } break;
+case 466:
+#line 1260 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 467:
+#line 1264 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 468:
+#line 1265 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].float64); delete yypvt[-0].float64; } break;
+case 469:
+#line 1267 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
+case 470:
+#line 1271 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 471:
+#line 1272 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
+case 472:
+#line 1276 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 473:
+#line 1277 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt32(yypvt[-0].int32);} break;
+case 474:
+#line 1280 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 475:
+#line 1281 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt16(yypvt[-0].int32);} break;
+case 476:
+#line 1284 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 477:
+#line 1285 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(yypvt[-0].int32); } break;
+case 478:
+#line 1288 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 479:
+#line 1289 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt8(yypvt[-0].int32);} break;
+case 480:
+#line 1293 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 481:
+#line 1294 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
+case 482:
+#line 1295 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
+case 483:
+#line 1299 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 484:
+#line 1300 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
+case 485:
+#line 1301 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr;
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
+case 486:
+#line 1303 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token));} break;
+case 487:
+#line 1307 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 488:
+#line 1308 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 489:
+#line 1312 "asmparse.y"
+{ parser->m_ANSFirst.PUSH(PASM->m_firstArgName);
+ parser->m_ANSLast.PUSH(PASM->m_lastArgName);
+ PASM->m_firstArgName = NULL;
+ PASM->m_lastArgName = NULL; } break;
+case 490:
+#line 1318 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 491:
+#line 1321 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 492:
+#line 1324 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 493:
+#line 1327 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 494:
+#line 1330 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 495:
+#line 1333 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 496:
+#line 1336 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode);
+ if((!PASM->OnErrGo)&&
+ ((yypvt[-0].opcode == CEE_NEWOBJ)||
+ (yypvt[-0].opcode == CEE_CALLVIRT)))
+ iCallConv = IMAGE_CEE_CS_CALLCONV_HASTHIS;
+ } break;
+case 497:
+#line 1344 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 498:
+#line 1347 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 499:
+#line 1350 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 500:
+#line 1353 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 501:
+#line 1356 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); iOpcodeLen = PASM->OpcodeLen(yyval.instr); } break;
+case 502:
+#line 1359 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 503:
+#line 1362 "asmparse.y"
+{ yyval.instr = yypvt[-1].instr; bParsingByteArray = TRUE; } break;
+case 504:
+#line 1366 "asmparse.y"
+{ PASM->EmitOpcode(yypvt[-0].instr); } break;
+case 505:
+#line 1367 "asmparse.y"
+{ PASM->EmitInstrVar(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 506:
+#line 1368 "asmparse.y"
+{ PASM->EmitInstrVarByName(yypvt[-1].instr, yypvt[-0].string); } break;
+case 507:
+#line 1369 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 508:
+#line 1370 "asmparse.y"
+{ PASM->EmitInstrI8(yypvt[-1].instr, yypvt[-0].int64); } break;
+case 509:
+#line 1371 "asmparse.y"
+{ PASM->EmitInstrR(yypvt[-1].instr, yypvt[-0].float64); delete (yypvt[-0].float64);} break;
+case 510:
+#line 1372 "asmparse.y"
+{ double f = (double) (*yypvt[-0].int64); PASM->EmitInstrR(yypvt[-1].instr, &f); } break;
+case 511:
+#line 1373 "asmparse.y"
+{ unsigned L = yypvt[-1].binstr->length();
+ FAIL_UNLESS(L >= sizeof(float), ("%d hexbytes, must be at least %d\n",
+ L,sizeof(float)));
+ if(L < sizeof(float)) {YYERROR; }
+ else {
+ double f = (L >= sizeof(double)) ? *((double *)(yypvt[-1].binstr->ptr()))
+ : (double)(*(float *)(yypvt[-1].binstr->ptr()));
+ PASM->EmitInstrR(yypvt[-2].instr,&f); }
+ delete yypvt[-1].binstr; } break;
+case 512:
+#line 1382 "asmparse.y"
+{ PASM->EmitInstrBrOffset(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 513:
+#line 1383 "asmparse.y"
+{ PASM->EmitInstrBrTarget(yypvt[-1].instr, yypvt[-0].string); } break;
+case 514:
+#line 1385 "asmparse.y"
+{ PASM->SetMemberRefFixup(yypvt[-0].token,PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ iCallConv = 0;
+ } break;
+case 515:
+#line 1392 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-4].instr));
+ PASM->EmitInstrI(yypvt[-4].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 516:
+#line 1400 "asmparse.y"
+{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-0].string, yypvt[-1].binstr);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-2].instr));
+ PASM->EmitInstrI(yypvt[-2].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 517:
+#line 1407 "asmparse.y"
+{ mdToken mr = yypvt[-0].token;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 518:
+#line 1413 "asmparse.y"
+{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 519:
+#line 1419 "asmparse.y"
+{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 520:
+#line 1425 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 521:
+#line 1429 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-1].instr, yypvt[-0].binstr,TRUE); } break;
+case 522:
+#line 1431 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-4].instr, yypvt[-1].binstr,FALSE); } break;
+case 523:
+#line 1433 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-3].instr, yypvt[-1].binstr,FALSE,TRUE); } break;
+case 524:
+#line 1435 "asmparse.y"
+{ PASM->EmitInstrSig(yypvt[-5].instr, parser->MakeSig(yypvt[-4].int32, yypvt[-3].binstr, yypvt[-1].binstr));
+ PASM->ResetArgNameList();
+ } break;
+case 525:
+#line 1439 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ iOpcodeLen = 0;
+ } break;
+case 526:
+#line 1444 "asmparse.y"
+{ PASM->EmitInstrSwitch(yypvt[-3].instr, yypvt[-1].labels); } break;
+case 527:
+#line 1447 "asmparse.y"
+{ yyval.labels = 0; } break;
+case 528:
+#line 1448 "asmparse.y"
+{ yyval.labels = new Labels(yypvt[-2].string, yypvt[-0].labels, TRUE); } break;
+case 529:
+#line 1449 "asmparse.y"
+{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-2].int32, yypvt[-0].labels, FALSE); } break;
+case 530:
+#line 1450 "asmparse.y"
+{ yyval.labels = new Labels(yypvt[-0].string, NULL, TRUE); } break;
+case 531:
+#line 1451 "asmparse.y"
+{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-0].int32, NULL, FALSE); } break;
+case 532:
+#line 1455 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 533:
+#line 1456 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 534:
+#line 1459 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 535:
+#line 1460 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 536:
+#line 1463 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 537:
+#line 1464 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 538:
+#line 1468 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 539:
+#line 1469 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr;} break;
+case 540:
+#line 1472 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 541:
+#line 1473 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 542:
+#line 1476 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_SENTINEL); } break;
+case 543:
+#line 1477 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-1].binstr); PASM->addArgName(NULL, yypvt[-1].binstr, yypvt[-0].binstr, yypvt[-2].int32); } break;
+case 544:
+#line 1478 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-2].binstr); PASM->addArgName(yypvt[-0].string, yypvt[-2].binstr, yypvt[-1].binstr, yypvt[-3].int32);} break;
+case 545:
+#line 1482 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(PASM->GetAsmRef(yypvt[-2].string), yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
+case 546:
+#line 1483 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(yypvt[-2].token, yypvt[-0].string, NULL); } break;
+case 547:
+#line 1484 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(mdTokenNil, yypvt[-0].string, NULL); } break;
+case 548:
+#line 1485 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(PASM->GetModRef(yypvt[-2].string),yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
+case 549:
+#line 1486 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(1,yypvt[-0].string,NULL); } break;
+case 550:
+#line 1487 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 551:
+#line 1488 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 552:
+#line 1489 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) yyval.token = PASM->m_pCurClass->m_cl;
+ else { yyval.token = 0; PASM->report->error(".this outside class scope\n"); }
+ } break;
+case 553:
+#line 1492 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) {
+ yyval.token = PASM->m_pCurClass->m_crExtends;
+ if(RidFromToken(yyval.token) == 0)
+ PASM->report->error(".base undefined\n");
+ } else { yyval.token = 0; PASM->report->error(".base outside class scope\n"); }
+ } break;
+case 554:
+#line 1498 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) {
+ if(PASM->m_pCurClass->m_pEncloser != NULL) yyval.token = PASM->m_pCurClass->m_pEncloser->m_cl;
+ else { yyval.token = 0; PASM->report->error(".nester undefined\n"); }
+ } else { yyval.token = 0; PASM->report->error(".nester outside class scope\n"); }
+ } break;
+case 555:
+#line 1505 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 556:
+#line 1506 "asmparse.y"
+{ yyval.string = newStringWDel(yypvt[-2].string, NESTING_SEP, yypvt[-0].string); } break;
+case 557:
+#line 1509 "asmparse.y"
+{ yyval.token = yypvt[-0].token;} break;
+case 558:
+#line 1510 "asmparse.y"
+{ yyval.token = PASM->GetAsmRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
+case 559:
+#line 1511 "asmparse.y"
+{ yyval.token = PASM->GetModRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
+case 560:
+#line 1512 "asmparse.y"
+{ yyval.token = PASM->ResolveTypeSpec(yypvt[-0].binstr); } break;
+case 561:
+#line 1516 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 562:
+#line 1518 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt(yyval.binstr,yypvt[-7].binstr->length()); yyval.binstr->append(yypvt[-7].binstr);
+ corEmitInt(yyval.binstr,yypvt[-5].binstr->length()); yyval.binstr->append(yypvt[-5].binstr);
+ corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr);
+ PASM->report->warn("Deprecated 4-string form of custom marshaler, first two strings ignored\n");} break;
+case 563:
+#line 1525 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr); } break;
+case 564:
+#line 1530 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDSYSSTRING);
+ corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
+case 565:
+#line 1533 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDARRAY);
+ corEmitInt(yyval.binstr,yypvt[-2].int32); yyval.binstr->append(yypvt[-0].binstr); } break;
+case 566:
+#line 1535 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANT);
+ PASM->report->warn("Deprecated native type 'variant'\n"); } break;
+case 567:
+#line 1537 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CURRENCY); } break;
+case 568:
+#line 1538 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SYSCHAR);
+ PASM->report->warn("Deprecated native type 'syschar'\n"); } break;
+case 569:
+#line 1540 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VOID);
+ PASM->report->warn("Deprecated native type 'void'\n"); } break;
+case 570:
+#line 1542 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BOOLEAN); } break;
+case 571:
+#line 1543 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I1); } break;
+case 572:
+#line 1544 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I2); } break;
+case 573:
+#line 1545 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I4); } break;
+case 574:
+#line 1546 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I8); } break;
+case 575:
+#line 1547 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R4); } break;
+case 576:
+#line 1548 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R8); } break;
+case 577:
+#line 1549 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ERROR); } break;
+case 578:
+#line 1550 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
+case 579:
+#line 1551 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
+case 580:
+#line 1552 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
+case 581:
+#line 1553 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
+case 582:
+#line 1554 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
+case 583:
+#line 1555 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
+case 584:
+#line 1556 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
+case 585:
+#line 1557 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
+case 586:
+#line 1558 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(NATIVE_TYPE_PTR);
+ PASM->report->warn("Deprecated native type '*'\n"); } break;
+case 587:
+#line 1560 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY); } break;
+case 588:
+#line 1562 "asmparse.y"
+{ yyval.binstr = yypvt[-3].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,yypvt[-1].int32);
+ corEmitInt(yyval.binstr,0); } break;
+case 589:
+#line 1567 "asmparse.y"
+{ yyval.binstr = yypvt[-5].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,yypvt[-1].int32);
+ corEmitInt(yyval.binstr,yypvt[-3].int32);
+ corEmitInt(yyval.binstr,ntaSizeParamIndexSpecified); } break;
+case 590:
+#line 1572 "asmparse.y"
+{ yyval.binstr = yypvt[-4].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
+case 591:
+#line 1575 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DECIMAL);
+ PASM->report->warn("Deprecated native type 'decimal'\n"); } break;
+case 592:
+#line 1577 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DATE);
+ PASM->report->warn("Deprecated native type 'date'\n"); } break;
+case 593:
+#line 1579 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BSTR); } break;
+case 594:
+#line 1580 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTR); } break;
+case 595:
+#line 1581 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPWSTR); } break;
+case 596:
+#line 1582 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPTSTR); } break;
+case 597:
+#line 1583 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_OBJECTREF);
+ PASM->report->warn("Deprecated native type 'objectref'\n"); } break;
+case 598:
+#line 1585 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IUNKNOWN);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 599:
+#line 1587 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IDISPATCH);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 600:
+#line 1589 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_STRUCT); } break;
+case 601:
+#line 1590 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INTF);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 602:
+#line 1592 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt(yyval.binstr,yypvt[-0].int32);
+ corEmitInt(yyval.binstr,0);} break;
+case 603:
+#line 1595 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt(yyval.binstr,yypvt[-2].int32);
+ corEmitInt(yyval.binstr,yypvt[-0].binstr->length()); yyval.binstr->append(yypvt[-0].binstr); } break;
+case 604:
+#line 1599 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INT); } break;
+case 605:
+#line 1600 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
+case 606:
+#line 1601 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
+case 607:
+#line 1602 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_NESTEDSTRUCT);
+ PASM->report->warn("Deprecated native type 'nested struct'\n"); } break;
+case 608:
+#line 1604 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BYVALSTR); } break;
+case 609:
+#line 1605 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ANSIBSTR); } break;
+case 610:
+#line 1606 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_TBSTR); } break;
+case 611:
+#line 1607 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANTBOOL); } break;
+case 612:
+#line 1608 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FUNC); } break;
+case 613:
+#line 1609 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ASANY); } break;
+case 614:
+#line 1610 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTRUCT); } break;
+case 615:
+#line 1611 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
+case 616:
+#line 1614 "asmparse.y"
+{ yyval.int32 = -1; } break;
+case 617:
+#line 1615 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 618:
+#line 1618 "asmparse.y"
+{ yyval.int32 = VT_EMPTY; } break;
+case 619:
+#line 1619 "asmparse.y"
+{ yyval.int32 = VT_NULL; } break;
+case 620:
+#line 1620 "asmparse.y"
+{ yyval.int32 = VT_VARIANT; } break;
+case 621:
+#line 1621 "asmparse.y"
+{ yyval.int32 = VT_CY; } break;
+case 622:
+#line 1622 "asmparse.y"
+{ yyval.int32 = VT_VOID; } break;
+case 623:
+#line 1623 "asmparse.y"
+{ yyval.int32 = VT_BOOL; } break;
+case 624:
+#line 1624 "asmparse.y"
+{ yyval.int32 = VT_I1; } break;
+case 625:
+#line 1625 "asmparse.y"
+{ yyval.int32 = VT_I2; } break;
+case 626:
+#line 1626 "asmparse.y"
+{ yyval.int32 = VT_I4; } break;
+case 627:
+#line 1627 "asmparse.y"
+{ yyval.int32 = VT_I8; } break;
+case 628:
+#line 1628 "asmparse.y"
+{ yyval.int32 = VT_R4; } break;
+case 629:
+#line 1629 "asmparse.y"
+{ yyval.int32 = VT_R8; } break;
+case 630:
+#line 1630 "asmparse.y"
+{ yyval.int32 = VT_UI1; } break;
+case 631:
+#line 1631 "asmparse.y"
+{ yyval.int32 = VT_UI2; } break;
+case 632:
+#line 1632 "asmparse.y"
+{ yyval.int32 = VT_UI4; } break;
+case 633:
+#line 1633 "asmparse.y"
+{ yyval.int32 = VT_UI8; } break;
+case 634:
+#line 1634 "asmparse.y"
+{ yyval.int32 = VT_UI1; } break;
+case 635:
+#line 1635 "asmparse.y"
+{ yyval.int32 = VT_UI2; } break;
+case 636:
+#line 1636 "asmparse.y"
+{ yyval.int32 = VT_UI4; } break;
+case 637:
+#line 1637 "asmparse.y"
+{ yyval.int32 = VT_UI8; } break;
+case 638:
+#line 1638 "asmparse.y"
+{ yyval.int32 = VT_PTR; } break;
+case 639:
+#line 1639 "asmparse.y"
+{ yyval.int32 = yypvt[-2].int32 | VT_ARRAY; } break;
+case 640:
+#line 1640 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | VT_VECTOR; } break;
+case 641:
+#line 1641 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | VT_BYREF; } break;
+case 642:
+#line 1642 "asmparse.y"
+{ yyval.int32 = VT_DECIMAL; } break;
+case 643:
+#line 1643 "asmparse.y"
+{ yyval.int32 = VT_DATE; } break;
+case 644:
+#line 1644 "asmparse.y"
+{ yyval.int32 = VT_BSTR; } break;
+case 645:
+#line 1645 "asmparse.y"
+{ yyval.int32 = VT_LPSTR; } break;
+case 646:
+#line 1646 "asmparse.y"
+{ yyval.int32 = VT_LPWSTR; } break;
+case 647:
+#line 1647 "asmparse.y"
+{ yyval.int32 = VT_UNKNOWN; } break;
+case 648:
+#line 1648 "asmparse.y"
+{ yyval.int32 = VT_DISPATCH; } break;
+case 649:
+#line 1649 "asmparse.y"
+{ yyval.int32 = VT_SAFEARRAY; } break;
+case 650:
+#line 1650 "asmparse.y"
+{ yyval.int32 = VT_INT; } break;
+case 651:
+#line 1651 "asmparse.y"
+{ yyval.int32 = VT_UINT; } break;
+case 652:
+#line 1652 "asmparse.y"
+{ yyval.int32 = VT_UINT; } break;
+case 653:
+#line 1653 "asmparse.y"
+{ yyval.int32 = VT_ERROR; } break;
+case 654:
+#line 1654 "asmparse.y"
+{ yyval.int32 = VT_HRESULT; } break;
+case 655:
+#line 1655 "asmparse.y"
+{ yyval.int32 = VT_CARRAY; } break;
+case 656:
+#line 1656 "asmparse.y"
+{ yyval.int32 = VT_USERDEFINED; } break;
+case 657:
+#line 1657 "asmparse.y"
+{ yyval.int32 = VT_RECORD; } break;
+case 658:
+#line 1658 "asmparse.y"
+{ yyval.int32 = VT_FILETIME; } break;
+case 659:
+#line 1659 "asmparse.y"
+{ yyval.int32 = VT_BLOB; } break;
+case 660:
+#line 1660 "asmparse.y"
+{ yyval.int32 = VT_STREAM; } break;
+case 661:
+#line 1661 "asmparse.y"
+{ yyval.int32 = VT_STORAGE; } break;
+case 662:
+#line 1662 "asmparse.y"
+{ yyval.int32 = VT_STREAMED_OBJECT; } break;
+case 663:
+#line 1663 "asmparse.y"
+{ yyval.int32 = VT_STORED_OBJECT; } break;
+case 664:
+#line 1664 "asmparse.y"
+{ yyval.int32 = VT_BLOB_OBJECT; } break;
+case 665:
+#line 1665 "asmparse.y"
+{ yyval.int32 = VT_CF; } break;
+case 666:
+#line 1666 "asmparse.y"
+{ yyval.int32 = VT_CLSID; } break;
+case 667:
+#line 1670 "asmparse.y"
+{ if(yypvt[-0].token == PASM->m_tkSysString)
+ { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); }
+ else if(yypvt[-0].token == PASM->m_tkSysObject)
+ { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); }
+ else
+ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CLASS, yypvt[-0].token); } break;
+case 668:
+#line 1676 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); } break;
+case 669:
+#line 1677 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
+case 670:
+#line 1678 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
+case 671:
+#line 1679 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 672:
+#line 1680 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeArray(ELEMENT_TYPE_ARRAY, yypvt[-3].binstr, yypvt[-1].binstr); } break;
+case 673:
+#line 1681 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_BYREF); } break;
+case 674:
+#line 1682 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PTR); } break;
+case 675:
+#line 1683 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PINNED); } break;
+case 676:
+#line 1684 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_REQD, yypvt[-1].token);
+ yyval.binstr->append(yypvt[-4].binstr); } break;
+case 677:
+#line 1686 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_OPT, yypvt[-1].token);
+ yyval.binstr->append(yypvt[-4].binstr); } break;
+case 678:
+#line 1689 "asmparse.y"
+{ yyval.binstr = parser->MakeSig(yypvt[-5].int32, yypvt[-4].binstr, yypvt[-1].binstr);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_FNPTR);
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ } break;
+case 679:
+#line 1695 "asmparse.y"
+{ if(yypvt[-1].binstr == NULL) yyval.binstr = yypvt[-3].binstr;
+ else {
+ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(ELEMENT_TYPE_GENERICINST);
+ yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr, corCountArgs(yypvt[-1].binstr));
+ yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-3].binstr; delete yypvt[-1].binstr; }} break;
+case 680:
+#line 1702 "asmparse.y"
+{ //if(PASM->m_pCurMethod) {
+ // if(($3 < 0)||((DWORD)$3 >= PASM->m_pCurMethod->m_NumTyPars))
+ // PASM->report->error("Invalid method type parameter '%d'\n",$3);
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_MVAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
+ //} else PASM->report->error("Method type parameter '%d' outside method scope\n",$3);
+ } break;
+case 681:
+#line 1708 "asmparse.y"
+{ //if(PASM->m_pCurClass) {
+ // if(($2 < 0)||((DWORD)$2 >= PASM->m_pCurClass->m_NumTyPars))
+ // PASM->report->error("Invalid type parameter '%d'\n",$2);
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
+ //} else PASM->report->error("Type parameter '%d' outside class scope\n",$2);
+ } break;
+case 682:
+#line 1714 "asmparse.y"
+{ int eltype = ELEMENT_TYPE_MVAR;
+ int n=-1;
+ if(PASM->m_pCurMethod) n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH(yypvt[-0].string);
+ eltype = ELEMENT_TYPE_MVARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid method type parameter '%s'\n",yypvt[-0].string);
+ n = 0x1FFFFFFF; }
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
+ } break;
+case 683:
+#line 1729 "asmparse.y"
+{ int eltype = ELEMENT_TYPE_VAR;
+ int n=-1;
+ if(PASM->m_pCurClass && !newclass) n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH(yypvt[-0].string);
+ eltype = ELEMENT_TYPE_VARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid type parameter '%s'\n",yypvt[-0].string);
+ n = 0x1FFFFFFF; }
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
+ } break;
+case 684:
+#line 1744 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_TYPEDBYREF); } break;
+case 685:
+#line 1745 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VOID); } break;
+case 686:
+#line 1746 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I); } break;
+case 687:
+#line 1747 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
+case 688:
+#line 1748 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
+case 689:
+#line 1749 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 690:
+#line 1750 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SENTINEL); } break;
+case 691:
+#line 1753 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR); } break;
+case 692:
+#line 1754 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); } break;
+case 693:
+#line 1755 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN); } break;
+case 694:
+#line 1756 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1); } break;
+case 695:
+#line 1757 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2); } break;
+case 696:
+#line 1758 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4); } break;
+case 697:
+#line 1759 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8); } break;
+case 698:
+#line 1760 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4); } break;
+case 699:
+#line 1761 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8); } break;
+case 700:
+#line 1762 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
+case 701:
+#line 1763 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
+case 702:
+#line 1764 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
+case 703:
+#line 1765 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
+case 704:
+#line 1766 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
+case 705:
+#line 1767 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
+case 706:
+#line 1768 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
+case 707:
+#line 1769 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
+case 708:
+#line 1770 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
+case 709:
+#line 1773 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 710:
+#line 1774 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yypvt[-2].binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 711:
+#line 1777 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 712:
+#line 1778 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 713:
+#line 1779 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0); yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 714:
+#line 1780 "asmparse.y"
+{ FAIL_UNLESS(yypvt[-2].int32 <= yypvt[-0].int32, ("lower bound %d must be <= upper bound %d\n", yypvt[-2].int32, yypvt[-0].int32));
+ if (yypvt[-2].int32 > yypvt[-0].int32) { YYERROR; };
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-2].int32); yyval.binstr->appendInt32(yypvt[-0].int32-yypvt[-2].int32+1); } break;
+case 715:
+#line 1783 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-1].int32); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 716:
+#line 1788 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-4].secAct, yypvt[-3].token, yypvt[-1].pair); } break;
+case 717:
+#line 1790 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-5].secAct, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 718:
+#line 1791 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-1].secAct, yypvt[-0].token, (NVPair *)NULL); } break;
+case 719:
+#line 1792 "asmparse.y"
+{ PASM->AddPermissionSetDecl(yypvt[-2].secAct, yypvt[-1].binstr); } break;
+case 720:
+#line 1794 "asmparse.y"
+{ PASM->AddPermissionSetDecl(yypvt[-1].secAct,BinStrToUnicode(yypvt[-0].binstr,true));} break;
+case 721:
+#line 1796 "asmparse.y"
+{ BinStr* ret = new BinStr();
+ ret->insertInt8('.');
+ corEmitInt(ret, nSecAttrBlobs);
+ ret->append(yypvt[-1].binstr);
+ PASM->AddPermissionSetDecl(yypvt[-4].secAct,ret);
+ nSecAttrBlobs = 0; } break;
+case 722:
+#line 1804 "asmparse.y"
+{ yyval.binstr = new BinStr(); nSecAttrBlobs = 0;} break;
+case 723:
+#line 1805 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; nSecAttrBlobs = 1; } break;
+case 724:
+#line 1806 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); nSecAttrBlobs++; } break;
+case 725:
+#line 1810 "asmparse.y"
+{ yyval.binstr = PASM->EncodeSecAttr(PASM->ReflectionNotation(yypvt[-4].token),yypvt[-1].binstr,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; } break;
+case 726:
+#line 1813 "asmparse.y"
+{ yyval.binstr = PASM->EncodeSecAttr(yypvt[-4].string,yypvt[-1].binstr,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; } break;
+case 727:
+#line 1817 "asmparse.y"
+{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
+case 728:
+#line 1819 "asmparse.y"
+{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
+case 729:
+#line 1822 "asmparse.y"
+{ yyval.pair = yypvt[-0].pair; } break;
+case 730:
+#line 1823 "asmparse.y"
+{ yyval.pair = yypvt[-2].pair->Concat(yypvt[-0].pair); } break;
+case 731:
+#line 1826 "asmparse.y"
+{ yypvt[-2].binstr->appendInt8(0); yyval.pair = new NVPair(yypvt[-2].binstr, yypvt[-0].binstr); } break;
+case 732:
+#line 1829 "asmparse.y"
+{ yyval.int32 = 1; } break;
+case 733:
+#line 1830 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 734:
+#line 1833 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_BOOLEAN);
+ yyval.binstr->appendInt8(yypvt[-0].int32); } break;
+case 735:
+#line 1836 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 736:
+#line 1839 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 737:
+#line 1842 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_STRING);
+ yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr;
+ yyval.binstr->appendInt8(0); } break;
+case 738:
+#line 1846 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(1);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 739:
+#line 1852 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(2);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 740:
+#line 1858 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 741:
+#line 1864 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-3].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 742:
+#line 1872 "asmparse.y"
+{ yyval.secAct = dclRequest; } break;
+case 743:
+#line 1873 "asmparse.y"
+{ yyval.secAct = dclDemand; } break;
+case 744:
+#line 1874 "asmparse.y"
+{ yyval.secAct = dclAssert; } break;
+case 745:
+#line 1875 "asmparse.y"
+{ yyval.secAct = dclDeny; } break;
+case 746:
+#line 1876 "asmparse.y"
+{ yyval.secAct = dclPermitOnly; } break;
+case 747:
+#line 1877 "asmparse.y"
+{ yyval.secAct = dclLinktimeCheck; } break;
+case 748:
+#line 1878 "asmparse.y"
+{ yyval.secAct = dclInheritanceCheck; } break;
+case 749:
+#line 1879 "asmparse.y"
+{ yyval.secAct = dclRequestMinimum; } break;
+case 750:
+#line 1880 "asmparse.y"
+{ yyval.secAct = dclRequestOptional; } break;
+case 751:
+#line 1881 "asmparse.y"
+{ yyval.secAct = dclRequestRefuse; } break;
+case 752:
+#line 1882 "asmparse.y"
+{ yyval.secAct = dclPrejitGrant; } break;
+case 753:
+#line 1883 "asmparse.y"
+{ yyval.secAct = dclPrejitDenied; } break;
+case 754:
+#line 1884 "asmparse.y"
+{ yyval.secAct = dclNonCasDemand; } break;
+case 755:
+#line 1885 "asmparse.y"
+{ yyval.secAct = dclNonCasLinkDemand; } break;
+case 756:
+#line 1886 "asmparse.y"
+{ yyval.secAct = dclNonCasInheritance; } break;
+case 757:
+#line 1890 "asmparse.y"
+{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = FALSE; } break;
+case 758:
+#line 1891 "asmparse.y"
+{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = TRUE; } break;
+case 759:
+#line 1894 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 760:
+#line 1897 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-0].int32;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
+case 761:
+#line 1899 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-3].int32;
+ PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 762:
+#line 1902 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-2].int32;
+ PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);} break;
+case 763:
+#line 1905 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-5].int32;
+ PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 764:
+#line 1909 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-4].int32;
+ PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
+case 765:
+#line 1912 "asmparse.y"
+{ PENV->nExtLine = yypvt[-5].int32; PENV->nExtLineEnd = yypvt[-3].int32;
+ PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 766:
+#line 1916 "asmparse.y"
+{ PENV->nExtLine = yypvt[-4].int32; PENV->nExtLineEnd = yypvt[-2].int32;
+ PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
+case 767:
+#line 1919 "asmparse.y"
+{ PENV->nExtLine = yypvt[-7].int32; PENV->nExtLineEnd = yypvt[-5].int32;
+ PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 768:
+#line 1923 "asmparse.y"
+{ PENV->nExtLine = yypvt[-6].int32; PENV->nExtLineEnd = yypvt[-4].int32;
+ PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
+case 769:
+#line 1925 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32 - 1;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].binstr);} break;
+case 770:
+#line 1932 "asmparse.y"
+{ PASMM->AddFile(yypvt[-5].string, yypvt[-6].fileAttr|yypvt[-4].fileAttr|yypvt[-0].fileAttr, yypvt[-2].binstr); } break;
+case 771:
+#line 1933 "asmparse.y"
+{ PASMM->AddFile(yypvt[-1].string, yypvt[-2].fileAttr|yypvt[-0].fileAttr, NULL); } break;
+case 772:
+#line 1936 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0; } break;
+case 773:
+#line 1937 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) (yypvt[-1].fileAttr | ffContainsNoMetaData); } break;
+case 774:
+#line 1940 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0; } break;
+case 775:
+#line 1941 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0x80000000; } break;
+case 776:
+#line 1944 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 777:
+#line 1947 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-0].string, NULL, (DWORD)yypvt[-1].asmAttr, FALSE); } break;
+case 778:
+#line 1950 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) 0; } break;
+case 779:
+#line 1951 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afRetargetable); } break;
+case 780:
+#line 1952 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afContentType_WindowsRuntime); } break;
+case 781:
+#line 1953 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afPA_NoPlatform); } break;
+case 782:
+#line 1954 "asmparse.y"
+{ yyval.asmAttr = yypvt[-2].asmAttr; } break;
+case 783:
+#line 1955 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_MSIL); } break;
+case 784:
+#line 1956 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_x86); } break;
+case 785:
+#line 1957 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_AMD64); } break;
+case 786:
+#line 1958 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM); } break;
+case 787:
+#line 1959 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM64); } break;
+case 790:
+#line 1966 "asmparse.y"
+{ PASMM->SetAssemblyHashAlg(yypvt[-0].int32); } break;
+case 793:
+#line 1971 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 794:
+#line 1972 "asmparse.y"
+{ yyval.int32 = 0xFFFF; } break;
+case 795:
+#line 1975 "asmparse.y"
+{ PASMM->SetAssemblyPublicKey(yypvt[-1].binstr); } break;
+case 796:
+#line 1977 "asmparse.y"
+{ PASMM->SetAssemblyVer((USHORT)yypvt[-6].int32, (USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, (USHORT)yypvt[-0].int32); } break;
+case 797:
+#line 1978 "asmparse.y"
+{ yypvt[-0].binstr->appendInt8(0); PASMM->SetAssemblyLocale(yypvt[-0].binstr,TRUE); } break;
+case 798:
+#line 1979 "asmparse.y"
+{ PASMM->SetAssemblyLocale(yypvt[-1].binstr,FALSE); } break;
+case 801:
+#line 1984 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 802:
+#line 1987 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 803:
+#line 1990 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 804:
+#line 1994 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-0].string, NULL, yypvt[-1].asmAttr, TRUE); } break;
+case 805:
+#line 1996 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-2].string, yypvt[-0].string, yypvt[-3].asmAttr, TRUE); } break;
+case 808:
+#line 2003 "asmparse.y"
+{ PASMM->SetAssemblyHashBlob(yypvt[-1].binstr); } break;
+case 810:
+#line 2005 "asmparse.y"
+{ PASMM->SetAssemblyPublicKeyToken(yypvt[-1].binstr); } break;
+case 811:
+#line 2006 "asmparse.y"
+{ PASMM->SetAssemblyAutodetect(); } break;
+case 812:
+#line 2009 "asmparse.y"
+{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr);} break;
+case 813:
+#line 2012 "asmparse.y"
+{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr); } break;
+case 814:
+#line 2015 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) 0; } break;
+case 815:
+#line 2016 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdNotPublic); } break;
+case 816:
+#line 2017 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdPublic); } break;
+case 817:
+#line 2018 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdForwarder); } break;
+case 818:
+#line 2019 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPublic); } break;
+case 819:
+#line 2020 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPrivate); } break;
+case 820:
+#line 2021 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamily); } break;
+case 821:
+#line 2022 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedAssembly); } break;
+case 822:
+#line 2023 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamANDAssem); } break;
+case 823:
+#line 2024 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamORAssem); } break;
+case 826:
+#line 2031 "asmparse.y"
+{ PASMM->SetComTypeFile(yypvt[-0].string); } break;
+case 827:
+#line 2032 "asmparse.y"
+{ PASMM->SetComTypeComType(yypvt[-0].string); } break;
+case 828:
+#line 2033 "asmparse.y"
+{ PASMM->SetComTypeAsmRef(yypvt[-0].string); } break;
+case 829:
+#line 2034 "asmparse.y"
+{ if(!PASMM->SetComTypeImplementationTok(yypvt[-1].int32))
+ PASM->report->error("Invalid implementation of exported type\n"); } break;
+case 830:
+#line 2036 "asmparse.y"
+{ if(!PASMM->SetComTypeClassTok(yypvt[-0].int32))
+ PASM->report->error("Invalid TypeDefID of exported type\n"); } break;
+case 833:
+#line 2042 "asmparse.y"
+{ PASMM->StartManifestRes(yypvt[-0].string, yypvt[-0].string, yypvt[-1].manresAttr); } break;
+case 834:
+#line 2044 "asmparse.y"
+{ PASMM->StartManifestRes(yypvt[-2].string, yypvt[-0].string, yypvt[-3].manresAttr); } break;
+case 835:
+#line 2047 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) 0; } break;
+case 836:
+#line 2048 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPublic); } break;
+case 837:
+#line 2049 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPrivate); } break;
+case 840:
+#line 2056 "asmparse.y"
+{ PASMM->SetManifestResFile(yypvt[-2].string, (ULONG)yypvt[-0].int32); } break;
+case 841:
+#line 2057 "asmparse.y"
+{ PASMM->SetManifestResAsmRef(yypvt[-0].string); } break;/* End of actions */
+#line 329 "F:\\NetFXDev1\\src\\tools\\devdiv\\amd64\\yypars.c"
+ }
+ }
+ goto yystack; /* stack new state and value */
+ }
+#pragma warning(default:102)
+
+
+#ifdef YYDUMP
+YYLOCAL void YYNEAR YYPASCAL yydumpinfo(void)
+{
+ short stackindex;
+ short valindex;
+
+ //dump yys
+ printf("short yys[%d] {\n", YYMAXDEPTH);
+ for (stackindex = 0; stackindex < YYMAXDEPTH; stackindex++){
+ if (stackindex)
+ printf(", %s", stackindex % 10 ? "\0" : "\n");
+ printf("%6d", yys[stackindex]);
+ }
+ printf("\n};\n");
+
+ //dump yyv
+ printf("YYSTYPE yyv[%d] {\n", YYMAXDEPTH);
+ for (valindex = 0; valindex < YYMAXDEPTH; valindex++){
+ if (valindex)
+ printf(", %s", valindex % 5 ? "\0" : "\n");
+ printf("%#*x", 3+sizeof(YYSTYPE), yyv[valindex]);
+ }
+ printf("\n};\n");
+ }
+#endif
diff --git a/src/coreclr/ilasm/prebuilt/asmparse.grammar b/src/coreclr/ilasm/prebuilt/asmparse.grammar
new file mode 100644
index 00000000000..82dac9517f7
--- /dev/null
+++ b/src/coreclr/ilasm/prebuilt/asmparse.grammar
@@ -0,0 +1,1280 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+Lexical tokens
+ ID - C style alphaNumeric identifier (e.g. Hello_There2)
+ DOTTEDNAME - Sequence of dot-separated IDs (e.g. System.Object)
+ QSTRING - C style quoted string (e.g. "hi\n")
+ SQSTRING - C style singlely quoted string(e.g. 'hi')
+ INT32 - C style 32 bit integer (e.g. 235, 03423, 0x34FFF)
+ INT64 - C style 64 bit integer (e.g. -2353453636235234, 0x34FFFFFFFFFF)
+ FLOAT64 - C style floating point number (e.g. -0.2323, 354.3423, 3435.34E-5)
+ INSTR_* - IL instructions of a particular class (see opcode.def).
+ HEXBYTE - 1- or 2-digit hexadecimal number (e.g., A2, F0).
+Auxiliary lexical tokens
+ TYPEDEF_T - Aliased class (TypeDef or TypeRef).
+ TYPEDEF_M - Aliased method.
+ TYPEDEF_F - Aliased field.
+ TYPEDEF_TS - Aliased type specification (TypeSpec).
+ TYPEDEF_MR - Aliased field/method reference (MemberRef).
+ TYPEDEF_CA - Aliased Custom Attribute.
+----------------------------------------------------------------------------------
+START : decls
+ ;
+
+decls : /* EMPTY */
+ | decls decl
+ ;
+/* Module-level declarations */
+decl : classHead '{' classDecls '}'
+ | nameSpaceHead '{' decls '}'
+ | methodHead methodDecls '}'
+ | fieldDecl
+ | dataDecl
+ | vtableDecl
+ | vtfixupDecl
+ | extSourceSpec
+ | fileDecl
+ | assemblyHead '{' assemblyDecls '}'
+ | assemblyRefHead '{' assemblyRefDecls '}'
+ | exptypeHead '{' exptypeDecls '}'
+ | manifestResHead '{' manifestResDecls '}'
+ | moduleHead
+ | secDecl
+ | customAttrDecl
+ | '.subsystem' int32
+ | '.corflags' int32
+ | '.file' 'alignment' int32
+ | '.imagebase' int64
+ | '.stackreserve' int64
+ | languageDecl
+ | typedefDecl
+ | compControl
+ | '.typelist' '{' classNameSeq '}'
+ | '.mscorlib'
+ ;
+
+classNameSeq : /* EMPTY */
+ | className classNameSeq
+ ;
+
+compQstring : QSTRING
+ | compQstring '+' QSTRING
+ ;
+
+languageDecl : '.language' SQSTRING
+ | '.language' SQSTRING ',' SQSTRING
+ | '.language' SQSTRING ',' SQSTRING ',' SQSTRING
+ ;
+/* Basic tokens */
+id : ID
+ | SQSTRING
+ ;
+
+dottedName : id
+ | DOTTEDNAME
+ | dottedName '.' dottedName
+ ;
+
+int32 : INT32
+ ;
+
+int64 : INT64
+ | INT32
+ ;
+
+float64 : FLOAT64
+ | 'float32' '(' int32 ')'
+ | 'float64' '(' int64 ')'
+ ;
+
+/* Aliasing of types, type specs, methods, fields and custom attributes */
+typedefDecl : '.typedef' type 'as' dottedName
+ | '.typedef' className 'as' dottedName
+ | '.typedef' memberRef 'as' dottedName
+ | '.typedef' customDescr 'as' dottedName
+ | '.typedef' customDescrWithOwner 'as' dottedName
+ ;
+
+/* Compilation control directives are processed within yylex(),
+ displayed here just for grammar completeness */
+compControl : P_DEFINE dottedName
+ | P_DEFINE dottedName compQstring
+ | P_UNDEF dottedName
+ | P_IFDEF dottedName
+ | P_IFNDEF dottedName
+ | P_ELSE
+ | P_ENDIF
+ | P_INCLUDE QSTRING
+ | ';'
+ ;
+
+/* Custom attribute declarations */
+customDescr : '.custom' customType
+ | '.custom' customType '=' compQstring
+ | '.custom' customType '=' '{' customBlobDescr '}'
+ | customHead bytes ')'
+ ;
+
+customDescrWithOwner : '.custom' '(' ownerType ')' customType
+ | '.custom' '(' ownerType ')' customType '=' compQstring
+ | '.custom' '(' ownerType ')' customType '=' '{' customBlobDescr '}'
+ | customHeadWithOwner bytes ')'
+ ;
+
+customHead : '.custom' customType '=' '('
+ ;
+
+customHeadWithOwner : '.custom' '(' ownerType ')' customType '=' '('
+ ;
+
+customType : methodRef
+ ;
+
+ownerType : typeSpec
+ | memberRef
+ ;
+
+/* Verbal description of custom attribute initialization blob */
+customBlobDescr : customBlobArgs customBlobNVPairs
+ ;
+
+customBlobArgs : /* EMPTY */
+ | customBlobArgs serInit
+ | customBlobArgs compControl
+ ;
+
+customBlobNVPairs : /* EMPTY */
+ | customBlobNVPairs fieldOrProp serializType dottedName '=' serInit
+ | customBlobNVPairs compControl
+ ;
+
+fieldOrProp : 'field'
+ | 'property'
+ ;
+
+customAttrDecl : customDescr
+ | customDescrWithOwner
+ | TYPEDEF_CA
+ ;
+
+serializType : simpleType
+ | 'type'
+ | 'object'
+ | 'enum' 'class' SQSTRING
+ | 'enum' className
+ | serializType '[' ']'
+ ;
+
+
+/* Module declaration */
+moduleHead : '.module'
+ | '.module' dottedName
+ | '.module' 'extern' dottedName
+ ;
+
+/* VTable Fixup table declaration */
+vtfixupDecl : '.vtfixup' '[' int32 ']' vtfixupAttr 'at' id
+ ;
+
+vtfixupAttr : /* EMPTY */
+ | vtfixupAttr 'int32'
+ | vtfixupAttr 'int64'
+ | vtfixupAttr 'fromunmanaged'
+ | vtfixupAttr 'callmostderived'
+ | vtfixupAttr 'retainappdomain'
+ ;
+
+vtableDecl : vtableHead bytes ')' /* deprecated */
+ ;
+
+vtableHead : '.vtable' '=' '(' /* deprecated */
+ ;
+
+/* Namespace and class declaration */
+nameSpaceHead : '.namespace' dottedName
+ ;
+
+_class : '.class'
+ ;
+
+classHeadBegin : _class classAttr dottedName typarsClause
+ ;
+classHead : classHeadBegin extendsClause implClause
+ ;
+
+classAttr : /* EMPTY */
+ | classAttr 'public'
+ | classAttr 'private'
+ | classAttr 'value'
+ | classAttr 'enum'
+ | classAttr 'interface'
+ | classAttr 'sealed'
+ | classAttr 'abstract'
+ | classAttr 'auto'
+ | classAttr 'sequential'
+ | classAttr 'explicit'
+ | classAttr 'ansi'
+ | classAttr 'unicode'
+ | classAttr 'autochar'
+ | classAttr 'import'
+ | classAttr 'serializable'
+ | classAttr 'windowsruntime'
+ | classAttr 'nested' 'public'
+ | classAttr 'nested' 'private'
+ | classAttr 'nested' 'family'
+ | classAttr 'nested' 'assembly'
+ | classAttr 'nested' 'famandassem'
+ | classAttr 'nested' 'famorassem'
+ | classAttr 'beforefieldinit'
+ | classAttr 'specialname'
+ | classAttr 'rtspecialname'
+ | classAttr 'flags' '(' int32 ')'
+ ;
+
+extendsClause : /* EMPTY */
+ | 'extends' typeSpec
+ ;
+
+implClause : /* EMPTY */
+ | 'implements' implList
+ ;
+
+classDecls : /* EMPTY */
+ | classDecls classDecl
+ ;
+
+implList : implList ',' typeSpec
+ | typeSpec
+ ;
+
+/* Generic type parameters declaration */
+typeList : /* EMPTY */
+ | typeListNotEmpty
+ ;
+
+typeListNotEmpty : typeSpec
+ | typeListNotEmpty ',' typeSpec
+ ;
+
+typarsClause : /* EMPTY */
+ | '<' typars '>'
+ ;
+
+typarAttrib : '+'
+ | '-'
+ | 'class'
+ | 'valuetype'
+ | '.ctor'
+ ;
+
+typarAttribs : /* EMPTY */
+ | typarAttrib typarAttribs
+ ;
+
+typars : typarAttribs tyBound dottedName typarsRest
+ | typarAttribs dottedName typarsRest
+ ;
+
+typarsRest : /* EMPTY */
+ | ',' typars
+ ;
+
+tyBound : '(' typeList ')'
+ ;
+
+genArity : /* EMPTY */
+ | genArityNotEmpty
+ ;
+
+genArityNotEmpty : '<' '[' int32 ']' '>'
+ ;
+
+/* Class body declarations */
+classDecl : methodHead methodDecls '}'
+ | classHead '{' classDecls '}'
+ | eventHead '{' eventDecls '}'
+ | propHead '{' propDecls '}'
+ | fieldDecl
+ | dataDecl
+ | secDecl
+ | extSourceSpec
+ | customAttrDecl
+ | '.size' int32
+ | '.pack' int32
+ | exportHead '{' exptypeDecls '}'
+ | '.override' typeSpec '::' methodName 'with' callConv type typeSpec '::' methodName '(' sigArgs0 ')'
+ | '.override' 'method' callConv type typeSpec '::' methodName genArity '(' sigArgs0 ')' 'with' 'method' callConv type typeSpec '::' methodName genArity '(' sigArgs0 ')'
+ | languageDecl
+ | compControl
+ | '.param' 'type' '[' int32 ']'
+ | '.param' 'type' dottedName
+ | '.param' 'constraint' '[' int32 ']' ',' typeSpec
+ | '.param' 'constraint' dottedName ',' typeSpec
+ | '.interfaceimpl' 'type' typeSpec customDescr
+ ;
+
+/* Field declaration */
+fieldDecl : '.field' repeatOpt fieldAttr type dottedName atOpt initOpt
+ ;
+
+fieldAttr : /* EMPTY */
+ | fieldAttr 'static'
+ | fieldAttr 'public'
+ | fieldAttr 'private'
+ | fieldAttr 'family'
+ | fieldAttr 'initonly'
+ | fieldAttr 'rtspecialname' /**/
+ | fieldAttr 'specialname'
+ /* <STRIP>commented out because PInvoke for fields is not supported by EE
+ | fieldAttr 'pinvokeimpl' '(' compQstring 'as' compQstring pinvAttr ')'
+ | fieldAttr 'pinvokeimpl' '(' compQstring pinvAttr ')'
+ | fieldAttr 'pinvokeimpl' '(' pinvAttr ')'
+ </STRIP>*/
+ | fieldAttr 'marshal' '(' marshalBlob ')'
+ | fieldAttr 'assembly'
+ | fieldAttr 'famandassem'
+ | fieldAttr 'famorassem'
+ | fieldAttr 'privatescope'
+ | fieldAttr 'literal'
+ | fieldAttr 'notserialized'
+ | fieldAttr 'flags' '(' int32 ')'
+ ;
+
+atOpt : /* EMPTY */
+ | 'at' id
+ ;
+
+initOpt : /* EMPTY */
+ | '=' fieldInit
+ ;
+
+repeatOpt : /* EMPTY */
+ | '[' int32 ']'
+ ;
+
+/* Method referencing */
+methodRef : callConv type typeSpec '::' methodName tyArgs0 '(' sigArgs0 ')'
+ | callConv type typeSpec '::' methodName genArityNotEmpty '(' sigArgs0 ')'
+ | callConv type methodName tyArgs0 '(' sigArgs0 ')'
+ | callConv type methodName genArityNotEmpty '(' sigArgs0 ')'
+ | mdtoken
+ | TYPEDEF_M
+ | TYPEDEF_MR
+ ;
+
+callConv : 'instance' callConv
+ | 'explicit' callConv
+ | callKind
+ | 'callconv' '(' int32 ')'
+ ;
+
+callKind : /* EMPTY */
+ | 'default'
+ | 'vararg'
+ | 'unmanaged' 'cdecl'
+ | 'unmanaged' 'stdcall'
+ | 'unmanaged' 'thiscall'
+ | 'unmanaged' 'fastcall'
+ | 'unmanaged'
+ ;
+
+mdtoken : 'mdtoken' '(' int32 ')'
+ ;
+
+memberRef : methodSpec methodRef
+ | 'field' type typeSpec '::' dottedName
+ | 'field' type dottedName
+ | 'field' TYPEDEF_F
+ | 'field' TYPEDEF_MR
+ | mdtoken
+ ;
+
+/* Event declaration */
+eventHead : '.event' eventAttr typeSpec dottedName
+ | '.event' eventAttr dottedName
+ ;
+
+
+eventAttr : /* EMPTY */
+ | eventAttr 'rtspecialname' /**/
+ | eventAttr 'specialname'
+ ;
+
+eventDecls : /* EMPTY */
+ | eventDecls eventDecl
+ ;
+
+eventDecl : '.addon' methodRef
+ | '.removeon' methodRef
+ | '.fire' methodRef
+ | '.other' methodRef
+ | extSourceSpec
+ | customAttrDecl
+ | languageDecl
+ | compControl
+ ;
+
+/* Property declaration */
+propHead : '.property' propAttr callConv type dottedName '(' sigArgs0 ')' initOpt
+ ;
+
+propAttr : /* EMPTY */
+ | propAttr 'rtspecialname' /**/
+ | propAttr 'specialname'
+ ;
+
+propDecls : /* EMPTY */
+ | propDecls propDecl
+ ;
+
+
+propDecl : '.set' methodRef
+ | '.get' methodRef
+ | '.other' methodRef
+ | customAttrDecl
+ | extSourceSpec
+ | languageDecl
+ | compControl
+ ;
+
+/* Method declaration */
+methodHeadPart1 : '.method'
+ ;
+
+marshalClause : /* EMPTY */
+ | 'marshal' '(' marshalBlob ')'
+ ;
+
+marshalBlob : nativeType
+ | marshalBlobHead hexbytes '}'
+ ;
+
+marshalBlobHead : '{'
+ ;
+
+methodHead : methodHeadPart1 methAttr callConv paramAttr type marshalClause methodName typarsClause'(' sigArgs0 ')' implAttr '{'
+ ;
+
+methAttr : /* EMPTY */
+ | methAttr 'static'
+ | methAttr 'public'
+ | methAttr 'private'
+ | methAttr 'family'
+ | methAttr 'final'
+ | methAttr 'specialname'
+ | methAttr 'virtual'
+ | methAttr 'strict'
+ | methAttr 'abstract'
+ | methAttr 'assembly'
+ | methAttr 'famandassem'
+ | methAttr 'famorassem'
+ | methAttr 'privatescope'
+ | methAttr 'hidebysig'
+ | methAttr 'newslot'
+ | methAttr 'rtspecialname' /**/
+ | methAttr 'unmanagedexp'
+ | methAttr 'reqsecobj'
+ | methAttr 'flags' '(' int32 ')'
+ | methAttr 'pinvokeimpl' '(' compQstring 'as' compQstring pinvAttr ')'
+ | methAttr 'pinvokeimpl' '(' compQstring pinvAttr ')'
+ | methAttr 'pinvokeimpl' '(' pinvAttr ')'
+ ;
+
+pinvAttr : /* EMPTY */
+ | pinvAttr 'nomangle'
+ | pinvAttr 'ansi'
+ | pinvAttr 'unicode'
+ | pinvAttr 'autochar'
+ | pinvAttr 'lasterr'
+ | pinvAttr 'winapi'
+ | pinvAttr 'cdecl'
+ | pinvAttr 'stdcall'
+ | pinvAttr 'thiscall'
+ | pinvAttr 'fastcall'
+ | pinvAttr 'bestfit' ':' 'on'
+ | pinvAttr 'bestfit' ':' 'off'
+ | pinvAttr 'charmaperror' ':' 'on'
+ | pinvAttr 'charmaperror' ':' 'off'
+ | pinvAttr 'flags' '(' int32 ')'
+ ;
+
+methodName : '.ctor'
+ | '.cctor'
+ | dottedName
+ ;
+
+paramAttr : /* EMPTY */
+ | paramAttr '[' 'in' ']'
+ | paramAttr '[' 'out' ']'
+ | paramAttr '[' 'opt' ']'
+ | paramAttr '[' int32 ']'
+ ;
+
+implAttr : /* EMPTY */
+ | implAttr 'native'
+ | implAttr 'cil'
+ | implAttr 'optil'
+ | implAttr 'managed'
+ | implAttr 'unmanaged'
+ | implAttr 'forwardref'
+ | implAttr 'preservesig'
+ | implAttr 'runtime'
+ | implAttr 'internalcall'
+ | implAttr 'synchronized'
+ | implAttr 'noinlining'
+ | implAttr 'aggressiveinlining'
+ | implAttr 'nooptimization'
+ | implAttr 'aggressiveoptimization'
+ | implAttr 'flags' '(' int32 ')'
+ ;
+
+localsHead : '.locals'
+ ;
+
+methodDecls : /* EMPTY */
+ | methodDecls methodDecl
+ ;
+
+methodDecl : '.emitbyte' int32
+ | sehBlock
+ | '.maxstack' int32
+ | localsHead '(' sigArgs0 ')'
+ | localsHead 'init' '(' sigArgs0 ')'
+ | '.entrypoint'
+ | '.zeroinit'
+ | dataDecl
+ | instr
+ | id ':'
+ | secDecl
+ | extSourceSpec
+ | languageDecl
+ | customAttrDecl
+ | compControl
+ | '.export' '[' int32 ']'
+ | '.export' '[' int32 ']' 'as' id
+ | '.vtentry' int32 ':' int32
+ | '.override' typeSpec '::' methodName
+
+ | '.override' 'method' callConv type typeSpec '::' methodName genArity '(' sigArgs0 ')'
+ | scopeBlock
+ | '.param' 'type' '[' int32 ']'
+ | '.param' 'type' dottedName
+ | '.param' 'constraint' '[' int32 ']' ',' typeSpec
+ | '.param' 'constraint' dottedName ',' typeSpec
+
+ | '.param' '[' int32 ']' initOpt
+ ;
+
+scopeBlock : scopeOpen methodDecls '}'
+ ;
+
+scopeOpen : '{'
+ ;
+
+/* Structured exception handling directives */
+sehBlock : tryBlock sehClauses
+ ;
+
+sehClauses : sehClause sehClauses
+ | sehClause
+ ;
+
+tryBlock : tryHead scopeBlock
+ | tryHead id 'to' id
+ | tryHead int32 'to' int32
+ ;
+
+tryHead : '.try'
+ ;
+
+
+sehClause : catchClause handlerBlock
+ | filterClause handlerBlock
+ | finallyClause handlerBlock
+ | faultClause handlerBlock
+ ;
+
+
+filterClause : filterHead scopeBlock
+ | filterHead id
+ | filterHead int32
+ ;
+
+filterHead : 'filter'
+ ;
+
+catchClause : 'catch' typeSpec
+ ;
+
+finallyClause : 'finally'
+ ;
+
+faultClause : 'fault'
+ ;
+
+handlerBlock : scopeBlock
+ | 'handler' id 'to' id
+ | 'handler' int32 'to' int32
+ ;
+
+/* Data declaration */
+dataDecl : ddHead ddBody
+ ;
+
+ddHead : '.data' tls id '='
+ | '.data' tls
+ ;
+
+tls : /* EMPTY */
+ | 'tls'
+ | 'cil'
+ ;
+
+ddBody : '{' ddItemList '}'
+ | ddItem
+ ;
+
+ddItemList : ddItem ',' ddItemList
+ | ddItem
+ ;
+
+ddItemCount : /* EMPTY */
+ | '[' int32 ']'
+ ;
+
+ddItem : 'char' '*' '(' compQstring ')'
+ | '&' '(' id ')'
+ | bytearrayhead bytes ')'
+ | 'float32' '(' float64 ')' ddItemCount
+ | 'float64' '(' float64 ')' ddItemCount
+ | 'int64' '(' int64 ')' ddItemCount
+ | 'int32' '(' int32 ')' ddItemCount
+ | 'int16' '(' int32 ')' ddItemCount
+ | 'int8' '(' int32 ')' ddItemCount
+ | 'float32' ddItemCount
+ | 'float64' ddItemCount
+ | 'int64' ddItemCount
+ | 'int32' ddItemCount
+ | 'int16' ddItemCount
+ | 'int8' ddItemCount
+ ;
+
+/* Default values declaration for fields, parameters and verbal form of CA blob description */
+fieldSerInit : 'float32' '(' float64 ')'
+ | 'float64' '(' float64 ')'
+ | 'float32' '(' int32 ')'
+ | 'float64' '(' int64 ')'
+ | 'int64' '(' int64 ')'
+ | 'int32' '(' int32 ')'
+ | 'int16' '(' int32 ')'
+ | 'int8' '(' int32 ')'
+ | 'unsigned' 'int64' '(' int64 ')'
+ | 'unsigned' 'int32' '(' int32 ')'
+ | 'unsigned' 'int16' '(' int32 ')'
+ | 'unsigned' 'int8' '(' int32 ')'
+ | 'uint64' '(' int64 ')'
+ | 'uint32' '(' int32 ')'
+ | 'uint16' '(' int32 ')'
+ | 'uint8' '(' int32 ')'
+ | 'char' '(' int32 ')'
+ | 'bool' '(' truefalse ')'
+ | bytearrayhead bytes ')'
+ ;
+
+bytearrayhead : 'bytearray' '('
+ ;
+
+bytes : /* EMPTY */
+ | hexbytes
+ ;
+
+hexbytes : HEXBYTE
+ | hexbytes HEXBYTE
+ ;
+
+/* Field/parameter initialization */
+fieldInit : fieldSerInit
+ | compQstring
+ | 'nullref'
+ ;
+
+/* Values for verbal form of CA blob description */
+serInit : fieldSerInit
+ | 'string' '(' 'nullref' ')'
+ | 'string' '(' SQSTRING ')'
+ | 'type' '(' 'class' SQSTRING ')'
+ | 'type' '(' className ')'
+ | 'type' '(' 'nullref' ')'
+ | 'object' '(' serInit ')'
+ | 'float32' '[' int32 ']' '(' f32seq ')'
+ | 'float64' '[' int32 ']' '(' f64seq ')'
+ | 'int64' '[' int32 ']' '(' i64seq ')'
+ | 'int32' '[' int32 ']' '(' i32seq ')'
+ | 'int16' '[' int32 ']' '(' i16seq ')'
+ | 'int8' '[' int32 ']' '(' i8seq ')'
+ | 'uint64' '[' int32 ']' '(' i64seq ')'
+ | 'uint32' '[' int32 ']' '(' i32seq ')'
+ | 'uint16' '[' int32 ']' '(' i16seq ')'
+ | 'uint8' '[' int32 ']' '(' i8seq ')'
+ | 'unsigned' 'int64' '[' int32 ']' '(' i64seq ')'
+ | 'unsigned' 'int32' '[' int32 ']' '(' i32seq ')'
+ | 'unsigned' 'int16' '[' int32 ']' '(' i16seq ')'
+ | 'unsigned' 'int8' '[' int32 ']' '(' i8seq ')'
+ | 'char' '[' int32 ']' '(' i16seq ')'
+ | 'bool' '[' int32 ']' '(' boolSeq ')'
+ | 'string' '[' int32 ']' '(' sqstringSeq ')'
+ | 'type' '[' int32 ']' '(' classSeq ')'
+ | 'object' '[' int32 ']' '(' objSeq ')'
+ ;
+
+
+f32seq : /* EMPTY */
+ | f32seq float64
+ | f32seq int32
+ ;
+
+f64seq : /* EMPTY */
+ | f64seq float64
+ | f64seq int64
+ ;
+
+i64seq : /* EMPTY */
+ | i64seq int64
+ ;
+
+i32seq : /* EMPTY */
+ | i32seq int32
+ ;
+
+i16seq : /* EMPTY */
+ | i16seq int32
+ ;
+
+i8seq : /* EMPTY */
+ | i8seq int32
+ ;
+
+boolSeq : /* EMPTY */
+ | boolSeq truefalse
+ ;
+
+sqstringSeq : /* EMPTY */
+ | sqstringSeq 'nullref'
+ | sqstringSeq SQSTRING
+ ;
+
+classSeq : /* EMPTY */
+ | classSeq 'nullref'
+ | classSeq 'class' SQSTRING
+ | classSeq className
+ ;
+
+objSeq : /* EMPTY */
+ | objSeq serInit
+ ;
+
+/* IL instructions and associated definitions */
+methodSpec : 'method'
+ ;
+
+instr_none : INSTR_NONE
+ ;
+
+instr_var : INSTR_VAR
+ ;
+
+instr_i : INSTR_I
+ ;
+
+instr_i8 : INSTR_I8
+ ;
+
+instr_r : INSTR_R
+ ;
+
+instr_brtarget : INSTR_BRTARGET
+ ;
+
+instr_method : INSTR_METHOD
+ ;
+
+instr_field : INSTR_FIELD
+ ;
+
+instr_type : INSTR_TYPE
+ ;
+
+instr_string : INSTR_STRING
+ ;
+
+instr_sig : INSTR_SIG
+ ;
+
+instr_tok : INSTR_TOK
+ ;
+
+instr_switch : INSTR_SWITCH
+ ;
+
+instr_r_head : instr_r '('
+ ;
+
+
+instr : instr_none
+ | instr_var int32
+ | instr_var id
+ | instr_i int32
+ | instr_i8 int64
+ | instr_r float64
+ | instr_r int64
+ | instr_r_head bytes ')'
+ | instr_brtarget int32
+ | instr_brtarget id
+ | instr_method methodRef
+ | instr_field type typeSpec '::' dottedName
+ | instr_field type dottedName
+ | instr_field mdtoken
+ | instr_field TYPEDEF_F
+ | instr_field TYPEDEF_MR
+ | instr_type typeSpec
+ | instr_string compQstring
+ | instr_string 'ansi' '(' compQstring ')'
+ | instr_string bytearrayhead bytes ')'
+ | instr_sig callConv type '(' sigArgs0 ')'
+ | instr_tok ownerType /* ownerType ::= memberRef | typeSpec */
+ | instr_switch '(' labels ')'
+ ;
+
+labels : /* empty */
+ | id ',' labels
+ | int32 ',' labels
+ | id
+ | int32
+ ;
+
+/* Signatures */
+tyArgs0 : /* EMPTY */
+ | '<' tyArgs1 '>'
+ ;
+
+tyArgs1 : /* EMPTY */
+ | tyArgs2
+ ;
+
+tyArgs2 : type
+ | tyArgs2 ',' type
+ ;
+
+
+sigArgs0 : /* EMPTY */
+ | sigArgs1
+ ;
+
+sigArgs1 : sigArg
+ | sigArgs1 ',' sigArg
+ ;
+
+sigArg : '...'
+ | paramAttr type marshalClause
+ | paramAttr type marshalClause id
+ ;
+
+/* Class referencing */
+className : '[' dottedName ']' slashedName
+ | '[' mdtoken ']' slashedName
+ | '[' '*' ']' slashedName
+ | '[' '.module' dottedName ']' slashedName
+ | slashedName
+ | mdtoken
+ | TYPEDEF_T
+ | '.this'
+ | '.base'
+ | '.nester'
+ ;
+
+slashedName : dottedName
+ | slashedName '/' dottedName
+ ;
+
+typeSpec : className
+ | '[' dottedName ']'
+ | '[' '.module' dottedName ']'
+ | type
+ ;
+
+/* Native types for marshaling signatures */
+nativeType : /* EMPTY */
+ | 'custom' '(' compQstring ',' compQstring ',' compQstring ',' compQstring ')'
+ | 'custom' '(' compQstring ',' compQstring ')'
+ | 'fixed' 'sysstring' '[' int32 ']'
+ | 'fixed' 'array' '[' int32 ']' nativeType
+ | 'variant'
+ | 'currency'
+ | 'syschar'
+ | 'void'
+ | 'bool'
+ | 'int8'
+ | 'int16'
+ | 'int32'
+ | 'int64'
+ | 'float32'
+ | 'float64'
+ | 'error'
+ | 'unsigned' 'int8'
+ | 'unsigned' 'int16'
+ | 'unsigned' 'int32'
+ | 'unsigned' 'int64'
+ | 'uint8'
+ | 'uint16'
+ | 'uint32'
+ | 'uint64'
+ | nativeType '*'
+ | nativeType '[' ']'
+ | nativeType '[' int32 ']'
+ | nativeType '[' int32 '+' int32 ']'
+ | nativeType '[' '+' int32 ']'
+ | 'decimal'
+ | 'date'
+ | 'bstr'
+ | 'lpstr'
+ | 'lpwstr'
+ | 'lptstr'
+ | 'objectref'
+ | 'iunknown' iidParamIndex
+ | 'idispatch' iidParamIndex
+ | 'struct'
+ | 'interface' iidParamIndex
+ | 'safearray' variantType
+ | 'safearray' variantType ',' compQstring
+
+ | 'int'
+ | 'unsigned' 'int'
+ | 'uint'
+ | 'nested' 'struct'
+ | 'byvalstr'
+ | 'ansi' 'bstr'
+ | 'tbstr'
+ | 'variant' 'bool'
+ | 'method'
+ | 'as' 'any'
+ | 'lpstruct'
+ | TYPEDEF_TS
+ ;
+
+iidParamIndex : /* EMPTY */
+ | '(' 'iidparam' '=' int32 ')'
+ ;
+
+variantType : /* EMPTY */
+ | 'null'
+ | 'variant'
+ | 'currency'
+ | 'void'
+ | 'bool'
+ | 'int8'
+ | 'int16'
+ | 'int32'
+ | 'int64'
+ | 'float32'
+ | 'float64'
+ | 'unsigned' 'int8'
+ | 'unsigned' 'int16'
+ | 'unsigned' 'int32'
+ | 'unsigned' 'int64'
+ | 'uint8'
+ | 'uint16'
+ | 'uint32'
+ | 'uint64'
+ | '*'
+ | variantType '[' ']'
+ | variantType 'vector'
+ | variantType '&'
+ | 'decimal'
+ | 'date'
+ | 'bstr'
+ | 'lpstr'
+ | 'lpwstr'
+ | 'iunknown'
+ | 'idispatch'
+ | 'safearray'
+ | 'int'
+ | 'unsigned' 'int'
+ | 'uint'
+ | 'error'
+ | 'hresult'
+ | 'carray'
+ | 'userdefined'
+ | 'record'
+ | 'filetime'
+ | 'blob'
+ | 'stream'
+ | 'storage'
+ | 'streamed_object'
+ | 'stored_object'
+ | 'blob_object'
+ | 'cf'
+ | 'clsid'
+ ;
+
+/* Managed types for signatures */
+type : 'class' className
+ | 'object'
+ | 'value' 'class' className
+ | 'valuetype' className
+ | type '[' ']'
+ | type '[' bounds1 ']'
+ | type '&'
+ | type '*'
+ | type 'pinned'
+ | type 'modreq' '(' typeSpec ')'
+ | type 'modopt' '(' typeSpec ')'
+ | methodSpec callConv type '*' '(' sigArgs0 ')'
+ | type '<' tyArgs1 '>'
+ | '!' '!' int32
+ | '!' int32
+ | '!' '!' dottedName
+ | '!' dottedName
+ | 'typedref'
+ | 'void'
+ | 'native' 'int'
+ | 'native' 'unsigned' 'int'
+ | 'native' 'uint'
+ | simpleType
+ | '...' type
+ ;
+
+simpleType : 'char'
+ | 'string'
+ | 'bool'
+ | 'int8'
+ | 'int16'
+ | 'int32'
+ | 'int64'
+ | 'float32'
+ | 'float64'
+ | 'unsigned' 'int8'
+ | 'unsigned' 'int16'
+ | 'unsigned' 'int32'
+ | 'unsigned' 'int64'
+ | 'uint8'
+ | 'uint16'
+ | 'uint32'
+ | 'uint64'
+ | TYPEDEF_TS
+ ;
+
+bounds1 : bound
+ | bounds1 ',' bound
+ ;
+
+bound : /* EMPTY */
+ | '...'
+ | int32
+ | int32 '...' int32
+ | int32 '...'
+ ;
+
+/* Security declarations */
+secDecl : '.permission' secAction typeSpec '(' nameValPairs ')'
+ | '.permission' secAction typeSpec '=' '{' customBlobDescr '}'
+ | '.permission' secAction typeSpec
+ | psetHead bytes ')'
+ | '.permissionset' secAction compQstring
+ | '.permissionset' secAction '=' '{' secAttrSetBlob '}'
+ ;
+
+secAttrSetBlob : /* EMPTY */
+ | secAttrBlob
+ | secAttrBlob ',' secAttrSetBlob
+ ;
+
+secAttrBlob : typeSpec '=' '{' customBlobNVPairs '}'
+ | 'class' SQSTRING '=' '{' customBlobNVPairs '}'
+ ;
+
+psetHead : '.permissionset' secAction '=' '('
+ | '.permissionset' secAction 'bytearray' '('
+ ;
+
+nameValPairs : nameValPair
+ | nameValPair ',' nameValPairs
+ ;
+
+nameValPair : compQstring '=' caValue
+ ;
+
+truefalse : 'true'
+ | 'false'
+ ;
+
+caValue : truefalse
+ | int32
+ | 'int32' '(' int32 ')'
+ | compQstring
+ | className '(' 'int8' ':' int32 ')'
+ | className '(' 'int16' ':' int32 ')'
+ | className '(' 'int32' ':' int32 ')'
+ | className '(' int32 ')'
+ ;
+
+secAction : 'request'
+ | 'demand'
+ | 'assert'
+ | 'deny'
+ | 'permitonly'
+ | 'linkcheck'
+ | 'inheritcheck'
+ | 'reqmin'
+ | 'reqopt'
+ | 'reqrefuse'
+ | 'prejitgrant'
+ | 'prejitdeny'
+ | 'noncasdemand'
+ | 'noncaslinkdemand'
+ | 'noncasinheritance'
+ ;
+
+/* External source declarations */
+esHead : '.line'
+ | P_LINE
+ ;
+
+extSourceSpec : esHead int32 SQSTRING
+ | esHead int32
+ | esHead int32 ':' int32 SQSTRING
+ | esHead int32 ':' int32
+ | esHead int32 ':' int32 ',' int32 SQSTRING
+ | esHead int32 ':' int32 ',' int32
+ | esHead int32 ',' int32 ':' int32 SQSTRING
+ | esHead int32 ',' int32 ':' int32
+ | esHead int32 ',' int32 ':' int32 ',' int32 SQSTRING
+ | esHead int32 ',' int32 ':' int32 ',' int32
+ | esHead int32 QSTRING
+ ;
+
+/* Manifest declarations */
+fileDecl : '.file' fileAttr dottedName fileEntry hashHead bytes ')' fileEntry
+ | '.file' fileAttr dottedName fileEntry
+ ;
+
+fileAttr : /* EMPTY */
+ | fileAttr 'nometadata'
+ ;
+
+fileEntry : /* EMPTY */
+ | '.entrypoint'
+ ;
+
+hashHead : '.hash' '=' '('
+ ;
+
+assemblyHead : '.assembly' asmAttr dottedName
+ ;
+
+asmAttr : /* EMPTY */
+ | asmAttr 'retargetable'
+ | asmAttr 'windowsruntime'
+ | asmAttr 'noplatform'
+ | asmAttr 'legacy' 'library'
+ | asmAttr 'cil'
+ | asmAttr 'x86'
+ | asmAttr 'amd64'
+ | asmAttr 'arm'
+ | asmAttr 'arm64'
+ ;
+
+assemblyDecls : /* EMPTY */
+ | assemblyDecls assemblyDecl
+ ;
+
+assemblyDecl : '.hash' 'algorithm' int32
+ | secDecl
+ | asmOrRefDecl
+ ;
+
+intOrWildcard : int32
+ | '*'
+ ;
+
+asmOrRefDecl : publicKeyHead bytes ')'
+ | '.ver' intOrWildcard ':' intOrWildcard ':' intOrWildcard ':' intOrWildcard
+ | '.locale' compQstring
+ | localeHead bytes ')'
+ | customAttrDecl
+ | compControl
+ ;
+
+publicKeyHead : '.publickey' '=' '('
+ ;
+
+publicKeyTokenHead : '.publickeytoken' '=' '('
+ ;
+
+localeHead : '.locale' '=' '('
+ ;
+
+assemblyRefHead : '.assembly' 'extern' asmAttr dottedName
+ | '.assembly' 'extern' asmAttr dottedName 'as' dottedName
+ ;
+
+assemblyRefDecls : /* EMPTY */
+ | assemblyRefDecls assemblyRefDecl
+ ;
+
+assemblyRefDecl : hashHead bytes ')'
+ | asmOrRefDecl
+ | publicKeyTokenHead bytes ')'
+ | 'auto'
+ ;
+
+exptypeHead : '.class' 'extern' exptAttr dottedName
+ ;
+
+exportHead : '.export' exptAttr dottedName /* deprecated */
+ ;
+
+exptAttr : /* EMPTY */
+ | exptAttr 'private'
+ | exptAttr 'public'
+ | exptAttr 'forwarder'
+ | exptAttr 'nested' 'public'
+ | exptAttr 'nested' 'private'
+ | exptAttr 'nested' 'family'
+ | exptAttr 'nested' 'assembly'
+ | exptAttr 'nested' 'famandassem'
+ | exptAttr 'nested' 'famorassem'
+ ;
+
+exptypeDecls : /* EMPTY */
+ | exptypeDecls exptypeDecl
+ ;
+
+exptypeDecl : '.file' dottedName
+ | '.class' 'extern' slashedName
+ | '.assembly' 'extern' dottedName
+ | 'mdtoken' '(' int32 ')'
+ | '.class' int32
+ | customAttrDecl
+ | compControl
+ ;
+
+manifestResHead : '.mresource' manresAttr dottedName
+ | '.mresource' manresAttr dottedName 'as' dottedName
+ ;
+
+manresAttr : /* EMPTY */
+ | manresAttr 'public'
+ | manresAttr 'private'
+ ;
+
+manifestResDecls : /* EMPTY */
+ | manifestResDecls manifestResDecl
+ ;
+
+manifestResDecl : '.file' dottedName 'at' int32
+ | '.assembly' 'extern' dottedName
+ | customAttrDecl
+ | compControl
+ ;
+
diff --git a/src/coreclr/ilasm/typar.hpp b/src/coreclr/ilasm/typar.hpp
new file mode 100644
index 00000000000..aee0c32c452
--- /dev/null
+++ b/src/coreclr/ilasm/typar.hpp
@@ -0,0 +1,182 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+/**************************************************************************/
+/* a type parameter list */
+
+#ifndef TYPAR_H
+#define TYPAR_H
+#include "binstr.h"
+
+extern unsigned int g_uCodePage;
+
+class TyParDescr
+{
+public:
+ TyParDescr()
+ {
+ m_pbsBounds = NULL;
+ m_wzName = NULL;
+ m_dwAttrs = 0;
+ };
+ ~TyParDescr()
+ {
+ delete m_pbsBounds;
+ delete [] m_wzName;
+ m_lstCA.RESET(true);
+ };
+ void Init(BinStr* bounds, LPCUTF8 name, DWORD attrs)
+ {
+ m_pbsBounds = bounds;
+ ULONG cTemp = (ULONG)strlen(name)+1;
+ WCHAR *pwzName;
+ m_wzName = pwzName = new WCHAR[cTemp];
+ if(pwzName)
+ {
+ memset(pwzName,0,sizeof(WCHAR)*cTemp);
+ WszMultiByteToWideChar(g_uCodePage,0,name,-1,pwzName,cTemp);
+ }
+ m_dwAttrs = attrs;
+ };
+ BinStr* Bounds() { return m_pbsBounds; };
+ LPCWSTR Name() { return m_wzName; };
+ DWORD Attrs() { return m_dwAttrs; };
+ mdToken Token() { return m_token; };
+ void Token(mdToken value)
+ {
+ m_token = value;
+ };
+ CustomDescrList* CAList() { return &m_lstCA; };
+
+private:
+ BinStr* m_pbsBounds;
+ LPCWSTR m_wzName;
+ DWORD m_dwAttrs;
+ mdToken m_token;
+ CustomDescrList m_lstCA;
+};
+
+class TyParList {
+public:
+ TyParList(DWORD a, BinStr* b, LPCUTF8 n, TyParList* nx = NULL)
+ {
+ bound = (b == NULL) ? new BinStr() : b;
+ bound->appendInt32(0); // zero terminator
+ attrs = a; name = n; next = nx;
+ };
+ ~TyParList()
+ {
+ if( bound) delete bound;
+
+ // To avoid excessive stack usage (especially in debug builds), we break the next chain
+ // and delete as we traverse the link list
+ TyParList *pCur = next;
+ while (pCur != NULL)
+ {
+ TyParList *pTmp = pCur->next;
+ pCur->next = NULL;
+ delete pCur;
+ pCur = pTmp;
+ }
+ };
+ int Count()
+ {
+ TyParList* tp = this;
+ int n;
+ for(n = 1; (tp = tp->next) != NULL; n++);
+ return n;
+ };
+ int IndexOf(LPCUTF8 name)
+ {
+ TyParList* tp = this;
+ int n;
+ int ret = -1;
+ for(n=0; tp != NULL; n++, tp = tp->next)
+ {
+ if(tp->name == NULL)
+ {
+ if(name == NULL) ret = n;
+ }
+ else
+ {
+ if(name == NULL) continue;
+ if(0 == strcmp(name,tp->name)) ret = n;
+ }
+ }
+ return ret;
+ };
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:6211) // "Leaking memory 'b' due to an exception. Consider using a local catch block to clean up memory"
+#endif /*_PREFAST_ */
+
+ int ToArray(BinStr ***bounds, LPCWSTR** names, DWORD **attrs)
+ {
+ int n = Count();
+ BinStr **b = new BinStr* [n];
+ LPCWSTR *nam = new LPCWSTR [n];
+ DWORD *attr = attrs ? new DWORD [n] : NULL;
+ TyParList *tp = this;
+ int i = 0;
+ while (tp)
+ {
+ ULONG cTemp = (ULONG)strlen(tp->name)+1;
+ WCHAR* wzDllName = new WCHAR [cTemp];
+ // Convert name to UNICODE
+ memset(wzDllName,0,sizeof(WCHAR)*cTemp);
+ WszMultiByteToWideChar(g_uCodePage,0,tp->name,-1,wzDllName,cTemp);
+ nam[i] = (LPCWSTR)wzDllName;
+ b[i] = tp->bound;
+ if (attr)
+ attr[i] = tp->attrs;
+ tp->bound = 0; // to avoid deletion by destructor
+ i++;
+ tp = tp->next;
+ }
+ *bounds = b;
+ *names = nam;
+ if (attrs)
+ *attrs = attr;
+ return n;
+ };
+
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif /*_PREFAST_*/
+
+ int ToArray(TyParDescr **ppTPD)
+ {
+ int n = Count();
+ TyParDescr *pTPD = NULL;
+ if(n)
+ {
+ pTPD = new TyParDescr[n];
+ if(pTPD)
+ {
+ int i = 0;
+ TyParList *tp = this;
+ while (tp)
+ {
+ pTPD[i].Init(tp->bound,tp->name,tp->attrs);
+ tp->bound = 0; // to avoid deletion by destructor
+ i++;
+ tp = tp->next;
+ }
+ }
+ }
+ *ppTPD = pTPD;
+ return n;
+ };
+ TyParList* Next() { return next; };
+ BinStr* Bound() { return bound; };
+private:
+ BinStr* bound;
+ LPCUTF8 name;
+ TyParList* next;
+ DWORD attrs;
+};
+
+typedef TyParList* pTyParList;
+
+#endif
+
diff --git a/src/coreclr/ilasm/writer.cpp b/src/coreclr/ilasm/writer.cpp
new file mode 100644
index 00000000000..0bff54b603d
--- /dev/null
+++ b/src/coreclr/ilasm/writer.cpp
@@ -0,0 +1,1663 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// writer.cpp
+//
+
+#include "ilasmpch.h"
+
+#include "assembler.h"
+
+#include "ceefilegenwriter.h"
+
+#ifndef _MSC_VER
+//cloned definition from ntimage.h that is removed for non MSVC builds
+typedef VOID
+(NTAPI *PIMAGE_TLS_CALLBACK) (
+ PVOID DllHandle,
+ ULONG Reason,
+ PVOID Reserved
+ );
+#endif //_MSC_VER
+
+
+HRESULT Assembler::InitMetaData()
+{
+ HRESULT hr = E_FAIL;
+
+ if(m_fInitialisedMetaData) return S_OK;
+
+ if(bClock) bClock->cMDInitBegin = GetTickCount();
+
+ hr = MetaDataGetDispenser(CLSID_CorMetaDataDispenser,
+ IID_IMetaDataDispenserEx2, (void **)&m_pDisp);
+ if (FAILED(hr))
+ goto exit;
+
+ if(m_wzMetadataVersion)
+ {
+ VARIANT encOption;
+ BSTR bstr;
+ V_VT(&encOption) = VT_BSTR;
+ V_BSTR(&encOption) = bstr = ::SysAllocString(m_wzMetadataVersion);
+ hr = m_pDisp->SetOption(MetaDataRuntimeVersion, &encOption);
+ ::SysFreeString(bstr);
+ }
+ hr = m_pDisp->DefineScope(CLSID_CorMetaDataRuntime, 0, IID_IMetaDataEmit3,
+ (IUnknown **)&m_pEmitter);
+ if (FAILED(hr))
+ goto exit;
+
+ m_pManifest->SetEmitter(m_pEmitter);
+ if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataImport2, (void**)&m_pImporter)))
+ goto exit;
+
+ if (m_pdbFormat == PdbFormat::PORTABLE)
+ {
+ m_pPortablePdbWriter = new PortablePdbWriter();
+ if (FAILED(hr = m_pPortablePdbWriter->Init(m_pDisp))) goto exit;
+ }
+
+ //m_Parser = new AsmParse(m_pEmitter);
+ m_fInitialisedMetaData = TRUE;
+
+ hr = S_OK;
+
+exit:
+ if(bClock) bClock->cMDInitEnd = GetTickCount();
+ return hr;
+}
+/*********************************************************************************/
+/* if we have any Thread local store data, make the TLS directory record for it */
+
+HRESULT Assembler::CreateTLSDirectory() {
+
+ ULONG tlsEnd;
+ HRESULT hr;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionDataLen(m_pTLSSection, &tlsEnd))) return(hr);
+
+ if (tlsEnd == 0) // No TLS data, we are done
+ return(S_OK);
+
+ // place to put the TLS directory
+ HCEESECTION tlsDirSec = m_pGlobalDataSection;
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_PE32)
+ {
+ DWORD sizeofptr = (DWORD)sizeof(DWORD);
+ DWORD sizeofdir = (DWORD)sizeof(IMAGE_TLS_DIRECTORY32);
+ DWORD offsetofStartAddressOfRawData = (DWORD)offsetof(IMAGE_TLS_DIRECTORY32, StartAddressOfRawData);
+ DWORD offsetofEndAddressOfRawData = (DWORD)offsetof(IMAGE_TLS_DIRECTORY32, EndAddressOfRawData);
+ DWORD offsetofAddressOfIndex = (DWORD)offsetof(IMAGE_TLS_DIRECTORY32, AddressOfIndex);
+ DWORD offsetofAddressOfCallBacks = (DWORD)offsetof(IMAGE_TLS_DIRECTORY32, AddressOfCallBacks);
+
+ // Get memory for for the TLS directory block,as well as a spot for callback chain
+ IMAGE_TLS_DIRECTORY32* tlsDir;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionBlock(tlsDirSec, sizeofdir + sizeofptr, sizeofptr, (void**) &tlsDir))) return(hr);
+ DWORD* callBackChain = (DWORD*) &tlsDir[1];
+ *callBackChain = 0;
+
+ // Find out where the tls directory will end up
+ ULONG tlsDirOffset;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionDataLen(tlsDirSec, &tlsDirOffset))) return(hr);
+ tlsDirOffset -= (sizeofdir + sizeofptr);
+
+ // Set the start of the TLS data (offset 0 of hte TLS section)
+ tlsDir->StartAddressOfRawData = 0;
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofStartAddressOfRawData, m_pTLSSection, srRelocHighLow))) return(hr);
+
+ // Set the end of the TLS data
+ tlsDir->EndAddressOfRawData = VALPTR(tlsEnd);
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofEndAddressOfRawData, m_pTLSSection, srRelocHighLow))) return(hr);
+
+ // Allocate space for the OS to put the TLS index for this PE file (needs to be Read/Write?)
+ DWORD* tlsIndex;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pGlobalDataSection, sizeof(DWORD), sizeof(DWORD), (void**) &tlsIndex))) return(hr);
+ *tlsIndex = 0xCCCCCCCC; // Does't really matter, the OS will fill it in
+
+ // Find out where tlsIndex index is
+ ULONG tlsIndexOffset;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionDataLen(tlsDirSec, &tlsIndexOffset))) return(hr);
+ tlsIndexOffset -= sizeof(DWORD);
+
+ // Set the address of the TLS index
+ tlsDir->AddressOfIndex = VALPTR(tlsIndexOffset);
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofAddressOfIndex, m_pGlobalDataSection, srRelocHighLow))) return(hr);
+
+ // Set addres of callbacks chain
+ tlsDir->AddressOfCallBacks = VALPTR((DWORD)(DWORD_PTR)(PIMAGE_TLS_CALLBACK*)(size_t)(tlsDirOffset + sizeofdir));
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofAddressOfCallBacks, tlsDirSec, srRelocHighLow))) return(hr);
+
+ // Set the other fields.
+ tlsDir->SizeOfZeroFill = 0;
+ tlsDir->Characteristics = 0;
+
+ hr=m_pCeeFileGen->SetDirectoryEntry (m_pCeeFile, tlsDirSec, IMAGE_DIRECTORY_ENTRY_TLS,
+ sizeofdir, tlsDirOffset);
+
+ if (m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ COR_SET_32BIT_REQUIRED(m_dwComImageFlags);
+ }
+ else
+ {
+ DWORD sizeofptr = (DWORD)sizeof(__int64);
+ DWORD sizeofdir = (DWORD)sizeof(IMAGE_TLS_DIRECTORY64);
+ DWORD offsetofStartAddressOfRawData = (DWORD)offsetof(IMAGE_TLS_DIRECTORY64, StartAddressOfRawData);
+ DWORD offsetofEndAddressOfRawData = (DWORD)offsetof(IMAGE_TLS_DIRECTORY64, EndAddressOfRawData);
+ DWORD offsetofAddressOfIndex = (DWORD)offsetof(IMAGE_TLS_DIRECTORY64, AddressOfIndex);
+ DWORD offsetofAddressOfCallBacks = (DWORD)offsetof(IMAGE_TLS_DIRECTORY64, AddressOfCallBacks);
+
+ // Get memory for for the TLS directory block,as well as a spot for callback chain
+ IMAGE_TLS_DIRECTORY64* tlsDir;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionBlock(tlsDirSec, sizeofdir + sizeofptr, sizeofptr, (void**) &tlsDir))) return(hr);
+ __int64* callBackChain = (__int64*) &tlsDir[1];
+ *callBackChain = 0;
+
+ // Find out where the tls directory will end up
+ ULONG tlsDirOffset;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionDataLen(tlsDirSec, &tlsDirOffset))) return(hr);
+ tlsDirOffset -= (sizeofdir + sizeofptr);
+
+ // Set the start of the TLS data (offset 0 of hte TLS section)
+ tlsDir->StartAddressOfRawData = 0;
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofStartAddressOfRawData, m_pTLSSection, srRelocHighLow))) return(hr);
+
+ // Set the end of the TLS data
+ tlsDir->EndAddressOfRawData = VALPTR(tlsEnd);
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofEndAddressOfRawData, m_pTLSSection, srRelocHighLow))) return(hr);
+
+ // Allocate space for the OS to put the TLS index for this PE file (needs to be Read/Write?)
+ DWORD* tlsIndex;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pGlobalDataSection, sizeof(DWORD), sizeof(DWORD), (void**) &tlsIndex))) return(hr);
+ *tlsIndex = 0xCCCCCCCC; // Does't really matter, the OS will fill it in
+
+ // Find out where tlsIndex index is
+ ULONG tlsIndexOffset;
+ if(FAILED(hr=m_pCeeFileGen->GetSectionDataLen(tlsDirSec, &tlsIndexOffset))) return(hr);
+ tlsIndexOffset -= sizeof(DWORD);
+
+ // Set the address of the TLS index
+ tlsDir->AddressOfIndex = VALPTR(tlsIndexOffset);
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofAddressOfIndex, m_pGlobalDataSection, srRelocHighLow))) return(hr);
+
+ // Set address of callbacks chain
+ tlsDir->AddressOfCallBacks = VALPTR((DWORD)(DWORD_PTR)(PIMAGE_TLS_CALLBACK*)(size_t)(tlsDirOffset + sizeofdir));
+ if(FAILED(hr=m_pCeeFileGen->AddSectionReloc(tlsDirSec, tlsDirOffset + offsetofAddressOfCallBacks, tlsDirSec, srRelocHighLow))) return(hr);
+
+ // Set the other fields.
+ tlsDir->SizeOfZeroFill = 0;
+ tlsDir->Characteristics = 0;
+
+ hr=m_pCeeFileGen->SetDirectoryEntry (m_pCeeFile, tlsDirSec, IMAGE_DIRECTORY_ENTRY_TLS,
+ sizeofdir, tlsDirOffset);
+ }
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_STRIP_RELOCS)
+ {
+ report->error("Base relocations are emitted, while /STRIPRELOC option has been specified");
+ }
+ m_dwComImageFlags &= ~COMIMAGE_FLAGS_ILONLY;
+
+ return(hr);
+}
+
+HRESULT Assembler::CreateDebugDirectory()
+{
+ HRESULT hr = S_OK;
+ HCEESECTION sec = m_pILSection;
+ BYTE *de;
+ ULONG deOffset;
+
+ // Only emit this if we're also emitting debug info.
+ if (!(m_fGeneratePDB && (m_pSymWriter || IsPortablePdb())))
+ return S_OK;
+
+ IMAGE_DEBUG_DIRECTORY debugDirIDD;
+ struct Param
+ {
+ DWORD debugDirDataSize;
+ BYTE *debugDirData;
+ } param;
+ param.debugDirData = NULL;
+
+ if (m_pSymWriter) // CLASSIC
+ {
+ // Get the debug info from the symbol writer.
+ if (FAILED(hr=m_pSymWriter->GetDebugInfo(NULL, 0, &param.debugDirDataSize, NULL)))
+ return hr;
+
+ // Will there even be any?
+ if (param.debugDirDataSize == 0)
+ return S_OK;
+
+ // Make some room for the data.
+ PAL_TRY(Param *, pParam, &param) {
+ pParam->debugDirData = new BYTE[pParam->debugDirDataSize];
+ } PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ hr = E_FAIL;
+ } PAL_ENDTRY
+
+ if(FAILED(hr)) return hr;
+ // Actually get the data now.
+ if (FAILED(hr = m_pSymWriter->GetDebugInfo(&debugDirIDD,
+ param.debugDirDataSize,
+ NULL,
+ param.debugDirData)))
+ goto ErrExit;
+
+ // Grab the timestamp of the PE file.
+ DWORD fileTimeStamp;
+
+ if (FAILED(hr = m_pCeeFileGen->GetFileTimeStamp(m_pCeeFile,
+ &fileTimeStamp)))
+ goto ErrExit;
+
+ // Fill in the directory entry.
+ debugDirIDD.TimeDateStamp = VAL32(fileTimeStamp);
+ }
+ else if (IsPortablePdb()) // PORTABLE
+ {
+ // get module ID
+ DWORD rsds = 0x53445352;
+ DWORD pdbAge = 0x1;
+ DWORD len = sizeof(rsds) + sizeof(GUID) + sizeof(pdbAge) + (DWORD)strlen(m_szPdbFileName) + 1;
+ BYTE* dbgDirData = new BYTE[len];
+
+ DWORD offset = 0;
+ memcpy_s(dbgDirData + offset, len, &rsds, sizeof(rsds)); // RSDS
+ offset += sizeof(rsds);
+ memcpy_s(dbgDirData + offset, len, m_pPortablePdbWriter->GetGuid(), sizeof(GUID)); // PDB GUID
+ offset += sizeof(GUID);
+ memcpy_s(dbgDirData + offset, len, &pdbAge, sizeof(pdbAge)); // PDB AGE
+ offset += sizeof(pdbAge);
+ memcpy_s(dbgDirData + offset, len, m_szPdbFileName, strlen(m_szPdbFileName) + 1); // PDB PATH
+
+ debugDirIDD.Characteristics = 0;
+ debugDirIDD.TimeDateStamp = m_pPortablePdbWriter->GetTimestamp();
+ debugDirIDD.MajorVersion = 0x100;
+ debugDirIDD.MinorVersion = 0x504d;
+ debugDirIDD.Type = IMAGE_DEBUG_TYPE_CODEVIEW;
+ debugDirIDD.SizeOfData = len;
+ debugDirIDD.AddressOfRawData = 0; // will be updated bellow
+ debugDirIDD.PointerToRawData = 0; // will be updated bellow
+
+ param.debugDirDataSize = len;
+
+ // Make some room for the data.
+ PAL_TRY(Param*, pParam, &param) {
+ pParam->debugDirData = new BYTE[pParam->debugDirDataSize];
+ } PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ hr = E_FAIL;
+ } PAL_ENDTRY
+
+ if (FAILED(hr)) return hr;
+
+ param.debugDirData = dbgDirData;
+ }
+
+ // Grab memory in the section for our stuff.
+ // Note that UpdateResource doesn't work correctly if the debug directory is
+ // in the data section. So instead we put it in the text section (same as
+ // cs compiler).
+ if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(sec,
+ sizeof(debugDirIDD) +
+ param.debugDirDataSize,
+ 4,
+ (void**) &de)))
+ goto ErrExit;
+
+ // Where did we get that memory?
+ if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(sec,
+ &deOffset)))
+ goto ErrExit;
+
+ deOffset -= (sizeof(debugDirIDD) + param.debugDirDataSize);
+
+ // Setup a reloc so that the address of the raw
+ // data is setup correctly.
+ debugDirIDD.PointerToRawData = VAL32(deOffset + sizeof(debugDirIDD));
+
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(
+ sec,
+ deOffset +
+ offsetof(IMAGE_DEBUG_DIRECTORY,
+ PointerToRawData),
+ sec, srRelocFilePos)))
+ goto ErrExit;
+
+ debugDirIDD.AddressOfRawData = VAL32(deOffset + sizeof(debugDirIDD));
+
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(
+ sec,
+ deOffset +
+ offsetof(IMAGE_DEBUG_DIRECTORY,
+ AddressOfRawData),
+ sec, srRelocAbsolute)))
+ goto ErrExit;
+ // Emit the directory entry.
+ if (FAILED(hr = m_pCeeFileGen->SetDirectoryEntry(m_pCeeFile,
+ sec,
+ IMAGE_DIRECTORY_ENTRY_DEBUG,
+ sizeof(debugDirIDD),
+ deOffset)))
+ goto ErrExit;
+
+ // Copy the debug directory into the section.
+ memcpy(de, &debugDirIDD, sizeof(debugDirIDD));
+ memcpy(de + sizeof(debugDirIDD), param.debugDirData,
+ param.debugDirDataSize);
+
+ if (param.debugDirData)
+ {
+ delete [] param.debugDirData;
+ }
+ return S_OK;
+
+ErrExit:
+ if (param.debugDirData)
+ {
+ delete [] param.debugDirData;
+ }
+ return hr;
+}
+//#ifdef EXPORT_DIR_ENABLED
+HRESULT Assembler::CreateExportDirectory()
+{
+ HRESULT hr = S_OK;
+ DWORD Nentries = m_EATList.COUNT();
+ if(Nentries == 0) return S_OK;
+
+ IMAGE_EXPORT_DIRECTORY exportDirIDD;
+ DWORD exportDirDataSize;
+ BYTE *exportDirData;
+ EATEntry *pEATE;
+ unsigned i, L, ordBase = 0xFFFFFFFF, Ldllname;
+ // get the DLL name from output file name
+ char* pszDllName;
+ Ldllname = (unsigned)wcslen(m_wzOutputFileName)*3+3;
+ char* szOutputFileName = new char[Ldllname];
+ memset(szOutputFileName,0,wcslen(m_wzOutputFileName)*3+3);
+ WszWideCharToMultiByte(CP_ACP,0,m_wzOutputFileName,-1,szOutputFileName,Ldllname,NULL,NULL);
+ pszDllName = strrchr(szOutputFileName,DIRECTORY_SEPARATOR_CHAR_A);
+#ifdef TARGET_WINDOWS
+ if(pszDllName == NULL) pszDllName = strrchr(szOutputFileName,':');
+#endif
+ if(pszDllName == NULL) pszDllName = szOutputFileName;
+ Ldllname = (unsigned)strlen(pszDllName)+1;
+
+ // Allocate buffer for tables
+ for(i = 0, L=0; i < Nentries; i++) L += 1+(unsigned)strlen(m_EATList.PEEK(i)->szAlias);
+ exportDirDataSize = Nentries*5*sizeof(WORD) + L + Ldllname;
+ exportDirData = new BYTE[exportDirDataSize];
+ memset(exportDirData,0,exportDirDataSize);
+
+ // Export address table
+ DWORD* pEAT = (DWORD*)exportDirData;
+ // Name pointer table
+ DWORD* pNPT = pEAT + Nentries;
+ // Ordinal table
+ WORD* pOT = (WORD*)(pNPT + Nentries);
+ // Export name table
+ char* pENT = (char*)(pOT + Nentries);
+ // DLL name
+ char* pDLLName = pENT + L;
+
+ // sort the names/ordinals
+ char** pAlias = new char*[Nentries];
+ for(i = 0; i < Nentries; i++)
+ {
+ pEATE = m_EATList.PEEK(i);
+ pOT[i] = (WORD)pEATE->dwOrdinal;
+ if(pOT[i] < ordBase) ordBase = pOT[i];
+ pAlias[i] = pEATE->szAlias;
+ }
+ bool swapped = true;
+ unsigned j;
+ char* pch;
+ while(swapped)
+ {
+ swapped = false;
+ for(i=1; i < Nentries; i++)
+ {
+ if(strcmp(pAlias[i-1],pAlias[i]) > 0)
+ {
+ swapped = true;
+ pch = pAlias[i-1];
+ pAlias[i-1] = pAlias[i];
+ pAlias[i] = pch;
+ j = pOT[i-1];
+ pOT[i-1] = pOT[i];
+ pOT[i] = j;
+ }
+ }
+ }
+ // normalize ordinals
+ for(i = 0; i < Nentries; i++) pOT[i] -= ordBase;
+ // fill the export address table
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22008) // "Suppress PREfast warnings about integer overflow"
+#endif
+ for(i = 0; i < Nentries; i++)
+ {
+ pEATE = m_EATList.PEEK(i);
+ pEAT[pEATE->dwOrdinal - ordBase] = pEATE->dwStubRVA;
+ }
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+ // fill the export names table
+ unsigned l;
+ for(i = 0, j = 0; i < Nentries; i++)
+ {
+ pNPT[i] = j; // relative offset in the table
+ l = (unsigned)strlen(pAlias[i])+1;
+ memcpy(&pENT[j],pAlias[i],l);
+ j+=l;
+ }
+ _ASSERTE(j==L);
+ // fill the DLL name
+ memcpy(pDLLName,pszDllName,Ldllname);
+
+ // Data blob is ready pending Name Pointer Table values offsetting
+
+ memset(&exportDirIDD,0,sizeof(IMAGE_EXPORT_DIRECTORY));
+ // Grab the timestamp of the PE file.
+ DWORD fileTimeStamp;
+ if (FAILED(hr = m_pCeeFileGen->GetFileTimeStamp(m_pCeeFile,&fileTimeStamp))) return hr;
+ // Fill in the directory entry.
+ // Characteristics, MajorVersion and MinorVersion play no role and stay 0
+ exportDirIDD.TimeDateStamp = VAL32(fileTimeStamp);
+ exportDirIDD.Name = VAL32(exportDirDataSize - Ldllname); // to be offset later
+ exportDirIDD.Base = VAL32(ordBase);
+ exportDirIDD.NumberOfFunctions = VAL32(Nentries);
+ exportDirIDD.NumberOfNames = VAL32(Nentries);
+ exportDirIDD.AddressOfFunctions = 0; // to be offset later
+ exportDirIDD.AddressOfNames = VAL32(Nentries*sizeof(DWORD)); // to be offset later
+ exportDirIDD.AddressOfNameOrdinals = VAL32(Nentries*sizeof(DWORD)*2); // to be offset later
+
+ // Grab memory in the section for our stuff.
+ HCEESECTION sec = m_pGlobalDataSection;
+ BYTE *de;
+ if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(sec,
+ sizeof(IMAGE_EXPORT_DIRECTORY) + exportDirDataSize,
+ 4,
+ (void**) &de))) return hr;
+ // Where did we get that memory?
+ ULONG deOffset, deDataOffset;
+ if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(sec, &deDataOffset))) return hr;
+
+ deDataOffset -= exportDirDataSize;
+ deOffset = deDataOffset - sizeof(IMAGE_EXPORT_DIRECTORY);
+
+ // Add offsets and set up relocs for header entries
+ exportDirIDD.Name = VAL32(VAL32(exportDirIDD.Name) + deDataOffset);
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,Name),
+ sec, srRelocAbsolute))) return hr;
+ exportDirIDD.AddressOfFunctions = VAL32(VAL32(exportDirIDD.AddressOfFunctions) + deDataOffset);
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfFunctions),
+ sec, srRelocAbsolute))) return hr;
+ exportDirIDD.AddressOfNames = VAL32(VAL32(exportDirIDD.AddressOfNames) + deDataOffset);
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfNames),
+ sec, srRelocAbsolute))) return hr;
+ exportDirIDD.AddressOfNameOrdinals = VAL32(VAL32(exportDirIDD.AddressOfNameOrdinals) + deDataOffset);
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfNameOrdinals),
+ sec, srRelocAbsolute))) return hr;
+
+ // Add offsets and set up relocs for Name Pointer Table
+ j = deDataOffset + Nentries*5*sizeof(WORD); // EA, NP and O Tables come first
+ for(i = 0; i < Nentries; i++)
+ {
+ pNPT[i] += j;
+ if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,exportDirIDD.AddressOfNames+i*sizeof(DWORD),
+ sec, srRelocAbsolute))) return hr;
+ }
+
+
+ // Emit the directory entry.
+ if (FAILED(hr = m_pCeeFileGen->SetDirectoryEntry(m_pCeeFile, sec, IMAGE_DIRECTORY_ENTRY_EXPORT,
+ sizeof(IMAGE_EXPORT_DIRECTORY), deOffset))) return hr;
+
+ // Copy the debug directory into the section.
+ memcpy(de, &exportDirIDD, sizeof(IMAGE_EXPORT_DIRECTORY));
+ memcpy(de + sizeof(IMAGE_EXPORT_DIRECTORY), exportDirData, exportDirDataSize);
+ delete [] pAlias;
+ delete [] exportDirData;
+ return S_OK;
+}
+
+static const BYTE ExportStubAMD64Template[] =
+{
+ // Jump through VTFixup table
+ 0x48, 0xA1, // rex.w rex.b mov rax,[following address]
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of VTFixup slot
+ 0xFF, 0xE0 // jmp [rax]
+};
+static const BYTE ExportStubX86Template[] =
+{
+ // Jump through VTFixup table
+ 0xFF, 0x25, // jmp [following address]
+ 0x00, 0x00, 0x00, 0x00 //address of VTFixup slot
+};
+static const WORD ExportStubARMTemplate[] =
+{
+ // Jump through VTFixup table
+ 0xf8df, 0xf000, // ldr pc, [pc, #0]
+ 0x0000, 0x0000 //address of VTFixup slot
+};
+
+DWORD Assembler::EmitExportStub(DWORD dwVTFSlotRVA)
+{
+ DWORD EXPORT_STUB_SIZE = (DWORD)(sizeof(WORD)+sizeof(DWORD));
+ DWORD OFFSET_OF_ADDR = (DWORD)sizeof(WORD);
+ DWORD STUB_ALIGNMENT = 16;
+ BYTE* STUB_TEMPLATE = NULL;
+ DWORD PEFileOffset;
+ BYTE* outBuff;
+ DWORD* pdwVTFSlotRVA;
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_AMD64)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubAMD64Template[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubAMD64Template);
+ OFFSET_OF_ADDR = 2;
+ STUB_ALIGNMENT = 4;
+ }
+ else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubX86Template[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubX86Template);
+ OFFSET_OF_ADDR = 2;
+ }
+ else if(m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM)
+ {
+ STUB_TEMPLATE = (BYTE*)&ExportStubARMTemplate[0];
+ EXPORT_STUB_SIZE = sizeof(ExportStubARMTemplate);
+ OFFSET_OF_ADDR = 4;
+ STUB_ALIGNMENT = 4;
+ }
+ else
+ {
+ report->error("Unmanaged exports are not implemented for unknown platform");
+ return NULL;
+ }
+ // Addr must be aligned, not the stub!
+ if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
+ if((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))
+ {
+ ULONG L = STUB_ALIGNMENT - ((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1));
+ if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, L, 1, (void **) &outBuff))) return 0;
+ memset(outBuff,0,L);
+ }
+
+ if (FAILED(m_pCeeFileGen->GetSectionBlock (m_pILSection, EXPORT_STUB_SIZE, 1, (void **) &outBuff))) return 0;
+ memcpy(outBuff,STUB_TEMPLATE,EXPORT_STUB_SIZE);
+ pdwVTFSlotRVA = (DWORD*)(&outBuff[OFFSET_OF_ADDR]);
+ *pdwVTFSlotRVA = VAL32(dwVTFSlotRVA);
+
+ // The offset where we start, (not where the alignment bytes start!)
+ if (FAILED(m_pCeeFileGen->GetSectionDataLen (m_pILSection, &PEFileOffset))) return 0;
+
+ PEFileOffset -= EXPORT_STUB_SIZE;
+ _ASSERTE(((PEFileOffset + OFFSET_OF_ADDR)&(STUB_ALIGNMENT-1))==0);
+ m_pCeeFileGen->AddSectionReloc(m_pILSection, PEFileOffset+OFFSET_OF_ADDR,m_pGlobalDataSection, srRelocHighLow);
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_STRIP_RELOCS)
+ {
+ report->error("Base relocations are emitted, while /STRIPRELOC option has been specified");
+ }
+ m_pCeeFileGen->GetMethodRVA(m_pCeeFile, PEFileOffset,&PEFileOffset);
+ return PEFileOffset;
+}
+//#endif
+
+HRESULT Assembler::GetCAName(mdToken tkCA, __out LPWSTR *ppszName)
+{
+ HRESULT hr = S_OK;
+ DWORD cchName;
+ LPWSTR name;
+
+ *ppszName = NULL;
+
+ if (TypeFromToken(tkCA) == mdtMemberRef)
+ {
+ mdToken parent;
+ if (FAILED(hr = m_pImporter->GetMemberRefProps( tkCA, &parent, NULL, 0, NULL, NULL, NULL)))
+ return hr;
+ tkCA = parent;
+ }
+ else if (TypeFromToken(tkCA) == mdtMethodDef)
+ {
+ mdToken parent;
+ if (FAILED(hr = m_pImporter->GetMemberProps( tkCA, &parent, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)))
+ return hr;
+ tkCA = parent;
+ }
+
+ if (TypeFromToken(tkCA) == mdtTypeRef)
+ {
+ // A TypeRef
+ if (FAILED(hr = m_pImporter->GetTypeRefProps(tkCA, NULL, NULL, 0, &cchName)))
+ return hr;
+ if ((name = new WCHAR[cchName + 1]) == NULL)
+ return E_OUTOFMEMORY;
+ hr = m_pImporter->GetTypeRefProps(tkCA, NULL, name, cchName, &cchName);
+ }
+ else
+ {
+ hr = m_pImporter->GetTypeDefProps(tkCA, NULL, 0, &cchName, NULL, NULL);
+ if (hr != S_OK)
+ return hr;
+ if ((name = new WCHAR[cchName + 1]) == NULL)
+ return E_OUTOFMEMORY;
+ hr = m_pImporter->GetTypeDefProps(tkCA, name, cchName, &cchName, NULL, NULL);
+ }
+ if (SUCCEEDED(hr))
+ *ppszName = name;
+ else
+ delete [] name;
+ return hr;
+}
+
+BYTE HexToByte (CHAR wc)
+{
+ if (!iswxdigit(wc)) return (BYTE) 0xff;
+ if (iswdigit(wc)) return (BYTE) (wc - L'0');
+ if (iswupper(wc)) return (BYTE) (wc - L'A' + 10);
+ return (BYTE) (wc - L'a' + 10);
+}
+
+
+BOOL Assembler::EmitFieldsMethods(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all field definition metadata tokens
+ if((n = pClass->m_FieldDList.COUNT()))
+ {
+ FieldDescriptor* pFD;
+ if(m_fReportProgress) printf("Fields: %d;\t",n);
+ for(int j=0; (pFD = pClass->m_FieldDList.PEEK(j)); j++) // can't use POP here: we'll need field list for props
+ {
+ if(!EmitField(pFD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pFD->m_fNew = FALSE;
+ }
+ }
+ // Fields are emitted; emit the class layout
+ {
+ COR_FIELD_OFFSET *pOffsets = NULL;
+ ULONG ul = pClass->m_ulPack;
+ ULONG N = pClass->m_dwNumFieldsWithOffset;
+
+ EmitSecurityInfo(pClass->m_cl,
+ pClass->m_pPermissions,
+ pClass->m_pPermissionSets);
+ pClass->m_pPermissions = NULL;
+ pClass->m_pPermissionSets = NULL;
+ if((pClass->m_ulSize != 0xFFFFFFFF)||(ul != 0)||(N != 0))
+ {
+ if(IsTdAutoLayout(pClass->m_Attr)) report->warn("Layout specified for auto-layout class\n");
+ if((ul > 128)||((ul & (ul-1)) !=0 ))
+ report->error("Invalid packing parameter (%d), must be 1,2,4,8...128\n",pClass->m_ulPack);
+ if(N)
+ {
+ pOffsets = new COR_FIELD_OFFSET[N+1];
+ ULONG i,j=0;
+ FieldDescriptor *pFD;
+ for(i=0; (pFD = pClass->m_FieldDList.PEEK(i)); i++)
+ {
+ if(pFD->m_ulOffset != 0xFFFFFFFF)
+ {
+ pOffsets[j].ridOfField = RidFromToken(pFD->m_fdFieldTok);
+ pOffsets[j].ulOffset = pFD->m_ulOffset;
+ j++;
+ }
+ }
+ _ASSERTE(j == N);
+ pOffsets[j].ridOfField = mdFieldDefNil;
+ }
+ m_pEmitter->SetClassLayout (
+ pClass->m_cl, // [IN] typedef
+ ul, // [IN] packing size specified as 1, 2, 4, 8, or 16
+ pOffsets, // [IN] array of layout specification
+ pClass->m_ulSize); // [IN] size of the class
+ if(pOffsets) delete [] pOffsets;
+ }
+ }
+ // emit all method definition metadata tokens
+ if((n = pClass->m_MethodList.COUNT()))
+ {
+ Method* pMethod;
+
+ if(m_fReportProgress) printf("Methods: %d;\t",n);
+ for(int i=0; (pMethod = pClass->m_MethodList.PEEK(i));i++)
+ {
+ if(!EmitMethod(pMethod))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pMethod->m_fNew = FALSE;
+ }
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+HRESULT Assembler::ResolveLocalMemberRefs()
+{
+ unsigned ulTotal=0, ulDefs=0, ulRefs=0, ulUnres=0;
+ MemberRefDList* pList[2] = {&m_LocalMethodRefDList,&m_LocalFieldRefDList};
+
+ if(pList[0]->COUNT() + pList[1]->COUNT())
+ {
+ MemberRefDescriptor* pMRD;
+ mdToken tkMemberDef = 0;
+ int i,j,k;
+ Class *pSearch;
+
+ if(m_fReportProgress) printf("Resolving local member refs: ");
+ for(k=0; k<2; k++)
+ {
+ for(i=0; (pMRD = pList[k]->PEEK(i)) != NULL; i++)
+ {
+ if(pMRD->m_tkResolved) continue;
+
+ tkMemberDef = 0;
+ Method* pListMD;
+ char* pMRD_szName = pMRD->m_szName;
+ DWORD pMRD_dwName = pMRD->m_dwName;
+ ULONG pMRD_dwCSig = (pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->length() : 0);
+ PCOR_SIGNATURE pMRD_pSig = (PCOR_SIGNATURE)(pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->ptr() : NULL);
+ CQuickBytes qbSig;
+
+ ulTotal++;
+
+ pSearch = NULL;
+ if(pMRD->m_tdClass == mdTokenNil)
+ pSearch = m_lstClass.PEEK(0);
+ else if((TypeFromToken(pMRD->m_tdClass) != mdtTypeDef)
+ ||((pSearch = m_lstClass.PEEK(RidFromToken(pMRD->m_tdClass)-1)) == NULL))
+ {
+ report->msg("Error: bad parent 0x%08X of local member ref '%s'\n",
+ pMRD->m_tdClass,pMRD->m_szName);
+ }
+ if(pSearch)
+ {
+ // MemberRef may reference a method or a field
+ if(k==0) //methods
+ {
+ if((*pMRD_pSig & IMAGE_CEE_CS_CALLCONV_MASK)==IMAGE_CEE_CS_CALLCONV_VARARG)
+ {
+ ULONG L;
+ qbSig.Shrink(0);
+ _GetFixedSigOfVarArg(pMRD_pSig,pMRD_dwCSig,&qbSig,&L);
+ pMRD_pSig = (PCOR_SIGNATURE)(qbSig.Ptr());
+ pMRD_dwCSig = L;
+ }
+ for(j=0; (pListMD = pSearch->m_MethodList.PEEK(j)) != NULL; j++)
+ {
+ if(pListMD->m_dwName != pMRD_dwName) continue;
+ if(strcmp(pListMD->m_szName,pMRD_szName)) continue;
+ if(pListMD->m_dwMethodCSig != pMRD_dwCSig) continue;
+ if(memcmp(pListMD->m_pMethodSig,pMRD_pSig,pMRD_dwCSig)) continue;
+ tkMemberDef = pListMD->m_Tok;
+ ulDefs++;
+ break;
+ }
+ if(tkMemberDef && ((*pMRD_pSig & IMAGE_CEE_CS_CALLCONV_MASK)==IMAGE_CEE_CS_CALLCONV_VARARG))
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzUniBuf,dwUniBuf);
+
+ if(IsMdPrivateScope(pListMD->m_Attr))
+ {
+ WCHAR* p = wcsstr(wzUniBuf,W("$PST06"));
+ if(p) *p = 0;
+ }
+
+ m_pEmitter->DefineMemberRef(tkMemberDef, wzUniBuf,
+ pMRD->m_pSigBinStr->ptr(),
+ pMRD->m_pSigBinStr->length(),
+ &tkMemberDef);
+ ulDefs--;
+ ulRefs++;
+ }
+ }
+ else // fields
+ {
+ FieldDescriptor* pListFD;
+ for(j=0; (pListFD = pSearch->m_FieldDList.PEEK(j)) != NULL; j++)
+ {
+ if(pListFD->m_dwName != pMRD_dwName) continue;
+ if(strcmp(pListFD->m_szName,pMRD_szName)) continue;
+ if(pListFD->m_pbsSig)
+ {
+ if(pListFD->m_pbsSig->length() != pMRD_dwCSig) continue;
+ if(memcmp(pListFD->m_pbsSig->ptr(),pMRD_pSig,pMRD_dwCSig)) continue;
+ }
+ else if(pMRD_dwCSig) continue;
+ tkMemberDef = pListFD->m_fdFieldTok;
+ ulDefs++;
+ break;
+ }
+ }
+ }
+ if(tkMemberDef==0)
+ { // could not resolve ref to def, make new ref and leave it this way
+ if((pSearch = pMRD->m_pClass) != NULL)
+ {
+ mdToken tkRef = MakeTypeRef(1,pSearch->m_szFQN);
+
+ if(RidFromToken(tkRef))
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzUniBuf,dwUniBuf);
+
+ m_pEmitter->DefineMemberRef(tkRef, wzUniBuf, pMRD_pSig,
+ pMRD_dwCSig, &tkMemberDef);
+ ulRefs++;
+ }
+ else
+ {
+ report->msg("Error: unresolved member ref '%s' of class 0x%08X\n",pMRD->m_szName,pMRD->m_tdClass);
+ ulUnres++;
+ }
+ }
+ else
+ {
+ report->msg("Error: unresolved global member ref '%s'\n",pMRD->m_szName);
+ ulUnres++;
+ }
+ }
+ pMRD->m_tkResolved = tkMemberDef;
+ }
+ }
+ for(i=0; (pMRD = m_MethodSpecList.PEEK(i)) != NULL; i++)
+ {
+ if(pMRD->m_tkResolved) continue;
+ tkMemberDef = pMRD->m_tdClass;
+ if(TypeFromToken(tkMemberDef)==0x99000000)
+ {
+ tkMemberDef = m_LocalMethodRefDList.PEEK(RidFromToken(tkMemberDef)-1)->m_tkResolved;
+ if((TypeFromToken(tkMemberDef)==mdtMethodDef)||(TypeFromToken(tkMemberDef)==mdtMemberRef))
+ {
+ ULONG pMRD_dwCSig = (pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->length() : 0);
+ PCOR_SIGNATURE pMRD_pSig = (PCOR_SIGNATURE)(pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->ptr() : NULL);
+ HRESULT hr = m_pEmitter->DefineMethodSpec(tkMemberDef, pMRD_pSig, pMRD_dwCSig, &(pMRD->m_tkResolved));
+ if(FAILED(hr))
+ report->error("Unable to define method instantiation");
+ }
+ }
+ if(RidFromToken(pMRD->m_tkResolved)) ulDefs++;
+ else ulUnres++;
+ }
+ if(m_fReportProgress) printf("%d -> %d defs, %d refs, %d unresolved\n",ulTotal,ulDefs,ulRefs,ulUnres);
+ }
+ return (ulUnres ? E_FAIL : S_OK);
+}
+
+HRESULT Assembler::DoLocalMemberRefFixups()
+{
+ MemberRefDList* pList;
+ unsigned Nlmr = m_LocalMethodRefDList.COUNT() + m_LocalFieldRefDList.COUNT(),
+ Nlmrf = m_LocalMemberRefFixupList.COUNT();
+ HRESULT hr = S_OK;
+ if(Nlmr)
+ {
+ MemberRefDescriptor* pMRD;
+ LocalMemberRefFixup* pMRF;
+ int i;
+ for(i = 0; (pMRF = m_LocalMemberRefFixupList.PEEK(i)) != NULL; i++)
+ {
+ if(m_fENCMode && (!pMRF->m_fNew)) continue;
+
+ switch(TypeFromToken(pMRF->tk))
+ {
+ case 0x99000000: pList = &m_LocalMethodRefDList; break;
+ case 0x98000000: pList = &m_LocalFieldRefDList; break;
+ case 0x9A000000: pList = &m_MethodSpecList; break;
+ default: pList = NULL; break;
+ }
+ if(pList)
+ {
+ if((pMRD = pList->PEEK(RidFromToken(pMRF->tk)-1)) != NULL)
+ SET_UNALIGNED_VAL32((void *)(pMRF->offset), pMRD->m_tkResolved);
+ else
+ {
+ report->msg("Error: bad local member ref token 0x%08X in LMR fixup\n",pMRF->tk);
+ hr = E_FAIL;
+ }
+ }
+ pMRF->m_fNew = FALSE;
+ }
+ }
+ else if(Nlmrf)
+ {
+ report->msg("Error: %d local member ref fixups, no local member refs\n",Nlmrf);
+ hr = E_FAIL;
+ }
+ return hr;
+}
+void Assembler::EmitUnresolvedCustomAttributes()
+{
+ CustomDescr *pCD;
+ while((pCD = m_CustomDescrList.POP()) != NULL)
+ {
+ pCD->tkType = ResolveLocalMemberRef(pCD->tkType);
+ pCD->tkOwner = ResolveLocalMemberRef(pCD->tkOwner);
+ // Look for the class'es interfaceimpl if this CA is one of those
+ if (pCD->tkInterfacePair)
+ pCD->tkOwner = GetInterfaceImpl(pCD->tkOwner, pCD->tkInterfacePair);
+ DefineCV(new CustomDescr(pCD->tkOwner,pCD->tkType,pCD->pBlob));
+ }
+}
+
+BOOL Assembler::EmitEventsProps(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all event definition metadata tokens
+ if((n = pClass->m_EventDList.COUNT()))
+ {
+ if(m_fReportProgress) printf("Events: %d;\t",n);
+ EventDescriptor* pED;
+ for(int j=0; (pED = pClass->m_EventDList.PEEK(j)); j++) // can't use POP here: we'll need event list for props
+ {
+ if(!EmitEvent(pED))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pED->m_fNew = FALSE;
+ }
+ }
+ // emit all property definition metadata tokens
+ if((n = pClass->m_PropDList.COUNT()))
+ {
+ if(m_fReportProgress) printf("Props: %d;\t",n);
+ PropDescriptor* pPD;
+
+ for(int j=0; (pPD = pClass->m_PropDList.PEEK(j)); j++)
+ {
+ if(!EmitProp(pPD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pPD->m_fNew = FALSE;
+ }
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+HRESULT Assembler::AllocateStrongNameSignature()
+{
+ HRESULT hr = S_OK;
+ HCEESECTION hSection;
+ DWORD dwDataLength;
+ DWORD dwDataOffset;
+ DWORD dwDataRVA;
+ VOID *pvBuffer;
+ AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
+
+ // pSN->m_cbPublicKey is the length of the m_pbPublicKey
+ dwDataLength = ((int)pSN->m_cbPublicKey < 128 + 32) ? 128 : (int)pSN->m_cbPublicKey - 32;
+
+ // Grab memory in the section for our stuff.
+ if (FAILED(hr = m_pCeeFileGen->GetIlSection(m_pCeeFile,
+ &hSection)))
+ {
+ return hr;
+ }
+
+ if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(hSection,
+ dwDataLength,
+ 4,
+ &pvBuffer)))
+ {
+ return hr;
+ }
+
+ // Where did we get that memory?
+ if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(hSection,
+ &dwDataOffset)))
+ {
+ return hr;
+ }
+
+ dwDataOffset -= dwDataLength;
+
+ // Convert to an RVA.
+ if (FAILED(hr = m_pCeeFileGen->GetMethodRVA(m_pCeeFile,
+ dwDataOffset,
+ &dwDataRVA)))
+ {
+ return hr;
+ }
+
+ // Emit the directory entry.
+ if (FAILED(hr = m_pCeeFileGen->SetStrongNameEntry(m_pCeeFile,
+ dwDataLength,
+ dwDataRVA)))
+ {
+ return hr;
+ }
+
+ return S_OK;
+}
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
+HRESULT Assembler::CreatePEFile(__in __nullterminated WCHAR *pwzOutputFilename)
+{
+ HRESULT hr;
+ DWORD mresourceSize = 0;
+ BYTE* mresourceData = NULL;
+ WCHAR* wzScopeName = NULL;
+
+ if(bClock) bClock->cMDEmitBegin = GetTickCount();
+ if(m_fReportProgress) printf("Creating PE file\n");
+ if (!m_pEmitter)
+ {
+ printf("Error: Cannot create a PE file with no metadata\n");
+ return E_FAIL;
+ }
+ if(!(m_fDLL || m_fEntryPointPresent))
+ {
+ printf("Error: No entry point declared for executable\n");
+ if(!OnErrGo) return E_FAIL;
+ }
+
+ if(bClock) bClock->cMDEmit1 = GetTickCount();
+
+ // Allocate space for a strong name signature if we're delay or full
+ // signing the assembly.
+ if (m_pManifest->m_sStrongName.m_pbPublicKey)
+ {
+ if (FAILED(hr = AllocateStrongNameSignature()))
+ {
+ goto exit;
+ }
+ }
+
+ if(bClock) bClock->cMDEmit2 = GetTickCount();
+
+ if(m_VTFList.COUNT()==0)
+ {
+ Method* pMD;
+ Class* pClass;
+ unsigned N=0, OrdBase=0xFFFFFFFF, i, j;
+ for(i=0; (pClass = m_lstClass.PEEK(i)) != NULL; i++)
+ {
+ for(j = 0; (pMD = pClass->m_MethodList.PEEK(j)) != NULL; j++)
+ {
+ if(pMD->m_dwExportOrdinal != 0xFFFFFFFF)
+ {
+ N++;
+ if(pMD->m_dwExportOrdinal < OrdBase) OrdBase = pMD->m_dwExportOrdinal;
+ }
+ }
+ }
+ if(N)
+ {
+ for(i=0; (pClass = m_lstClass.PEEK(i)) != NULL; i++)
+ {
+ for(j = 0; (pMD = pClass->m_MethodList.PEEK(j)) != NULL; j++)
+ {
+ if(pMD->m_wVTSlot >= 0x8000)
+ {
+ pMD->m_wVTSlot -= 0x8000 + OrdBase - 1;
+ }
+ }
+ }
+ SetDataSection();
+ char* sz = new char[20];
+ strcpy_s(sz,20,"VTF_EAT_internal");
+ EmitDataLabel(sz);
+ sz = new char[20];
+ strcpy_s(sz,20,"VTF_EAT_internal");
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_PE64)
+ {
+ ULONGLONG *pdw = new ULONGLONG[N];
+ for(i=0; i<N; i++) pdw[i] = UI64(0xdeadbeefdeadbeef);
+ EmitData(pdw,sizeof(ULONGLONG)*N);
+ m_VTFList.PUSH(new VTFEntry((USHORT)N,COR_VTABLE_64BIT|COR_VTABLE_FROM_UNMANAGED,sz));
+ delete [] pdw;
+ }
+ else
+ {
+ unsigned *pdw = new unsigned[N];
+ for(i=0; i<N; i++) pdw[i] = 0xdeadbeef;
+ EmitData(pdw,sizeof(unsigned)*N);
+ m_VTFList.PUSH(new VTFEntry((USHORT)N,COR_VTABLE_32BIT|COR_VTABLE_FROM_UNMANAGED,sz));
+ delete [] pdw;
+ }
+ }
+ }
+ wzScopeName=&wzUniBuf[0];
+ if(m_szScopeName[0]) // default: scope name = output file name
+ {
+ WszMultiByteToWideChar(g_uCodePage,0,m_szScopeName,-1,wzScopeName,MAX_SCOPE_LENGTH);
+ }
+ else
+ {
+ WCHAR* pwc;
+ if ((pwc = wcsrchr(m_wzOutputFileName, DIRECTORY_SEPARATOR_CHAR_A)) != NULL) pwc++;
+#ifdef TARGET_WINDOWS
+ else if ((pwc = wcsrchr(m_wzOutputFileName, ':')) != NULL) pwc++;
+#endif
+ else pwc = m_wzOutputFileName;
+
+ wcsncpy_s(wzScopeName, MAX_SCOPE_LENGTH, pwc, _TRUNCATE);
+ }
+ hr = m_pEmitter->SetModuleProps(wzScopeName);
+
+ if (FAILED(hr))
+ goto exit;
+
+ EmitImports();
+ if(m_pManifest)
+ {
+ hr = S_OK;
+ if(m_pManifest->m_pAsmEmitter==NULL)
+ hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &(m_pManifest->m_pAsmEmitter));
+
+ if(SUCCEEDED(hr))
+ {
+ m_pManifest->EmitAssemblyRefs();
+ }
+ }
+ // Emit classes, class members and globals:
+ {
+ Class *pSearch;
+ int i;
+ BOOL bIsUndefClass = FALSE;
+ if(m_fReportProgress) printf("\nEmitting classes:\n");
+ for (i=1; (pSearch = m_lstClass.PEEK(i)); i++) // 0 is <Module>
+ {
+ if(m_fReportProgress)
+ printf("Class %d:\t%s\n",i,pSearch->m_szFQN);
+
+ if(pSearch->m_bIsMaster)
+ {
+ report->msg("Error: Reference to undefined class '%s'\n",pSearch->m_szFQN);
+ bIsUndefClass = TRUE;
+ }
+ if(!EmitClass(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNew = FALSE;
+ }
+ if(bIsUndefClass && !OnErrGo) return E_FAIL;
+
+ if(m_fReportProgress) printf("\nEmitting fields and methods:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)) != NULL; i++)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitFieldsMethods(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+ }
+
+ // All ref'ed items def'ed in this file are emitted, resolve member refs to member defs:
+ if(bClock) bClock->cRef2DefBegin = GetTickCount();
+ hr = ResolveLocalMemberRefs();
+ if(bClock) bClock->cRef2DefEnd = GetTickCount();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+
+ // Local member refs resolved, emit events, props and method impls
+ {
+ Class *pSearch;
+ int i;
+
+ if(m_fReportProgress) printf("\nEmitting events and properties:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitEventsProps(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNewMembers = FALSE;
+ }
+ }
+ if(bClock) bClock->cMDEmit3 = GetTickCount();
+ if(m_MethodImplDList.COUNT())
+ {
+ if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT());
+ if(!EmitMethodImpls())
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+ // Emit the rest of the metadata
+ if(bClock) bClock->cMDEmit4 = GetTickCount();
+ hr = S_OK;
+ if(m_pManifest)
+ {
+ if (FAILED(hr = m_pManifest->EmitManifest())) goto exit;
+ }
+ ResolveLocalMemberRefs(); // in case CAs added some
+ EmitUnresolvedCustomAttributes();
+ // Emit typedefs as special TypeSpecs
+ {
+#define ELEMENT_TYPE_TYPEDEF (ELEMENT_TYPE_MAX+1)
+ TypeDefDescr* pTDD;
+ unsigned __int8* pb;
+ unsigned namesize;
+ while((pTDD = m_TypeDefDList.POP()))
+ {
+ BinStr* pbs = new BinStr();
+ if(pbs)
+ {
+ namesize = 1 + (unsigned)strlen(pTDD->m_szName);
+ pb = pbs->getBuff(namesize + 1 + sizeof(mdToken));
+ *pb = ELEMENT_TYPE_TYPEDEF;
+ memcpy(++pb,pTDD->m_szName,namesize);
+ pTDD->m_tkTypeSpec = ResolveLocalMemberRef(pTDD->m_tkTypeSpec);
+ memcpy(pb+namesize,&(pTDD->m_tkTypeSpec),sizeof(mdToken));
+ if(TypeFromToken(pTDD->m_tkTypeSpec)==mdtCustomAttribute)
+ {
+ CustomDescr* pCA = pTDD->m_pCA;
+ pbs->appendInt32(pCA->tkType);
+ pbs->appendInt32(pCA->tkOwner);
+ if(pCA->pBlob) pbs->append(pCA->pBlob);
+ }
+ ResolveTypeSpec(pbs);
+ delete pbs;
+ }
+ delete pTDD;
+ }
+ }
+ if(bClock) bClock->cMDEmitEnd = GetTickCount();
+
+ hr = DoLocalMemberRefFixups();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+ // Local member refs resolved and fixed up in BinStr method bodies. Emit the bodies.
+ {
+ Class* pClass;
+ Method* pMethod;
+ for (int i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(int j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(!EmitMethodBody(pMethod,NULL))
+ {
+ report->msg("Error: failed to emit body of '%s'\n",pMethod->m_szName);
+ hr = E_FAIL;
+ if(!OnErrGo) goto exit;
+ }
+ pMethod->m_fNewBody = FALSE;
+ }
+ }
+ //while(MethodBody* pMB = m_MethodBodyList.POP()) delete pMB;
+ }
+
+ if (DoGlobalFixups() == FALSE)
+ return E_FAIL;
+
+ if(m_wzResourceFile)
+ {
+#ifdef TARGET_UNIX
+ report->msg("Warning: The Win32 resource file '%S' is ignored and not emitted on xPlatform.\n", m_wzResourceFile);
+#else
+ if (FAILED(hr=m_pCeeFileGen->SetResourceFileName(m_pCeeFile, m_wzResourceFile)))
+ {
+ report->msg("Warning: failed to set Win32 resource file name '%S', hr=0x%8.8X\n The Win32 resource is not emitted.\n",
+ m_wzResourceFile, hr);
+ }
+#endif
+ }
+
+ if (FAILED(hr=CreateTLSDirectory())) goto exit;
+
+ if (FAILED(hr=CreateDebugDirectory())) goto exit;
+
+ if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit;
+
+ // Reserve a buffer for the meta-data
+ DWORD metaDataSize;
+ if (FAILED(hr=m_pEmitter->GetSaveSize(cssAccurate, &metaDataSize))) goto exit;
+ BYTE* metaData;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData))) goto exit;
+ ULONG metaDataOffset;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionDataLen(m_pILSection, &metaDataOffset))) goto exit;
+ metaDataOffset -= metaDataSize;
+ // set managed resource entry, if any
+ if(m_pManifest && m_pManifest->m_dwMResSizeTotal)
+ {
+ mresourceSize = m_pManifest->m_dwMResSizeTotal;
+
+ if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize,
+ sizeof(DWORD), (void**) &mresourceData))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit;
+ }
+ if(m_VTFList.COUNT())
+ {
+ GlobalLabel *pGlobalLabel;
+ VTFEntry* pVTFEntry;
+
+ if(m_pVTable) delete m_pVTable; // can't have both; list takes precedence
+ m_pVTable = new BinStr();
+ hr = S_OK;
+ for(WORD k=0; (pVTFEntry = m_VTFList.POP()); k++)
+ {
+ if((pGlobalLabel = FindGlobalLabel(pVTFEntry->m_szLabel)))
+ {
+ Method* pMD;
+ Class* pClass;
+ m_pVTable->appendInt32(pGlobalLabel->m_GlobalOffset);
+ m_pVTable->appendInt16(pVTFEntry->m_wCount);
+ m_pVTable->appendInt16(pVTFEntry->m_wType);
+ for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(WORD j = 0; (pMD = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(pMD->m_wVTEntry == k+1)
+ {
+ char* ptr;
+ if(SUCCEEDED(hr = m_pCeeFileGen->ComputeSectionPointer(m_pGlobalDataSection,pGlobalLabel->m_GlobalOffset,&ptr)))
+ {
+ DWORD dwDelta;
+ if((pVTFEntry->m_wType & COR_VTABLE_32BIT))
+ {
+ dwDelta = (pMD->m_wVTSlot-1)*(DWORD)sizeof(DWORD);
+ ptr += dwDelta;
+ DWORD* mptr = (DWORD*)ptr;
+ *mptr = (DWORD)(pMD->m_Tok);
+ }
+ else
+ {
+ dwDelta = (pMD->m_wVTSlot-1)*(DWORD)sizeof(ULONGLONG);
+ ptr += dwDelta;
+ ULONGLONG* mptr = (ULONGLONG*)ptr;
+ *mptr = (ULONGLONG)(pMD->m_Tok);
+ }
+ if(pMD->m_dwExportOrdinal != 0xFFFFFFFF)
+ {
+ EATEntry* pEATE = new EATEntry;
+ pEATE->dwOrdinal = pMD->m_dwExportOrdinal;
+ pEATE->szAlias = pMD->m_szExportAlias ? pMD->m_szExportAlias : pMD->m_szName;
+ pEATE->dwStubRVA = EmitExportStub(pGlobalLabel->m_GlobalOffset+dwDelta);
+ m_EATList.PUSH(pEATE);
+ }
+ }
+ else
+ report->msg("Error: Failed to get pointer to label '%s' inVTable fixup\n",pVTFEntry->m_szLabel);
+ }
+ }
+ }
+ }
+ else
+ {
+ report->msg("Error: Unresolved label '%s' in VTable fixup\n",pVTFEntry->m_szLabel);
+ hr = E_FAIL;
+ }
+ delete pVTFEntry;
+ }
+ if(FAILED(hr)) goto exit;
+ }
+ if(m_pVTable)
+ {
+ ULONG i, N = m_pVTable->length()/sizeof(DWORD);
+ ULONG ulVTableOffset;
+ m_pCeeFileGen->GetSectionDataLen (m_pILSection, &ulVTableOffset);
+ // SetVTableEntry will align VTable on DWORD
+ ulVTableOffset = (ulVTableOffset + (ULONG)sizeof(DWORD) - 1) & ~((ULONG)sizeof(DWORD) - 1);
+ if (FAILED(hr=m_pCeeFileGen->SetVTableEntry64(m_pCeeFile, m_pVTable->length(),(void*)(m_pVTable->ptr())))) goto exit; // @WARNING: casting down from pointer-size to DWORD
+ for(i = 0; i < N; i+=2)
+ {
+ m_pCeeFileGen->AddSectionReloc(m_pILSection,
+ ulVTableOffset+(i*sizeof(DWORD)),
+ m_pGlobalDataSection,
+ srRelocAbsolute);
+ }
+ }
+ if(m_EATList.COUNT())
+ {
+ if(FAILED(CreateExportDirectory())) goto exit;
+ m_dwComImageFlags &= ~COMIMAGE_FLAGS_ILONLY;
+ if (m_dwCeeFileFlags & ICEE_CREATE_MACHINE_I386)
+ COR_SET_32BIT_REQUIRED(m_dwComImageFlags);
+ }
+ if (m_fWindowsCE)
+ {
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit;
+
+ if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit;
+ }
+ else
+ {
+ if (m_dwCeeFileFlags & ICEE_CREATE_MACHINE_ARM || m_fAppContainer)
+ {
+ // For AppContainer and ARM, you must have a minimum subsystem version of 6.02
+ m_wSSVersionMajor = (m_wSSVersionMajor < 6) ? 6 : m_wSSVersionMajor;
+ m_wSSVersionMinor = (m_wSSVersionMinor < 2 && m_wSSVersionMajor <= 6) ? 2 : m_wSSVersionMinor;
+
+ }
+
+ // Default the subsystem, instead the user doesn't set it to GUI or CUI
+ if (m_dwSubsystem == (DWORD)-1)
+ // The default for ILAsm previously was CUI, so that should be the default behavior...
+ m_dwSubsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
+
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, m_wSSVersionMajor, m_wSSVersionMinor))) goto exit;
+ }
+
+ if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit;
+
+ if(m_dwFileAlignment)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit;
+ }
+ if(m_stBaseAddress)
+ {
+
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_PE64)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetImageBase64(m_pCeeFile, m_stBaseAddress))) goto exit;
+ }
+ else
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, (size_t)m_stBaseAddress))) goto exit;
+ }
+ }
+ if(m_stSizeOfStackReserve || m_fAppContainer || m_fHighEntropyVA)
+ {
+ PIMAGE_NT_HEADERS pNT;
+ PIMAGE_SECTION_HEADER pSect;
+ ULONG ulNumSect;
+ if(FAILED(hr=m_pCeeFileGen->GetHeaderInfo(m_pCeeFile,&pNT,&pSect,&ulNumSect))) goto exit;
+ if(m_dwCeeFileFlags & ICEE_CREATE_FILE_PE64)
+ {
+ PIMAGE_OPTIONAL_HEADER64 pOpt = (PIMAGE_OPTIONAL_HEADER64)(&pNT->OptionalHeader);
+ if (m_stSizeOfStackReserve)
+ pOpt->SizeOfStackReserve = VAL64(m_stSizeOfStackReserve);
+ if (m_fAppContainer)
+ pOpt->DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_APPCONTAINER;
+ if (m_fHighEntropyVA)
+ pOpt->DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA;
+ }
+ else
+ {
+ PIMAGE_OPTIONAL_HEADER32 pOpt = (PIMAGE_OPTIONAL_HEADER32)(&pNT->OptionalHeader);
+ if (m_stSizeOfStackReserve)
+ pOpt->SizeOfStackReserve = (DWORD)VAL32(m_stSizeOfStackReserve);
+ if (m_fAppContainer)
+ pOpt->DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_APPCONTAINER;
+ if (m_fHighEntropyVA)
+ pOpt->DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA;
+ }
+ }
+ //Compute all the RVAs
+ if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit;
+
+ // Fix up any fields that have RVA associated with them
+ if (m_fHaveFieldsWithRvas) {
+ hr = S_OK;
+ ULONG dataSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit;
+
+ ULONG tlsSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit;
+
+ ULONG ilSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pILSection, &ilSectionRVA))) goto exit;
+
+ FieldDescriptor* pListFD;
+ Class* pClass;
+ for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++)
+ {
+ if (pListFD->m_rvaLabel != 0)
+ {
+ DWORD rva;
+ if(*(pListFD->m_rvaLabel)=='@')
+ {
+ rva = (DWORD)atoi(pListFD->m_rvaLabel + 1);
+ }
+ else
+ {
+ GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel);
+ if (pLabel == 0)
+ {
+ report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName);
+ hr = E_FAIL;
+ continue;
+ }
+
+ rva = pLabel->m_GlobalOffset;
+ if (pLabel->m_Section == m_pTLSSection)
+ rva += tlsSectionRVA;
+ else if (pLabel->m_Section == m_pILSection)
+ rva += ilSectionRVA;
+ else {
+ _ASSERTE(pLabel->m_Section == m_pGlobalDataSection);
+ rva += dataSectionRVA;
+ }
+ }
+ if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit;
+ }
+ }
+ }
+ if (FAILED(hr)) goto exit;
+ }
+
+ if(bClock) bClock->cFilegenBegin = GetTickCount();
+ // actually output the meta-data
+ if (FAILED(hr=m_pCeeFileGen->EmitMetaDataAt(m_pCeeFile, m_pEmitter, m_pILSection, metaDataOffset, metaData, metaDataSize))) goto exit;
+
+ if((m_wMSVmajor < 0xFF)&&(m_wMSVminor < 0xFF))
+ {
+ STORAGESIGNATURE *pSSig = (STORAGESIGNATURE *)metaData;
+ BYTE* pb = metaData;
+ pb += 3*sizeof(DWORD)+2*sizeof(WORD)+VAL32(pSSig->iVersionString);
+ pb = (BYTE*)(((size_t)pb + 3) & ~3);
+ PSTORAGEHEADER pSHdr = (PSTORAGEHEADER)pb;
+ PSTORAGESTREAM pStr = (PSTORAGESTREAM)(pSHdr+1);
+ for(short iStr = 1; iStr <= VAL16(pSHdr->iStreams); iStr++)
+ {
+ if((strcmp(pStr->rcName,"#-")==0)||(strcmp(pStr->rcName,"#~")==0))
+ {
+ pb = metaData + VAL32(pStr->iOffset); // start of the stream header
+ pb += sizeof(DWORD); // skip Reserved
+ *pb = VAL16(m_wMSVmajor)&0xFF;
+ *(pb+1) = VAL16(m_wMSVminor)&0xFF;
+ break;
+ }
+ pb = (BYTE*)pStr;
+ pb += 2*sizeof(DWORD)+strlen(pStr->rcName)+1;
+ pb = (BYTE*)(((size_t)pb + 3) & ~3);
+ pStr = (PSTORAGESTREAM)pb;
+ }
+ }
+
+ if(m_fTolerateDupMethods) // means that there are /ENC files
+ {
+ if(m_pbsMD) delete m_pbsMD;
+ m_pbsMD = new BinStr();
+ memcpy(m_pbsMD->getBuff(metaDataSize),metaData,metaDataSize);
+ }
+ // actually output the resources
+ if(mresourceSize && mresourceData)
+ {
+ size_t i, N = m_pManifest->m_dwMResNum, sizeread, L;
+ BYTE *ptr = (BYTE*)mresourceData;
+ BOOL mrfail = FALSE;
+ FILE* pFile = NULL;
+ char sz[2048];
+ for(i=0; i < N; i++)
+ {
+ m_pManifest->m_fMResNew[i] = FALSE;
+ memset(sz,0,2048);
+ WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL);
+ L = m_pManifest->m_dwMResSize[i];
+ sizeread = 0;
+ memcpy(ptr,&L,sizeof(DWORD));
+ ptr += sizeof(DWORD);
+ if(fopen_s(&pFile,sz,"rb") == 0)
+ {
+ sizeread = fread((void *)ptr,1,L,pFile);
+ fclose(pFile);
+ ptr += sizeread;
+ }
+ else
+ {
+ report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ }
+ if(sizeread < L)
+ {
+ report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ L -= sizeread;
+ memset(ptr,0,L);
+ ptr += L;
+ }
+ }
+ if(mrfail)
+ {
+ hr = E_FAIL;
+ goto exit;
+ }
+ }
+ /*
+ if((m_wRTVmajor < 0xFFFF)&&(m_wRTVminor < 0xFFFF))
+ {
+ IMAGE_COR20_HEADER* pCorH;
+ if(FAILED(hr=m_pCeeFileGen->GetCorHeader(m_pCeeFile,&pCorH))) goto exit;
+ pCorH->MajorRuntimeVersion = VAL16(m_wRTVmajor);
+ pCorH->MinorRuntimeVersion = VAL16(m_wRTVminor);
+ }
+ */
+ // Generate the file -- moved to main
+ //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit;
+
+
+ hr = S_OK;
+
+exit:
+ return hr;
+}
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
diff --git a/src/coreclr/ilasm/writer_enc.cpp b/src/coreclr/ilasm/writer_enc.cpp
new file mode 100644
index 00000000000..96a637b4dec
--- /dev/null
+++ b/src/coreclr/ilasm/writer_enc.cpp
@@ -0,0 +1,608 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+// writer_ENC.cpp
+//
+
+//
+#include "ilasmpch.h"
+
+#include "assembler.h"
+
+int ist=0;
+#define REPT_STEP //printf("Step %d\n",++ist);
+
+HRESULT Assembler::InitMetaDataForENC(__in __nullterminated WCHAR* wzOrigFileName, BOOL generatePdb, PdbFormat pdbFormat)
+{
+ HRESULT hr = E_FAIL;
+
+ if((wzOrigFileName==NULL)||(*wzOrigFileName == 0)||(m_pDisp==NULL)) return hr;
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+ if (m_pImporter != NULL)
+ {
+ m_pImporter->Release();
+ m_pImporter = NULL;
+ }
+ if (m_pEmitter != NULL)
+ {
+ m_pEmitter->Release();
+ m_pEmitter = NULL;
+ }
+ if (m_pPortablePdbWriter != NULL)
+ {
+ delete m_pPortablePdbWriter;
+ m_pPortablePdbWriter = NULL;
+ }
+ //WszSetEnvironmentVariable(L"COMP_ENC_OPENSCOPE", wzOrigFileName);
+ //hr = m_pDisp->DefineScope(CLSID_CorMetaDataRuntime, 0, IID_IMetaDataEmit2,
+ // (IUnknown **)&m_pEmitter);
+
+ if((m_pbsMD==NULL)||(m_pbsMD->length()==0))
+ {
+ _ASSERTE(!"NO BASE METADATA!");
+ return E_FAIL;
+ }
+
+ VARIANT encOption;
+ V_VT(&encOption) = VT_UI4;
+ V_UI4(&encOption) = MDUpdateENC;
+ m_pDisp->SetOption(MetaDataSetENC, &encOption);
+ V_UI4(&encOption) = MDErrorOutOfOrderDefault;
+ m_pDisp->SetOption(MetaDataErrorIfEmitOutOfOrder, &encOption);
+ hr = m_pDisp->OpenScopeOnMemory( m_pbsMD->ptr(),
+ m_pbsMD->length(),
+ ofWrite,
+ IID_IMetaDataEmit2,
+ (IUnknown **)&m_pEmitter);
+ _ASSERTE(SUCCEEDED(hr));
+ if (FAILED(hr))
+ goto exit;
+
+ m_pManifest->SetEmitter(m_pEmitter);
+ if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataImport2, (void**)&m_pImporter)))
+ goto exit;
+
+ //WszSetEnvironmentVariable(L"COMP_ENC_EMIT", wzOrigFileName);
+ if(!Init(generatePdb, pdbFormat)) goto exit; // close and re-open CeeFileGen and CeeFile
+ hr = S_OK;
+
+
+exit:
+ return hr;
+}
+/*********************************************************************************/
+
+BOOL Assembler::EmitFieldsMethodsENC(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all field definition metadata tokens
+ if((pClass->m_FieldDList.COUNT()))
+ {
+ FieldDescriptor* pFD;
+ int j;
+ for(j=0, n=0; (pFD = pClass->m_FieldDList.PEEK(j)); j++) // can't use POP here: we'll need field list for props
+ {
+ if(pFD->m_fNew)
+ {
+ if(!EmitField(pFD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pFD->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Fields: %d;\t",n);
+ }
+ // Fields are emitted; emit the class layout
+ {
+ COR_FIELD_OFFSET *pOffsets = NULL;
+ ULONG ul = pClass->m_ulPack;
+ ULONG N = pClass->m_dwNumFieldsWithOffset;
+
+ EmitSecurityInfo(pClass->m_cl,
+ pClass->m_pPermissions,
+ pClass->m_pPermissionSets);
+ pClass->m_pPermissions = NULL;
+ pClass->m_pPermissionSets = NULL;
+ if((pClass->m_ulSize != 0xFFFFFFFF)||(ul != 0)||(N != 0))
+ {
+ if(IsTdAutoLayout(pClass->m_Attr)) report->warn("Layout specified for auto-layout class\n");
+ if((ul > 128)||((ul & (ul-1)) !=0 ))
+ report->error("Invalid packing parameter (%d), must be 1,2,4,8...128\n",pClass->m_ulPack);
+ if(N)
+ {
+ pOffsets = new COR_FIELD_OFFSET[N+1];
+ ULONG i,j=0;
+ FieldDescriptor *pFD;
+ for(i=0; (pFD = pClass->m_FieldDList.PEEK(i)); i++)
+ {
+ if(pFD->m_ulOffset != 0xFFFFFFFF)
+ {
+ pOffsets[j].ridOfField = RidFromToken(pFD->m_fdFieldTok);
+ pOffsets[j].ulOffset = pFD->m_ulOffset;
+ j++;
+ }
+ }
+ _ASSERTE(j == N);
+ pOffsets[j].ridOfField = mdFieldDefNil;
+ }
+ m_pEmitter->SetClassLayout (
+ pClass->m_cl, // [IN] typedef
+ ul, // [IN] packing size specified as 1, 2, 4, 8, or 16
+ pOffsets, // [IN] array of layout specification
+ pClass->m_ulSize); // [IN] size of the class
+ if(pOffsets) delete [] pOffsets;
+ }
+ }
+ // emit all method definition metadata tokens
+ if((pClass->m_MethodList.COUNT()))
+ {
+ Method* pMethod;
+ int i;
+
+ for(i=0, n=0; (pMethod = pClass->m_MethodList.PEEK(i));i++)
+ {
+ if(pMethod->m_fNew)
+ {
+ if(!EmitMethod(pMethod))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pMethod->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Methods: %d;\t",n);
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+BOOL Assembler::EmitEventsPropsENC(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all event definition metadata tokens
+ if((pClass->m_EventDList.COUNT()))
+ {
+ EventDescriptor* pED;
+ int j;
+ for(j=0,n=0; (pED = pClass->m_EventDList.PEEK(j)); j++) // can't use POP here: we'll need event list for props
+ {
+ if(pED->m_fNew)
+ {
+ if(!EmitEvent(pED))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pED->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Events: %d;\t",n);
+ }
+ // emit all property definition metadata tokens
+ if((pClass->m_PropDList.COUNT()))
+ {
+ PropDescriptor* pPD;
+ int j;
+
+ for(j=0,n=0; (pPD = pClass->m_PropDList.PEEK(j)); j++)
+ {
+ if(pPD->m_fNew)
+ {
+ if(!EmitProp(pPD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pPD->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Props: %d;\t",n);
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+HRESULT Assembler::CreateDeltaFiles(__in __nullterminated WCHAR *pwzOutputFilename)
+{
+ HRESULT hr;
+ DWORD mresourceSize = 0;
+ BYTE* mresourceData = NULL;
+ WCHAR* pEnd = NULL;
+
+ if(m_fReportProgress) printf("Creating DMETA,DIL files\n");
+ if (!m_pEmitter)
+ {
+ printf("Error: Cannot create a PE file with no metadata\n");
+ return E_FAIL;
+ }
+REPT_STEP
+ if(m_pManifest)
+ {
+ hr = S_OK;
+ if(m_pManifest->m_pAsmEmitter==NULL)
+ hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &(m_pManifest->m_pAsmEmitter));
+
+ if(SUCCEEDED(hr))
+ {
+ m_pManifest->EmitAssemblyRefs();
+ }
+ }
+ // Emit classes, class members and globals:
+ {
+ Class *pSearch;
+ int i;
+ BOOL bIsUndefClass = FALSE;
+ if(m_fReportProgress) printf("\nEmitting classes:\n");
+ for (i=1; (pSearch = m_lstClass.PEEK(i)); i++) // 0 is <Module>
+ {
+ if(pSearch->m_fNew)
+ {
+ if(m_fReportProgress)
+ printf("Class %d:\t%s\n",i,pSearch->m_szFQN);
+
+ if(pSearch->m_bIsMaster)
+ {
+ report->msg("Error: Reference to undefined class '%s'\n",pSearch->m_szFQN);
+ bIsUndefClass = TRUE;
+ }
+ if(!EmitClass(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNew = FALSE;
+ }
+ }
+ if(bIsUndefClass && !OnErrGo) return E_FAIL;
+
+ if(m_fReportProgress) printf("\nEmitting fields and methods:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)) != NULL; i++)
+ {
+ if(pSearch->m_fNewMembers)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitFieldsMethodsENC(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+ }
+ }
+REPT_STEP
+
+ // All ref'ed items def'ed in this file are emitted, resolve member refs to member defs:
+ hr = ResolveLocalMemberRefs();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+
+ // Local member refs resolved, emit events, props and method impls
+ {
+ Class *pSearch;
+ int i;
+
+ if(m_fReportProgress) printf("\nEmitting events and properties:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
+ {
+ if(pSearch->m_fNewMembers)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitEventsPropsENC(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNewMembers = FALSE;
+ }
+ }
+ }
+ if(m_MethodImplDList.COUNT())
+ {
+ if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT());
+ if(!EmitMethodImpls())
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+REPT_STEP
+ // Emit the rest of the metadata
+ hr = S_OK;
+ if(m_pManifest)
+ {
+ if (FAILED(hr = m_pManifest->EmitManifest())) goto exit;
+ }
+ ResolveLocalMemberRefs(); // in case CAs added some
+ EmitUnresolvedCustomAttributes();
+REPT_STEP
+
+ hr = DoLocalMemberRefFixups();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+
+ // Local member refs resolved and fixed up in BinStr method bodies. Emit the bodies to a separate file.
+ pEnd = &pwzOutputFilename[wcslen(pwzOutputFilename)];
+ {
+ Class* pClass;
+ Method* pMethod;
+ FILE* pF = NULL;
+ wcscat_s(pwzOutputFilename,MAX_SCOPE_LENGTH,W(".dil"));
+ if(_wfopen_s(&pF,pwzOutputFilename,W("wb"))==0)
+ {
+ int i,j,L=0,M=0;
+ BinStr bsOut;
+ for (i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(pMethod->m_fNewBody)
+ {
+ L+= pMethod->m_pbsBody->length()+3;
+ M++;
+ }
+ }
+ }
+ bsOut.getBuff(L+sizeof(DWORD)); // to avoid reallocs
+ bsOut.remove(L);
+ for (i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(pMethod->m_fNewBody)
+ {
+ if(!EmitMethodBody(pMethod,&bsOut))
+ {
+ report->msg("Error: failed to emit body of '%s'\n",pMethod->m_szName);
+ hr = E_FAIL;
+ if(!OnErrGo)
+ {
+ fclose(pF);
+ *pEnd = 0;
+ goto exit;
+ }
+ }
+ pMethod->m_fNewBody = FALSE;
+ }
+ }
+ }
+ *((DWORD*)(bsOut.ptr())) = bsOut.length() - sizeof(DWORD);
+ fwrite(bsOut.ptr(),bsOut.length(),1,pF);
+ fclose(pF);
+ }
+ else
+ report->msg("Error: failed to open file '%S'\n",pwzOutputFilename);
+
+ *pEnd = 0;
+ }
+REPT_STEP
+
+ //if (DoGlobalFixups() == FALSE)
+ // return E_FAIL;
+
+ //if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit;
+
+ // Emit the meta-data to a separate file
+ IMetaDataEmit2* pENCEmitter;
+ if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataEmit2, (void**)&pENCEmitter)))
+ goto exit;
+
+ DWORD metaDataSize;
+ if (FAILED(hr=pENCEmitter->GetDeltaSaveSize(cssAccurate, &metaDataSize))) goto exit;
+
+ wcscat_s(pwzOutputFilename,MAX_SCOPE_LENGTH,W(".dmeta"));
+ pENCEmitter->SaveDelta(pwzOutputFilename,0); // second arg (dwFlags) is not used
+ *pEnd = 0;
+ pENCEmitter->Release();
+
+ // apply delta to create basis for the next ENC iteration
+ if(m_pbsMD)
+ {
+ IMetaDataEmit2* pBaseMDEmit = NULL;
+ if(FAILED(hr = m_pDisp->OpenScopeOnMemory(m_pbsMD->ptr(),
+ m_pbsMD->length(),
+ ofWrite,
+ IID_IMetaDataEmit2,
+ (IUnknown **)&pBaseMDEmit))) goto exit;
+
+ if(FAILED(hr = pBaseMDEmit->ApplyEditAndContinue((IUnknown*)m_pImporter))) goto exit;
+ delete m_pbsMD;
+ if((m_pbsMD = new BinStr()) != NULL)
+ {
+ DWORD cb;
+ hr = pBaseMDEmit->GetSaveSize(cssAccurate,&cb);
+ BYTE* pb = m_pbsMD->getBuff(cb);
+ hr = pBaseMDEmit->SaveToMemory(pb,cb);
+ }
+ pBaseMDEmit->Release();
+ }
+
+
+ // release all interfaces
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+ if (m_pImporter != NULL)
+ {
+ m_pImporter->Release();
+ m_pImporter = NULL;
+ }
+ if (m_pEmitter != NULL)
+ {
+ m_pEmitter->Release();
+ m_pEmitter = NULL;
+ }
+ if (m_pPortablePdbWriter != NULL)
+ {
+ delete m_pPortablePdbWriter;
+ m_pPortablePdbWriter = NULL;
+ }
+
+ return S_OK;
+
+REPT_STEP
+
+ // set managed resource entry, if any
+ if(m_pManifest && m_pManifest->m_dwMResSizeTotal)
+ {
+ mresourceSize = m_pManifest->m_dwMResSizeTotal;
+
+ if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize,
+ sizeof(DWORD), (void**) &mresourceData))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit;
+ }
+REPT_STEP
+ /*
+ if (m_fWindowsCE)
+ {
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit;
+
+ if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit;
+ }
+ else if(m_dwSubsystem != (DWORD)-1)
+ {
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, 4, 0))) goto exit;
+ }
+
+ if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit;
+
+ if(m_dwFileAlignment)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit;
+ }
+ if(m_stBaseAddress)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, m_stBaseAddress))) goto exit;
+ }
+ */
+REPT_STEP
+ //Compute all the RVAs
+ if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit;
+
+REPT_STEP
+ // Fix up any fields that have RVA associated with them
+/*
+ if (m_fHaveFieldsWithRvas) {
+ hr = S_OK;
+ ULONG dataSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit;
+
+ ULONG tlsSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit;
+
+ FieldDescriptor* pListFD;
+ Class* pClass;
+ for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++)
+ {
+ if (pListFD->m_rvaLabel != 0)
+ {
+ DWORD rva;
+ if(*(pListFD->m_rvaLabel)=='@')
+ {
+ rva = (DWORD)atoi(pListFD->m_rvaLabel + 1);
+ }
+ else
+ {
+ GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel);
+ if (pLabel == 0)
+ {
+ report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName);
+ hr = E_FAIL;
+ continue;
+ }
+
+ rva = pLabel->m_GlobalOffset;
+ if (pLabel->m_Section == m_pTLSSection)
+ rva += tlsSectionRVA;
+ else {
+ _ASSERTE(pLabel->m_Section == m_pGlobalDataSection);
+ rva += dataSectionRVA;
+ }
+ }
+ if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit;
+ }
+ }
+ }
+ if (FAILED(hr)) goto exit;
+ }
+REPT_STEP
+*/
+
+REPT_STEP
+ // actually output the resources
+ if(mresourceSize && mresourceData)
+ {
+ size_t i, N = m_pManifest->m_dwMResNum, sizeread, L;
+ BYTE *ptr = (BYTE*)mresourceData;
+ BOOL mrfail = FALSE;
+ FILE* pFile = NULL;
+ char sz[2048];
+ for(i=0; i < N; i++)
+ {
+ if(!m_pManifest->m_fMResNew[i]) continue;
+ m_pManifest->m_fMResNew[i] = FALSE;
+ memset(sz,0,2048);
+ WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL);
+ L = m_pManifest->m_dwMResSize[i];
+ sizeread = 0;
+ memcpy(ptr,&L,sizeof(DWORD));
+ ptr += sizeof(DWORD);
+ pFile = NULL;
+ if(fopen_s(&pFile,sz,"rb")==0)
+ {
+ sizeread = fread((void *)ptr,1,L,pFile);
+ fclose(pFile);
+ ptr += sizeread;
+ }
+ else
+ {
+ report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ }
+ if(sizeread < L)
+ {
+ report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ L -= sizeread;
+ memset(ptr,0,L);
+ ptr += L;
+ }
+ }
+ if(mrfail)
+ {
+ hr = E_FAIL;
+ goto exit;
+ }
+ }
+REPT_STEP
+
+ // Generate the file -- moved to main
+ //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit;
+
+
+ hr = S_OK;
+
+exit:
+ return hr;
+}