//************************************************ // // This function will not increase the argument count. It only fills in bytes // in the signature based on clsArgument. This helper is called for return type. // //************************************************ private void AddOneArgTypeHelper(Type clsArgument) { if (clsArgument == null) { throw new ArgumentNullException("clsArgument"); } if (clsArgument is TypeBuilder) { TypeBuilder clsBuilder = (TypeBuilder)clsArgument; TypeToken tkType; if (clsBuilder.Module == m_module) { tkType = clsBuilder.TypeToken; } else { tkType = m_module.GetTypeToken(clsArgument); } if (clsArgument.IsValueType) { InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE); } else { InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS); } } else if (clsArgument is EnumBuilder) { TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder; TypeToken tkType; if (clsBuilder.Module == m_module) { tkType = clsBuilder.TypeToken; } else { tkType = m_module.GetTypeToken(clsArgument); } if (clsArgument.IsValueType) { InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE); } else { InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS); } } else if (clsArgument is SymbolType) { SignatureBuffer sigBuf = new SignatureBuffer(); SymbolType symType = (SymbolType)clsArgument; int i; // convert SymbolType to blob form symType.ToSigBytes(m_module, sigBuf); // add to our signature buffer // ensure the size of the signature buffer if ((m_currSig + sigBuf.m_curPos) > m_signature.Length) { m_signature = ExpandArray(m_signature, m_currSig + sigBuf.m_curPos); } // copy over the signature segment for (i = 0; i < sigBuf.m_curPos; i++) { m_signature[m_currSig++] = sigBuf.m_buf[i]; } } else { if (clsArgument.IsByRef) { AddElementType(ELEMENT_TYPE_BYREF); clsArgument = clsArgument.GetElementType(); } if (clsArgument.IsArray || clsArgument.IsPointer) { AddArrayOrPointer(clsArgument); return; } RuntimeType rType = clsArgument as RuntimeType; int type = rType != null?GetCorElementTypeFromClass(rType) : ELEMENT_TYPE_MAX; if (IsSimpleType(type)) { // base element type AddElementType(type); } else { if (clsArgument.IsValueType) { InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_VALUETYPE); } else { if (clsArgument == SystemObject) { // use the short cut for System.Object AddElementType(ELEMENT_TYPE_OBJECT); } else if (clsArgument == SystemString) { // use the short cut for System.String AddElementType(ELEMENT_TYPE_STRING); } else { InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_CLASS); } } } } }
//************************************************ // // This function will not increase the argument count. It only fills in bytes // in the signature based on clsArgument. This helper is called for return type. // //************************************************ private void AddOneArgTypeHelper(Type clsArgument) { if (clsArgument == null) throw new ArgumentNullException("clsArgument"); if (clsArgument is TypeBuilder) { TypeBuilder clsBuilder = (TypeBuilder) clsArgument; TypeToken tkType; if (clsBuilder.Module == m_module) { tkType = clsBuilder.TypeToken; } else { tkType = m_module.GetTypeToken(clsArgument); } if (clsArgument.IsValueType) { InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE); } else { InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS); } } else if (clsArgument is EnumBuilder) { TypeBuilder clsBuilder = ((EnumBuilder) clsArgument).m_typeBuilder; TypeToken tkType; if (clsBuilder.Module == m_module) { tkType = clsBuilder.TypeToken; } else { tkType = m_module.GetTypeToken(clsArgument); } if (clsArgument.IsValueType) { InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE); } else { InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS); } } else if (clsArgument is SymbolType) { SignatureBuffer sigBuf = new SignatureBuffer(); SymbolType symType = (SymbolType) clsArgument; int i; // convert SymbolType to blob form symType.ToSigBytes(m_module, sigBuf); // add to our signature buffer // ensure the size of the signature buffer if ((m_currSig + sigBuf.m_curPos) > m_signature.Length) m_signature = ExpandArray(m_signature, m_currSig + sigBuf.m_curPos); // copy over the signature segment for (i = 0; i < sigBuf.m_curPos; i++) { m_signature[m_currSig++] = sigBuf.m_buf[i]; } } else { if (clsArgument.IsByRef) { AddElementType(ELEMENT_TYPE_BYREF); clsArgument = clsArgument.GetElementType(); } if (clsArgument.IsArray || clsArgument.IsPointer) { AddArrayOrPointer(clsArgument); return; } RuntimeType rType = clsArgument as RuntimeType; int type = rType != null ? GetCorElementTypeFromClass(rType) : ELEMENT_TYPE_MAX; if (IsSimpleType(type)) { // base element type AddElementType(type); } else { if (clsArgument.IsValueType) { InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_VALUETYPE); } else { if (clsArgument == SystemObject) // use the short cut for System.Object AddElementType(ELEMENT_TYPE_OBJECT); else if (clsArgument == SystemString) // use the short cut for System.String AddElementType(ELEMENT_TYPE_STRING); else InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_CLASS); } } } }
//*********************************************** // // Translate the type into signature format // //*********************************************** internal void ToSigBytes(ModuleBuilder moduleBuilder, SignatureBuffer sigBuf) { bool isArray = false; // now process whatever information that we have here. if (m_typeKind == TypeKind.IsArray) { if (m_cRank == 1 && m_iaLowerBound[0] == 0 && m_iaUpperBound[0] == -1) { // zero lower bound, unspecified count. So simplify to SZARRAY sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_SZARRAY); } else { // ELEMENT_TYPE_ARRAY : ARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ... sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_ARRAY); isArray = true; } } else if (m_typeKind == TypeKind.IsPointer) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_PTR); } else if (m_typeKind == TypeKind.IsByRef) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_BYREF); } if (m_baseType is SymbolType) { // the base type is still a SymbolType. So recursively form the signature blob ((SymbolType) m_baseType).ToSigBytes(moduleBuilder, sigBuf); } else { // we have walked to the most nested class. int cvType; if (m_baseType is RuntimeType) cvType = SignatureHelper.GetCorElementTypeFromClass((RuntimeType)m_baseType); else cvType = SignatureHelper.ELEMENT_TYPE_MAX; if (SignatureHelper.IsSimpleType(cvType)) { sigBuf.AddElementType(cvType); } else { if (m_baseType.IsValueType) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_VALUETYPE); sigBuf.AddToken(moduleBuilder.GetTypeToken(m_baseType).Token); } else if (m_baseType == SignatureHelper.SystemObject) sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_OBJECT); else if (m_baseType == SignatureHelper.SystemString) sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_STRING); else { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_CLASS); sigBuf.AddToken(moduleBuilder.GetTypeToken(m_baseType).Token); } } } if (isArray) { // ELEMENT_TYPE_ARRAY : ARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ... // generic array!! Put in the dimension, sizes and lower bounds information. int index; int i; sigBuf.AddData(m_cRank); // determine the number of dimensions that we have to specify the size for (index = m_cRank - 1; index >= 0 && m_iaLowerBound[index] > m_iaUpperBound[index]; index--); sigBuf.AddData(index + 1); for (i=0; i <= index; i++) { if (m_iaLowerBound[index] > m_iaUpperBound[index]) { // bad signature!! throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); } else { sigBuf.AddData(m_iaUpperBound[i] - m_iaLowerBound[i] + 1); } } // loop from last dimension back to first dimension. Look for the first one that does // not have lower bound equals to zero. If this is index, then 0..index has to specify the // lower bound. for (index = m_cRank - 1; index >= 0 && m_iaLowerBound[index] == 0; index--); sigBuf.AddData(index + 1); for (i=0; i <= index; i++) { sigBuf.AddInteger(m_iaLowerBound[i]); } } }
// Return a token for the class relative to the Module. Tokens // are used to indentify objects when the objects are used in IL // instructions. Tokens are always relative to the Module. For example, // the token value for System.String is likely to be different from // Module to Module. Calling GetTypeToken will cause a reference to be // added to the Module. This reference becomes a perminate part of the Module, // multiple calles to this method with the same class have no additional side affects. // // This function is optimized to use the TypeDef token if Type is within the same module. // We should also be aware of multiple dynamic modules and multiple implementation of Type!!! /// <include file='doc\ModuleBuilder.uex' path='docs/doc[@for="ModuleBuilder.GetTypeToken"]/*' /> public TypeToken GetTypeToken(Type type) { try { Enter(); TypeToken tkToken; bool isSameAssembly; bool isSameModule; Module refedModule; String strRefedModuleFileName = String.Empty; // assume that referenced module is non-transient. Only if the referenced module is dynamic, // and transient, this variable will be set to true. bool isRefedModuleTransient = false; if (type == null) throw new ArgumentNullException("type"); BCLDebug.Log("DYNIL","## DYNIL LOGGING: ModuleBuilder.GetTypeToken( " + type.FullName + " )"); refedModule = type.Module; isSameModule = refedModule.Equals(this); // Console.WriteLine("***** " + type.FullName); if (type.IsByRef) { // cannot be by ref!!! Throw exception throw new ArgumentException(Environment.GetResourceString("Argument_CannotGetTypeTokenForByRef")); } if (type is SymbolType) { if (type.IsPointer || type.IsArray) { SignatureBuffer sigBuf = new SignatureBuffer(); SymbolType symType = (SymbolType) type; // convert SymbolType to blob form symType.ToSigBytes(this, sigBuf); return new TypeToken( InternalGetTypeSpecTokenWithBytes(sigBuf.m_buf, sigBuf.m_curPos) ); } else throw new ArgumentException(Environment.GetResourceString("Argument_UnknownTypeForGetTypeToken")); } Type baseType; baseType = GetBaseType(type); if ( (type.IsArray || type.IsPointer) && baseType != type) { // We will at most recursive once. int baseToken; baseToken = GetTypeToken(baseType).Token; if (!(type is RuntimeType)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type"); return new TypeToken( InternalGetTypeSpecToken((RuntimeType)type, baseToken) ); } // After this point, it is not an array type nor Pointer type if (isSameModule) { // no need to do anything additional other than defining the TypeRef Token if (type is TypeBuilder) { // optimization: if the type is defined in this module, // just return the token // TypeBuilder typeBuilder = (TypeBuilder) type; return typeBuilder.TypeToken; } else if (type is EnumBuilder) { TypeBuilder typeBuilder = ((EnumBuilder) type).m_typeBuilder; return typeBuilder.TypeToken; } return new TypeToken(GetTypeRefNested(type, this, String.Empty)); } // After this point, the referenced module is not the same as the referencing // module. // isSameAssembly = refedModule.Assembly.Equals(Assembly); if (refedModule is ModuleBuilder) { ModuleBuilder refedModuleBuilder = (ModuleBuilder) refedModule; if (refedModuleBuilder.IsTransient()) { isRefedModuleTransient = true; } // get the referenced module's file name strRefedModuleFileName = refedModuleBuilder.m_moduleData.m_strFileName; } else strRefedModuleFileName = refedModule.ScopeName; // We cannot have a non-transient module referencing to a transient module. if (IsTransient() == false && isRefedModuleTransient) { // we got problem here. throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTransientModuleReference")); } tkToken = new TypeToken(GetTypeRefNested(type, refedModule, strRefedModuleFileName)); return tkToken; } finally { Exit(); } }
//*********************************************** // // Translate the type into signature format // //*********************************************** internal void ToSigBytes(ModuleBuilder moduleBuilder, SignatureBuffer sigBuf) { bool isArray = false; // now process whatever information that we have here. if (m_typeKind == TypeKind.IsArray) { if (m_cRank == 1 && m_iaLowerBound[0] == 0 && m_iaUpperBound[0] == -1) { // zero lower bound, unspecified count. So simplify to SZARRAY sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_SZARRAY); } else { // ELEMENT_TYPE_ARRAY : ARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ... // @todo: fill the signature blob sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_ARRAY); isArray = true; } } else if (m_typeKind == TypeKind.IsPointer) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_PTR); } else if (m_typeKind == TypeKind.IsByRef) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_BYREF); } if (m_baseType is SymbolType) { // the base type is still a SymbolType. So recursively form the signature blob ((SymbolType)m_baseType).ToSigBytes(moduleBuilder, sigBuf); } else { // we have walked to the most nested class. int cvType; if (m_baseType is RuntimeType) { cvType = SignatureHelper.GetCorElementTypeFromClass((RuntimeType)m_baseType); } else { cvType = SignatureHelper.ELEMENT_TYPE_MAX; } if (SignatureHelper.IsSimpleType(cvType)) { sigBuf.AddElementType(cvType); } else { if (m_baseType.IsValueType) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_VALUETYPE); sigBuf.AddToken(moduleBuilder.GetTypeToken(m_baseType).Token); } else if (m_baseType == SignatureHelper.SystemObject) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_OBJECT); } else if (m_baseType == SignatureHelper.SystemString) { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_STRING); } else { sigBuf.AddElementType(SignatureHelper.ELEMENT_TYPE_CLASS); sigBuf.AddToken(moduleBuilder.GetTypeToken(m_baseType).Token); } } } if (isArray) { // ELEMENT_TYPE_ARRAY : ARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ... // generic array!! Put in the dimension, sizes and lower bounds information. int index; int i; sigBuf.AddData(m_cRank); // determine the number of dimensions that we have to specify the size for (index = m_cRank - 1; index >= 0 && m_iaLowerBound[index] > m_iaUpperBound[index]; index--) { ; } sigBuf.AddData(index + 1); for (i = 0; i <= index; i++) { if (m_iaLowerBound[index] > m_iaUpperBound[index]) { // bad signature!! throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); } else { sigBuf.AddData(m_iaUpperBound[i] - m_iaLowerBound[i] + 1); } } // loop from last dimension back to first dimension. Look for the first one that does // not have lower bound equals to zero. If this is index, then 0..index has to specify the // lower bound. for (index = m_cRank - 1; index >= 0 && m_iaLowerBound[index] == 0; index--) { ; } sigBuf.AddData(index + 1); for (i = 0; i <= index; i++) { sigBuf.AddInteger(m_iaLowerBound[i]); } } }