diff options
Diffstat (limited to 'src/vm/assemblyspec.cpp')
-rw-r--r-- | src/vm/assemblyspec.cpp | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp index 9ec1d97086..7f2829de99 100644 --- a/src/vm/assemblyspec.cpp +++ b/src/vm/assemblyspec.cpp @@ -19,7 +19,6 @@ #include <stdlib.h> #include "assemblyspec.hpp" -#include "security.h" #include "eeconfig.h" #include "strongname.h" #include "strongnameholders.h" @@ -495,18 +494,68 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn // version gc.Version = AllocateObject(pVersion); - - MethodDescCallSite ctorMethod(METHOD__VERSION__CTOR); - - ARG_SLOT VersionArgs[5] = + // BaseAssemblySpec and AssemblyName properties store uint16 components for the version. Version and AssemblyVersion + // store int32 or uint32. When the former are initialized from the latter, the components are truncated to uint16 size. + // When the latter are initialized from the former, they are zero-extended to int32 size. For uint16 components, the max + // value is used to indicate an unspecified component. For int32 components, -1 is used. Since we're initializing a + // Version from an assembly version, map the uint16 unspecified value to the int32 size. + int componentCount = 2; + if (m_context.usBuildNumber != (USHORT)-1) { - ObjToArgSlot(gc.Version), - (ARG_SLOT) m_context.usMajorVersion, - (ARG_SLOT) m_context.usMinorVersion, - (ARG_SLOT) m_context.usBuildNumber, - (ARG_SLOT) m_context.usRevisionNumber, - }; - ctorMethod.Call(VersionArgs); + ++componentCount; + if (m_context.usRevisionNumber != (USHORT)-1) + { + ++componentCount; + } + } + switch (componentCount) + { + case 2: + { + // Call Version(int, int) because Version(int, int, int, int) does not allow passing the unspecified value -1 + MethodDescCallSite ctorMethod(METHOD__VERSION__CTOR_Ix2); + ARG_SLOT VersionArgs[] = + { + ObjToArgSlot(gc.Version), + (ARG_SLOT) m_context.usMajorVersion, + (ARG_SLOT) m_context.usMinorVersion + }; + ctorMethod.Call(VersionArgs); + break; + } + + case 3: + { + // Call Version(int, int, int) because Version(int, int, int, int) does not allow passing the unspecified value -1 + MethodDescCallSite ctorMethod(METHOD__VERSION__CTOR_Ix3); + ARG_SLOT VersionArgs[] = + { + ObjToArgSlot(gc.Version), + (ARG_SLOT) m_context.usMajorVersion, + (ARG_SLOT) m_context.usMinorVersion, + (ARG_SLOT) m_context.usBuildNumber + }; + ctorMethod.Call(VersionArgs); + break; + } + + default: + { + // Call Version(int, int, int, int) + _ASSERTE(componentCount == 4); + MethodDescCallSite ctorMethod(METHOD__VERSION__CTOR_Ix4); + ARG_SLOT VersionArgs[] = + { + ObjToArgSlot(gc.Version), + (ARG_SLOT) m_context.usMajorVersion, + (ARG_SLOT) m_context.usMinorVersion, + (ARG_SLOT) m_context.usBuildNumber, + (ARG_SLOT) m_context.usRevisionNumber + }; + ctorMethod.Call(VersionArgs); + break; + } + } } // cultureinfo @@ -527,13 +576,13 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn strCtor.Call(args); } - // public key or token byte array if (m_pbPublicKeyOrToken) - Security::CopyEncodingToByteArray((BYTE*) m_pbPublicKeyOrToken, - m_cbPublicKeyOrToken, - (OBJECTREF*) &gc.PublicKeyOrToken); + { + gc.PublicKeyOrToken = (U1ARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_U1, m_cbPublicKeyOrToken); + memcpyNoGCRefs(gc.PublicKeyOrToken->m_Array, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken); + } // simple name if(GetName()) |