Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Reflection / Emit / ModuleBuilder.cs / 5 / ModuleBuilder.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System.Reflection.Emit
{
using System.Runtime.InteropServices;
using System;
using IList = System.Collections.IList;
using System.Collections.Generic;
using ArrayList = System.Collections.ArrayList;
using CultureInfo = System.Globalization.CultureInfo;
using ResourceWriter = System.Resources.ResourceWriter;
using IResourceWriter = System.Resources.IResourceWriter;
using System.Diagnostics.SymbolStore;
using System.Reflection;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Runtime.Versioning;
// deliberately not [serializable]
[HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_ModuleBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
public class ModuleBuilder : Module, _ModuleBuilder
{
#region Internal Static Members
static internal String UnmangleTypeName(String typeName)
{
// Gets the original type name, without '+' name mangling.
int i = typeName.Length - 1;
while (true)
{
i = typeName.LastIndexOf('+', i);
if (i == -1)
break;
bool evenSlashes = true;
int iSlash = i;
while (typeName[--iSlash] == '\\')
evenSlashes = !evenSlashes;
// Even number of slashes means this '+' is a name separator
if (evenSlashes)
break;
i = iSlash;
}
return typeName.Substring(i + 1);
}
#endregion
#region Intenral Data Members
internal ModuleBuilder m_internalModuleBuilder;
// This is the "external" AssemblyBuilder
// only the "external" ModuleBuilder has this set
private AssemblyBuilder m_assemblyBuilder;
#endregion
#region Constructor
// key: "internal" ModuleBuilder
// value: "external" ModuleBuilder
private static readonly Dictionary s_moduleBuilders = new Dictionary();
// This method returns self for Modules and "external" ModuleBuilders for ModuleBuilders
internal static Module GetModuleBuilder(Module module)
{
ModuleBuilder internalModuleBuilder = module.InternalModule as ModuleBuilder;
if (internalModuleBuilder == null)
return module;
ModuleBuilder externalModuleBuilder = null;
lock (s_moduleBuilders)
{
if (s_moduleBuilders.TryGetValue(internalModuleBuilder, out externalModuleBuilder))
// all ModuleBuilder objects created through DefineDynamicModule already
// have corresponding "external" ModuleBuilders in s_moduleBuilders
return externalModuleBuilder;
else
// there is no corresponding "external" ModuleBuilder for the manifest module
return internalModuleBuilder;
}
}
internal ModuleBuilder(AssemblyBuilder assemblyBuilder, ModuleBuilder internalModuleBuilder)
{
m_internalModuleBuilder = internalModuleBuilder;
m_assemblyBuilder = assemblyBuilder;
lock(s_moduleBuilders)
s_moduleBuilders[internalModuleBuilder] = this;
}
#endregion
#region Private Members
private Type GetType(String strFormat, Type baseType)
{
// This function takes a string to describe the compound type, such as "[,][]", and a baseType.
if (strFormat == null || strFormat.Equals(String.Empty))
{
return baseType;
}
// convert the format string to byte array and then call FormCompoundType
char[] bFormat = strFormat.ToCharArray();
return SymbolType.FormCompoundType(bFormat, baseType, 0);
}
internal void CheckContext(params Type[][] typess)
{
((AssemblyBuilder)Assembly).CheckContext(typess);
}
internal void CheckContext(params Type[] types)
{
((AssemblyBuilder)Assembly).CheckContext(types);
}
#endregion
#region Internal Members
private bool IsInternal
{
get
{
return (m_internalModuleBuilder == null);
}
}
private void DemandGrantedAssemblyPermission()
{
AssemblyBuilder assemblyBuilder = (AssemblyBuilder)Assembly;
assemblyBuilder.DemandGrantedPermission();
}
internal virtual Type FindTypeBuilderWithName(String strTypeName, bool ignoreCase)
{
int size = m_TypeBuilderList.Count;
int i;
Type typeTemp = null;
for (i = 0; i < size; i++)
{
typeTemp = (Type) m_TypeBuilderList[i];
if (ignoreCase == true)
{
if (String.Compare(typeTemp.FullName, strTypeName, ((ignoreCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) == 0)
break;
}
else
{
if (typeTemp.FullName.Equals( strTypeName))
break;
}
}
if (i == size)
typeTemp = null;
return typeTemp;
}
internal Type GetRootElementType(Type type)
{
// This function will walk compound type to the inner most BaseType. Such as returning int for "ptr[] int".
if (type.IsByRef == false && type.IsPointer == false && type.IsArray == false)
return type;
return GetRootElementType(type.GetElementType());
}
internal void SetEntryPoint(MethodInfo entryPoint)
{
// Sets the entry point of the module to be a given method. If no entry point
// is specified, calling EmitPEFile will generate a dll.
// AssemblyBuilder.SetEntryPoint has already demanded required permission
m_EntryPoint = GetMethodTokenInternal(entryPoint);
}
internal void PreSave(String fileName,
PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
PreSaveNoLock(fileName, portableExecutableKind, imageFileMachine);
}
}
else
{
PreSaveNoLock(fileName, portableExecutableKind, imageFileMachine);
}
}
private void PreSaveNoLock(String fileName,
PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
// This is a helper called by AssemblyBuilder save to presave information for the persistable modules.
Object item;
TypeBuilder typeBuilder;
if (m_moduleData.m_isSaved == true)
{
// can only save once
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
Environment.GetResourceString("InvalidOperation_ModuleHasBeenSaved"),
m_moduleData.m_strModuleName));
}
if (m_moduleData.m_fGlobalBeenCreated == false && m_moduleData.m_fHasGlobal == true)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalFunctionNotBaked"));
int size = m_TypeBuilderList.Count;
for (int i=0; i.M ==> methDef = G.M
MethodOnTypeBuilderInstantiation motbi;
ConstructorOnTypeBuilderInstantiation cotbi;
if ((motbi = method as MethodOnTypeBuilderInstantiation) != null)
{
methDef = motbi.m_method;
}
else if ((cotbi = method as ConstructorOnTypeBuilderInstantiation) != null)
{
methDef = cotbi.m_ctor;
}
else if (method is MethodBuilder || method is ConstructorBuilder)
{
// methodInfo must be GenericMethodDefinition; trying to emit G>.M
methDef = method;
}
else if (method.IsGenericMethod)
{
methDef = masmi.GetGenericMethodDefinition();
methDef = methDef.Module.ResolveMethod(
methDef.MetadataTokenInternal,
methDef.GetGenericArguments(),
methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase;
}
else
{
methDef = method;
methDef = method.Module.ResolveMethod(
method.MetadataTokenInternal,
null,
methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase;
}
parameterTypes = methDef.GetParameterTypes();
returnType = methDef.GetReturnType();
}
else
{
parameterTypes = method.GetParameterTypes();
returnType = method.GetReturnType();
}
if (method.DeclaringType.IsGenericType)
{
int length;
byte[] sig = SignatureHelper.GetTypeSigToken(this, method.DeclaringType).InternalGetSignature(out length);
tkParent = InternalGetTypeSpecTokenWithBytes(sig, length);
}
else if (method.Module.InternalModule != this.InternalModule)
{
// Use typeRef as parent because the method's declaringType lives in a different assembly
tkParent = GetTypeToken(method.DeclaringType).Token;
}
else
{
// Use methodDef as parent because the method lives in this assembly and its declaringType has no generic arguments
if (masmi != null)
tkParent = GetMethodToken(method as MethodInfo).Token;
else
tkParent = GetConstructorToken(method as ConstructorInfo).Token;
}
int sigLength;
byte[] sigBytes = GetMemberRefSignature(
method.CallingConvention, returnType, parameterTypes,
optionalParameterTypes, cGenericParameters).InternalGetSignature(out sigLength);
return InternalGetMemberRefFromSignature(tkParent, method.Name, sigBytes, sigLength);
}
internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters)
{
int cParams;
int i;
SignatureHelper sig;
if (parameterTypes == null)
{
cParams = 0;
}
else
{
cParams = parameterTypes.Length;
}
sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);
for (i=0; i < cParams; i++)
sig.AddArgument(parameterTypes[i]);
if (optionalParameterTypes != null && optionalParameterTypes.Length != 0)
{
// add the sentinel
sig.AddSentinel();
for (i=0; i < optionalParameterTypes.Length; i++)
sig.AddArgument(optionalParameterTypes[i]);
}
return sig;
}
#endregion
#region Module Overrides
internal override bool IsDynamic()
{
return true;
}
// m_internalModuleBuilder is null iff this is a "internal" ModuleBuilder
internal override Module InternalModule
{
get
{
if (IsInternal)
return this;
else
return m_internalModuleBuilder;
}
}
internal override Assembly GetAssemblyInternal()
{
if (!IsInternal)
// return the "external" AssemblyBuilder
return m_assemblyBuilder;
else
// return the "internal" AssemblyBuilder
return _GetAssemblyInternal();
}
public override Type[] GetTypes()
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetTypesNoLock();
}
}
else
{
return GetTypesNoLock();
}
}
internal Type[] GetTypesNoLock()
{
int size = m_TypeBuilderList.Count;
List typeList = new List(size);
TypeBuilder tmpTypeBldr;
bool canReturnTypeBuilder = false;
if (IsInternal)
{
try
{
DemandGrantedAssemblyPermission();
canReturnTypeBuilder = true;
}
catch (SecurityException)
{
canReturnTypeBuilder = false;
}
}
else
{
canReturnTypeBuilder = true;
}
for (int i = 0; i < size; i++)
{
EnumBuilder enumBldr = m_TypeBuilderList[i] as EnumBuilder;
if (enumBldr != null)
tmpTypeBldr = enumBldr.m_typeBuilder;
else
tmpTypeBldr = m_TypeBuilderList[i] as TypeBuilder;
if (tmpTypeBldr != null)
{
// We should return TypeBuilders only if this is "external"
// ModuleBuilder or if we its granted permission
if (tmpTypeBldr.m_hasBeenCreated)
typeList.Add(tmpTypeBldr.UnderlyingSystemType);
else if (canReturnTypeBuilder)
typeList.Add(tmpTypeBldr);
}
else
{
// RuntimeType case: This will happen in TlbImp.
typeList.Add((Type) m_TypeBuilderList[i]);
}
}
return typeList.ToArray();
}
[System.Runtime.InteropServices.ComVisible(true)]
public override Type GetType(String className)
{
return GetType(className, false, false);
}
[System.Runtime.InteropServices.ComVisible(true)]
public override Type GetType(String className, bool ignoreCase)
{
return GetType(className, false, ignoreCase);
}
[System.Runtime.InteropServices.ComVisible(true)]
public override Type GetType(String className, bool throwOnError, bool ignoreCase)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetTypeNoLock(className, throwOnError, ignoreCase);
}
}
else
{
return GetTypeNoLock(className, throwOnError, ignoreCase);
}
}
private Type GetTypeNoLock(String className, bool throwOnError, bool ignoreCase)
{
// public API to to a type. The reason that we need this function override from module
// is because clients might need to get foo[] when foo is being built. For example, if
// foo class contains a data member of type foo[].
// This API first delegate to the Module.GetType implementation. If succeeded, great!
// If not, we have to look up the current module to find the TypeBuilder to represent the base
// type and form the Type object for "foo[,]".
// Module.GetType() will verify className.
Type baseType = base.GetType(className, throwOnError, ignoreCase);
if (baseType != null)
return baseType;
// Now try to see if we contain a TypeBuilder for this type or not.
// Might have a compound type name, indicated via an unescaped
// '[', '*' or '&'. Split the name at this point.
String baseName = null;
String parameters = null;
int startIndex = 0;
while (startIndex <= className.Length)
{
// Are there any possible special characters left?
int i = className.IndexOfAny(new char[]{'[', '*', '&'}, startIndex);
if (i == -1)
{
// No, type name is simple.
baseName = className;
parameters = null;
break;
}
// Found a potential special character, but it might be escaped.
int slashes = 0;
for (int j = i - 1; j >= 0 && className[j] == '\\'; j--)
slashes++;
// Odd number of slashes indicates escaping.
if (slashes % 2 == 1)
{
startIndex = i + 1;
continue;
}
// Found the end of the base type name.
baseName = className.Substring(0, i);
parameters = className.Substring(i);
break;
}
// If we didn't find a basename yet, the entire class name is
// the base name and we don't have a composite type.
if (baseName == null)
{
baseName = className;
parameters = null;
}
baseName = baseName.Replace(@"\\",@"\").Replace(@"\[",@"[").Replace(@"\*",@"*").Replace(@"\&",@"&");
if (parameters != null)
{
// try to see if reflection can find the base type. It can be such that reflection
// does not support the complex format string yet!
baseType = base.GetType(baseName, false, ignoreCase);
}
bool canReturnTypeBuilder = false;
if (IsInternal)
{
try
{
DemandGrantedAssemblyPermission();
canReturnTypeBuilder = true;
}
catch (SecurityException)
{
canReturnTypeBuilder = false;
}
}
else
{
canReturnTypeBuilder = true;
}
if (baseType == null && canReturnTypeBuilder)
{
// try to find it among the unbaked types.
// starting with the current module first of all.
// We only do this is this is an "external" ModuleBuilder
// or if we have its granted permission
baseType = FindTypeBuilderWithName(baseName, ignoreCase);
if (baseType == null && Assembly is AssemblyBuilder)
{
// now goto Assembly level to find the type.
int size;
ArrayList modList;
modList = Assembly.m_assemblyData.m_moduleBuilderList;
size = modList.Count;
for (int i = 0; i < size && baseType == null; i++)
{
ModuleBuilder mBuilder = (ModuleBuilder) modList[i];
baseType = mBuilder.FindTypeBuilderWithName(baseName, ignoreCase);
}
}
}
if (baseType == null)
return null;
if (parameters == null)
return baseType;
return GetType(parameters, baseType);
}
public override String FullyQualifiedName
{
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get
{
String fullyQualifiedName = m_moduleData.m_strFileName;
if (fullyQualifiedName == null)
return null;
if (Assembly.m_assemblyData.m_strDir != null)
{
fullyQualifiedName = Path.Combine(Assembly.m_assemblyData.m_strDir, fullyQualifiedName);
fullyQualifiedName = Path.GetFullPath(fullyQualifiedName);
}
if (Assembly.m_assemblyData.m_strDir != null && fullyQualifiedName != null)
{
new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullyQualifiedName ).Demand();
}
return fullyQualifiedName;
}
}
#endregion
#region Public Members
#region Define Type
public TypeBuilder DefineType(String name)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name);
}
}
else
{
return DefineTypeNoLock(name);
}
}
private TypeBuilder DefineTypeNoLock(String name)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, TypeAttributes.NotPublic, null, null, this, PackingSize.Unspecified, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
public TypeBuilder DefineType(String name, TypeAttributes attr)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr);
}
}
else
{
return DefineTypeNoLock(name, attr);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, attr, null, null, this, PackingSize.Unspecified, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr, parent);
}
}
else
{
return DefineTypeNoLock(name, attr, parent);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent)
{
CheckContext(parent);
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(
name, attr, parent, null, this, PackingSize.Unspecified, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, int typesize)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr, parent, typesize);
}
}
else
{
return DefineTypeNoLock(name, attr, parent, typesize);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, int typesize)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, attr, parent, this, PackingSize.Unspecified, typesize, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr, parent, packingSize, typesize);
}
}
else
{
return DefineTypeNoLock(name, attr, parent, packingSize, typesize);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, attr, parent, this, packingSize, typesize, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
[System.Runtime.InteropServices.ComVisible(true)]
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, Type[] interfaces)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr, parent, interfaces);
}
}
else
{
return DefineTypeNoLock(name, attr, parent, interfaces);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, attr, parent, interfaces, this, PackingSize.Unspecified, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
#endregion
#region Define Enum
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packsize)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineTypeNoLock(name, attr, parent, packsize);
}
}
else
{
return DefineTypeNoLock(name, attr, parent, packsize);
}
}
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packsize)
{
TypeBuilder typeBuilder;
typeBuilder = new TypeBuilder(name, attr, parent, null, this, packsize, null);
m_TypeBuilderList.Add(typeBuilder);
return typeBuilder;
}
public EnumBuilder DefineEnum(String name, TypeAttributes visibility, Type underlyingType)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
CheckContext(underlyingType);
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineEnumNoLock(name, visibility, underlyingType);
}
}
else
{
return DefineEnumNoLock(name, visibility, underlyingType);
}
}
private EnumBuilder DefineEnumNoLock(String name, TypeAttributes visibility, Type underlyingType)
{
EnumBuilder enumBuilder;
enumBuilder = new EnumBuilder(name, underlyingType, visibility, this);
m_TypeBuilderList.Add(enumBuilder);
return enumBuilder;
}
#endregion
#region Define Resource
public IResourceWriter DefineResource(String name, String description)
{
// Define embedded managed resource to be stored in this module
return DefineResource(name, description, ResourceAttributes.Public);
}
public IResourceWriter DefineResource(String name, String description, ResourceAttributes attribute)
{
// Define embedded managed resource to be stored in this module
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineResourceNoLock(name, description, attribute);
}
}
else
{
return DefineResourceNoLock(name, description, attribute);
}
}
private IResourceWriter DefineResourceNoLock(String name, String description, ResourceAttributes attribute)
{
// Define embedded managed resource to be stored in this module
if (IsTransient())
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
Assembly assembly = this.Assembly;
if (assembly is AssemblyBuilder)
{
AssemblyBuilder asmBuilder = (AssemblyBuilder)assembly;
if (asmBuilder.IsPersistable())
{
asmBuilder.m_assemblyData.CheckResNameConflict(name);
MemoryStream stream = new MemoryStream();
ResourceWriter resWriter = new ResourceWriter(stream);
ResWriterData resWriterData = new ResWriterData( resWriter, stream, name, String.Empty, String.Empty, attribute);
// chain it to the embedded resource list
resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes;
m_moduleData.m_embeddedRes = resWriterData;
return resWriter;
}
else
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
}
}
else
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
}
}
public void DefineManifestResource(String name, Stream stream, ResourceAttributes attribute)
{
if (name == null)
throw new ArgumentNullException("name");
if (stream == null)
throw new ArgumentNullException("stream");
if (IsInternal)
DemandGrantedAssemblyPermission();
// Define embedded managed resource to be stored in this module
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
DefineManifestResourceNoLock(name, stream, attribute);
}
}
else
{
DefineManifestResourceNoLock(name, stream, attribute);
}
}
private void DefineManifestResourceNoLock(String name, Stream stream, ResourceAttributes attribute)
{
// Define embedded managed resource to be stored in this module
if (IsTransient())
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
Assembly assembly = this.Assembly;
if (assembly is AssemblyBuilder)
{
AssemblyBuilder asmBuilder = (AssemblyBuilder)assembly;
if (asmBuilder.IsPersistable())
{
asmBuilder.m_assemblyData.CheckResNameConflict(name);
ResWriterData resWriterData = new ResWriterData( null, stream, name, String.Empty, String.Empty, attribute);
// chain it to the embedded resource list
resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes;
m_moduleData.m_embeddedRes = resWriterData;
}
else
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
}
}
else
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
}
}
public void DefineUnmanagedResource(Byte[] resource)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock (Assembly.m_assemblyData)
{
DefineUnmanagedResourceInternalNoLock(resource);
}
}
else
{
DefineUnmanagedResourceInternalNoLock(resource);
}
}
internal void DefineUnmanagedResourceInternalNoLock(Byte[] resource)
{
if (m_moduleData.m_strResourceFileName != null || m_moduleData.m_resourceBytes != null)
throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
if (resource == null)
throw new ArgumentNullException("resource");
m_moduleData.m_resourceBytes = new byte[resource.Length];
System.Array.Copy(resource, m_moduleData.m_resourceBytes, resource.Length);
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public void DefineUnmanagedResource(String resourceFileName)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock (Assembly.m_assemblyData)
{
DefineUnmanagedResourceFileInternalNoLock(resourceFileName);
}
}
else
{
DefineUnmanagedResourceFileInternalNoLock(resourceFileName);
}
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
internal void DefineUnmanagedResourceFileInternalNoLock(String resourceFileName)
{
if (m_moduleData.m_resourceBytes != null || m_moduleData.m_strResourceFileName != null)
throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
if (resourceFileName == null)
throw new ArgumentNullException("resourceFileName");
// Check caller has the right to read the file.
string strFullFileName;
strFullFileName = Path.GetFullPath(resourceFileName);
new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand();
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
try
{
if (File.Exists(resourceFileName) == false)
throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString(
"IO.FileNotFound_FileName"),
resourceFileName), resourceFileName);
}
finally
{
CodeAccessPermission.RevertAssert();
}
m_moduleData.m_strResourceFileName = strFullFileName;
}
#endregion
#region Define Global Method
public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
{
return DefineGlobalMethod(name, attributes, CallingConventions.Standard, returnType, parameterTypes);
}
public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
return DefineGlobalMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
}
public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
}
else
{
return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
}
private MethodBuilder DefineGlobalMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
CheckContext(returnType);
CheckContext(requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes);
CheckContext(requiredParameterTypeCustomModifiers);
CheckContext(optionalParameterTypeCustomModifiers);
if (m_moduleData.m_fGlobalBeenCreated == true)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
if ((attributes & MethodAttributes.Static) == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefineMethod(name, attributes, callingConvention,
returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
{
return DefinePInvokeMethod(name, dllName, name, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
}
public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv,
CharSet nativeCharSet)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefinePInvokeMethodNoLock(name, dllName, entryName, attributes, callingConvention,
returnType, parameterTypes, nativeCallConv, nativeCharSet);
}
}
else
{
return DefinePInvokeMethodNoLock(name, dllName, entryName, attributes, callingConvention,
returnType, parameterTypes, nativeCallConv, nativeCharSet);
}
}
private MethodBuilder DefinePInvokeMethodNoLock(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv,
CharSet nativeCharSet)
{
CheckContext(returnType);
CheckContext(parameterTypes);
//Global methods must be static.
if ((attributes & MethodAttributes.Static) == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
}
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
}
public void CreateGlobalFunctions()
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
CreateGlobalFunctionsNoLock();
}
}
else
{
CreateGlobalFunctionsNoLock();
}
}
private void CreateGlobalFunctionsNoLock()
{
if (m_moduleData.m_fGlobalBeenCreated)
{
// cannot create globals twice
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
m_moduleData.m_globalTypeBuilder.CreateType();
m_moduleData.m_fGlobalBeenCreated = true;
}
#endregion
#region Define Data
public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes)
{
// This method will define an initialized Data in .sdata.
// We will create a fake TypeDef to represent the data with size. This TypeDef
// will be the signature for the Field.
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineInitializedDataNoLock(name, data, attributes);
}
}
else
{
return DefineInitializedDataNoLock(name, data, attributes);
}
}
private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes)
{
// This method will define an initialized Data in .sdata.
// We will create a fake TypeDef to represent the data with size. This TypeDef
// will be the signature for the Field.
if (m_moduleData.m_fGlobalBeenCreated == true)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
}
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefineInitializedData(name, data, attributes);
}
public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineUninitializedDataNoLock(name, size, attributes);
}
}
else
{
return DefineUninitializedDataNoLock(name, size, attributes);
}
}
private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes)
{
// This method will define an uninitialized Data in .sdata.
// We will create a fake TypeDef to represent the data with size. This TypeDef
// will be the signature for the Field.
if (m_moduleData.m_fGlobalBeenCreated == true)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
}
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefineUninitializedData(name, size, attributes);
}
#endregion
#region GetToken
// For a generic type definition, we should return the token for the generic type definition itself in two cases:
// 1. GetTypeToken
// 2. ldtoken (see ILGenerator)
// For all other occasions we should return the generic type instantiated on its formal parameters.
internal TypeToken GetTypeTokenInternal(Type type)
{
return GetTypeTokenInternal(type, false);
}
internal TypeToken GetTypeTokenInternal(Type type, bool getGenericDefinition)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetTypeTokenWorkerNoLock(type, getGenericDefinition);
}
}
else
{
return GetTypeTokenWorkerNoLock(type, getGenericDefinition);
}
}
public TypeToken GetTypeToken(Type type)
{
return GetTypeTokenInternal(type, true);
}
private TypeToken GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition)
{
CheckContext(type);
// 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!!!
TypeToken tkToken;
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");
refedModule = GetModuleBuilder(type.Module);
isSameModule = refedModule.Equals(this);
if (type.IsByRef)
throw new ArgumentException(Environment.GetResourceString("Argument_CannotGetTypeTokenForByRef"));
if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition)) ||
type.IsGenericParameter ||
type.IsArray ||
type.IsPointer)
{
int length;
byte[] sig = SignatureHelper.GetTypeSigToken(this, type).InternalGetSignature(out length);
return new TypeToken(InternalGetTypeSpecTokenWithBytes(sig, length));
}
if (isSameModule)
{
// no need to do anything additional other than defining the TypeRef Token
TypeBuilder typeBuilder;
EnumBuilder enumBuilder = type as EnumBuilder;
if (enumBuilder != null)
typeBuilder = enumBuilder.m_typeBuilder;
else
typeBuilder = type as TypeBuilder;
if (typeBuilder != null)
{
// optimization: if the type is defined in this module,
// just return the token
//
return typeBuilder.TypeToken;
}
else if (type is GenericTypeParameterBuilder)
{
return new TypeToken(type.MetadataTokenInternal);
}
return new TypeToken(GetTypeRefNested(type, this, String.Empty));
}
// After this point, the referenced module is not the same as the referencing
// module.
ModuleBuilder refedModuleBuilder = refedModule as ModuleBuilder;
if (refedModuleBuilder != null)
{
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)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTransientModuleReference"));
}
tkToken = new TypeToken(GetTypeRefNested(type, refedModule, strRefedModuleFileName));
return tkToken;
}
public TypeToken GetTypeToken(String name)
{
// Return a token for the class relative to the Module.
// Module.GetType() verifies name
// Unfortunately, we will need to load the Type and then call GetTypeToken in
// order to correctly track the assembly reference information.
return GetTypeToken(base.GetType(name, false, true));
}
public MethodToken GetMethodToken(MethodInfo method)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetMethodTokenNoLock(method, true);
}
}
else
{
return GetMethodTokenNoLock(method, true);
}
}
internal MethodToken GetMethodTokenInternal(MethodInfo method)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetMethodTokenNoLock(method, false);
}
}
else
{
return GetMethodTokenNoLock(method, false);
}
}
// For a method on a generic type, we should return the methoddef token on the generic type definition in two cases
// 1. GetMethodToken
// 2. ldtoken (see ILGenerator)
// For all other occasions we should return the method on the generic type instantiated on the formal parameters.
private MethodToken GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeDefinition)
{
// Return a MemberRef token if MethodInfo is not defined in this module. Or
// return the MethodDef token.
int tr;
int mr = 0;
if (method == null)
throw new ArgumentNullException("method");
if (method is MethodBuilder)
{
if (method.Module.InternalModule == this.InternalModule)
return new MethodToken(method.MetadataTokenInternal);
if (method.DeclaringType == null)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
// method is defined in a different module
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
mr = InternalGetMemberRef(method.DeclaringType.Module, tr, method.MetadataTokenInternal);
}
else if (method is MethodOnTypeBuilderInstantiation)
{
return new MethodToken(GetMemberRefToken(method, null));
}
else if (method is SymbolMethod)
{
SymbolMethod symMethod = method as SymbolMethod;
if (symMethod.GetModule() == this)
return symMethod.GetToken();
// form the method token
return symMethod.GetToken(this);
}
else
{
Type declaringType = method.DeclaringType;
// We need to get the TypeRef tokens
if (declaringType == null)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
if (declaringType.IsArray == true)
{
// use reflection to build signature to work around the E_T_VAR problem in EEClass
ParameterInfo[] paramInfo = method.GetParameters();
Type[] tt = new Type[paramInfo.Length];
for (int i = 0; i < paramInfo.Length; i++)
tt[i] = paramInfo[i].ParameterType;
return GetArrayMethodToken(declaringType, method.Name, method.CallingConvention, method.ReturnType, tt);
}
else if (method is RuntimeMethodInfo)
{
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
mr = InternalGetMemberRefOfMethodInfo(tr, method.GetMethodHandle());
}
else
{
// some user derived ConstructorInfo
// go through the slower code path, i.e. retrieve parameters and form signature helper.
ParameterInfo[] parameters = method.GetParameters();
Type[] parameterTypes = new Type[parameters.Length];
Type[][] requiredCustomModifiers = new Type[parameterTypes.Length][];
Type[][] optionalCustomModifiers = new Type[parameterTypes.Length][];
for (int i = 0; i < parameters.Length; i++)
{
parameterTypes[i] = parameters[i].ParameterType;
requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers();
}
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
SignatureHelper sigHelp;
try
{
sigHelp = SignatureHelper.GetMethodSigHelper(
this, method.CallingConvention, method.ReturnType,
method.ReturnParameter.GetRequiredCustomModifiers(), method.ReturnParameter.GetOptionalCustomModifiers(),
parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
}
catch(NotImplementedException)
{
// Legacy code deriving from MethodInfo may not have implemented ReturnParameter.
sigHelp = SignatureHelper.GetMethodSigHelper(this, method.ReturnType, parameterTypes);
}
int length;
byte[] sigBytes = sigHelp.InternalGetSignature(out length);
mr = InternalGetMemberRefFromSignature(tr, method.Name, sigBytes, length);
}
}
return new MethodToken(mr);
}
public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes);
}
}
else
{
return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes);
}
}
private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
CheckContext(returnType, arrayClass);
CheckContext(parameterTypes);
// Return a token for the MethodInfo for a method on an Array. This is primarily
// used to get the LoadElementAddress method.
Type baseType;
int baseToken;
int length;
if (arrayClass == null)
throw new ArgumentNullException("arrayClass");
if (methodName == null)
throw new ArgumentNullException("methodName");
if (methodName.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "methodName");
if (arrayClass.IsArray == false)
throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
SignatureHelper sigHelp = SignatureHelper.GetMethodSigHelper(
this, callingConvention, returnType, null, null, parameterTypes, null, null);
byte[] sigBytes = sigHelp.InternalGetSignature(out length);
// track the TypeRef of the array base class
for (baseType = arrayClass; baseType.IsArray; baseType = baseType.GetElementType());
baseToken = GetTypeTokenInternal(baseType).Token;
TypeToken typeSpec = GetTypeTokenInternal(arrayClass);
return new MethodToken(nativeGetArrayMethodToken(
typeSpec.Token, methodName, sigBytes, length, baseToken /* TODO: Remove */));
}
public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
CheckContext(returnType, arrayClass);
CheckContext(parameterTypes);
// GetArrayMethod is useful when you have an array of a type whose definition has not been completed and
// you want to access methods defined on Array. For example, you might define a type and want to define a
// method that takes an array of the type as a parameter. In order to access the elements of the array,
// you will need to call methods of the Array class.
MethodToken token = GetArrayMethodToken(arrayClass, methodName, callingConvention, returnType, parameterTypes);
return new SymbolMethod(this, token, arrayClass, methodName, callingConvention, returnType, parameterTypes);
}
[System.Runtime.InteropServices.ComVisible(true)]
public MethodToken GetConstructorToken(ConstructorInfo con)
{
// Return a token for the ConstructorInfo relative to the Module.
return InternalGetConstructorToken(con, false);
}
public FieldToken GetFieldToken(FieldInfo field)
{
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return GetFieldTokenNoLock(field);
}
}
else
{
return GetFieldTokenNoLock(field);
}
}
private FieldToken GetFieldTokenNoLock(FieldInfo field)
{
int tr;
int mr = 0;
if (field == null) {
throw new ArgumentNullException("con");
}
else if (field is FieldBuilder)
{
FieldBuilder fdBuilder = (FieldBuilder) field;
if (field.DeclaringType != null && field.DeclaringType.IsGenericType)
{
int length;
byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length);
tr = InternalGetTypeSpecTokenWithBytes(sig, length);
mr = InternalGetMemberRef(this, tr, fdBuilder.GetToken().Token);
}
else if (fdBuilder.GetTypeBuilder().Module.InternalModule.Equals(this.InternalModule))
{
// field is defined in the same module
return fdBuilder.GetToken();
}
else
{
// field is defined in a different module
if (field.DeclaringType == null)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
}
tr = GetTypeTokenInternal(field.DeclaringType).Token;
mr = InternalGetMemberRef(field.ReflectedType.Module, tr, fdBuilder.GetToken().Token);
}
}
else if (field is RuntimeFieldInfo)
{
// FieldInfo is not an dynamic field
// We need to get the TypeRef tokens
if (field.DeclaringType == null)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
}
if (field.DeclaringType != null && field.DeclaringType.IsGenericType)
{
int length;
byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length);
tr = InternalGetTypeSpecTokenWithBytes(sig, length);
mr = InternalGetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), field.MetadataTokenInternal);
}
else
{
tr = GetTypeTokenInternal(field.DeclaringType).Token;
mr = InternalGetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), field.MetadataTokenInternal);
}
}
else if (field is FieldOnTypeBuilderInstantiation)
{
FieldInfo fb = ((FieldOnTypeBuilderInstantiation)field).FieldInfo;
int length;
byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length);
tr = InternalGetTypeSpecTokenWithBytes(sig, length);
mr = InternalGetMemberRef(fb.ReflectedType.Module, tr, fb.MetadataTokenInternal);
}
else
{
// user defined FieldInfo
tr = GetTypeTokenInternal(field.ReflectedType).Token;
SignatureHelper sigHelp = SignatureHelper.GetFieldSigHelper(this);
sigHelp.AddArgument(field.FieldType, field.GetRequiredCustomModifiers(), field.GetOptionalCustomModifiers());
int length;
byte[] sigBytes = sigHelp.InternalGetSignature(out length);
mr = InternalGetMemberRefFromSignature(tr, field.Name, sigBytes, length);
}
return new FieldToken(mr, field.GetType());
}
public StringToken GetStringConstant(String str)
{
// Returns a token representing a String constant. If the string
// value has already been defined, the existing token will be returned.
return new StringToken(InternalGetStringConstant(str));
}
public SignatureToken GetSignatureToken(SignatureHelper sigHelper)
{
// Define signature token given a signature helper. This will define a metadata
// token for the signature described by SignatureHelper.
int sigLength;
byte[] sigBytes;
if (sigHelper == null)
{
throw new ArgumentNullException("sigHelper");
}
// get the signature in byte form
sigBytes = sigHelper.InternalGetSignature(out sigLength);
return new SignatureToken(TypeBuilder.InternalGetTokenFromSig(this, sigBytes, sigLength), this);
}
public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)
{
byte[] localSigBytes = null;
if (sigBytes == null)
throw new ArgumentNullException("sigBytes");
localSigBytes = new byte[sigBytes.Length];
Array.Copy(sigBytes, localSigBytes, sigBytes.Length);
return new SignatureToken(TypeBuilder.InternalGetTokenFromSig(this, localSigBytes, sigLength), this);
}
#endregion
#region Other
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (con == null)
throw new ArgumentNullException("con");
if (binaryAttribute == null)
throw new ArgumentNullException("binaryAttribute");
TypeBuilder.InternalCreateCustomAttribute(
1, // This is hard coding the module token to 1
this.GetConstructorToken(con).Token,
binaryAttribute,
this,
false);
}
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (customBuilder == null)
{
throw new ArgumentNullException("customBuilder");
}
customBuilder.CreateCustomAttribute(this, 1); // This is hard coding the module token to 1
}
public ISymbolWriter GetSymWriter()
{
if (IsInternal)
DemandGrantedAssemblyPermission();
return m_iSymWriter;
}
public ISymbolDocumentWriter DefineDocument(String url, Guid language, Guid languageVendor, Guid documentType)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
return DefineDocumentNoLock(url, language, languageVendor, documentType);
}
}
else
{
return DefineDocumentNoLock(url, language, languageVendor, documentType);
}
}
private ISymbolDocumentWriter DefineDocumentNoLock(String url, Guid language, Guid languageVendor, Guid documentType)
{
if (m_iSymWriter == null)
{
// Cannot DefineDocument when it is not a debug module
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
return m_iSymWriter.DefineDocument(url, language, languageVendor, documentType);
}
public void SetUserEntryPoint(MethodInfo entryPoint)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
SetUserEntryPointNoLock(entryPoint);
}
}
else
{
SetUserEntryPointNoLock(entryPoint);
}
}
private void SetUserEntryPointNoLock(MethodInfo entryPoint)
{
// Set the user entry point. Compiler may generate startup stub before calling user main.
// The startup stub will be the entry point. While the user "main" will be the user entry
// point so that debugger will not step into the compiler entry point.
if (entryPoint == null)
{
throw new ArgumentNullException("entryPoint");
}
if (m_iSymWriter == null)
{
// Cannot set entry point when it is not a debug module
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
if (entryPoint.DeclaringType != null)
{
if (entryPoint.Module.InternalModule != this.InternalModule)
{
// you cannot pass in a MethodInfo that is not contained by this ModuleBuilder
throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder"));
}
}
else
{
// unfortunately this check is missing for global function passed in as RuntimeMethodInfo.
// The problem is that Reflection does not
// allow us to get the containing module giving a global function
MethodBuilder mb = entryPoint as MethodBuilder;
if (mb != null && mb.GetModule().InternalModule != this.InternalModule)
{
// you cannot pass in a MethodInfo that is not contained by this ModuleBuilder
throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder"));
}
}
// get the metadata token value and create the SymbolStore's token value class
SymbolToken tkMethod = new SymbolToken(GetMethodTokenInternal(entryPoint).Token);
// set the UserEntryPoint
m_iSymWriter.SetUserEntryPoint(tkMethod);
}
public void SetSymCustomAttribute(String name, byte[] data)
{
if (IsInternal)
DemandGrantedAssemblyPermission();
if (Assembly.m_assemblyData.m_isSynchronized)
{
lock(Assembly.m_assemblyData)
{
SetSymCustomAttributeNoLock(name, data);
}
}
else
{
SetSymCustomAttributeNoLock(name, data);
}
}
private void SetSymCustomAttributeNoLock(String name, byte[] data)
{
if (m_iSymWriter == null)
{
// Cannot SetSymCustomAttribute when it is not a debug module
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
//SymbolToken tk = new SymbolToken();
//m_iSymWriter.SetSymAttribute(tk, name, data);
}
public bool IsTransient()
{
return m_moduleData.IsTransient();
}
#endregion
#endregion
void _ModuleBuilder.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
void _ModuleBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
void _ModuleBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
void _ModuleBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExpressionBuilder.cs
- RegularExpressionValidator.cs
- SmtpClient.cs
- TextElementEditingBehaviorAttribute.cs
- DesignerDeviceConfig.cs
- WeakReferenceList.cs
- KeyedHashAlgorithm.cs
- TableLayoutPanel.cs
- DataTable.cs
- GeneralTransformCollection.cs
- RuleSet.cs
- RuntimeConfigLKG.cs
- AsymmetricKeyExchangeDeformatter.cs
- Validator.cs
- TextSelection.cs
- StaticResourceExtension.cs
- SByteConverter.cs
- autovalidator.cs
- CodeTryCatchFinallyStatement.cs
- SystemTcpStatistics.cs
- QilPatternVisitor.cs
- ExpandCollapsePattern.cs
- ModuleBuilderData.cs
- IconHelper.cs
- AnnotationHelper.cs
- sqlstateclientmanager.cs
- SecureConversationServiceElement.cs
- StreamWithDictionary.cs
- RoutedEvent.cs
- DomainUpDown.cs
- JsonFormatReaderGenerator.cs
- DesignSurfaceEvent.cs
- DragEventArgs.cs
- InternalCache.cs
- TextServicesCompartmentContext.cs
- ResizingMessageFilter.cs
- ProviderConnectionPointCollection.cs
- DataSysAttribute.cs
- RequiredFieldValidator.cs
- UriTemplateTrieLocation.cs
- RtfToken.cs
- SessionEndingEventArgs.cs
- DocumentSchemaValidator.cs
- XmlNamespaceDeclarationsAttribute.cs
- CompositeControl.cs
- CardSpaceSelector.cs
- EnvironmentPermission.cs
- DataTableMapping.cs
- DataSourceHelper.cs
- EventTrigger.cs
- DocumentsTrace.cs
- CodeDomSerializerBase.cs
- SingleAnimationUsingKeyFrames.cs
- QilUnary.cs
- XmlSchemaAnnotated.cs
- WithParamAction.cs
- EntityDesignerUtils.cs
- RubberbandSelector.cs
- CmsInterop.cs
- RemoteDebugger.cs
- Vector3DCollectionConverter.cs
- ConfigurationException.cs
- SequenceDesigner.xaml.cs
- EmptyStringExpandableObjectConverter.cs
- IisTraceWebEventProvider.cs
- DataSourceView.cs
- PublisherIdentityPermission.cs
- ConfigurationProperty.cs
- EntityChangedParams.cs
- UrlMapping.cs
- ExpressionReplacer.cs
- DragCompletedEventArgs.cs
- FormViewInsertEventArgs.cs
- ToolboxItemCollection.cs
- UserNameSecurityTokenAuthenticator.cs
- MemberAccessException.cs
- ConnectionPointCookie.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- ToolConsole.cs
- StringUtil.cs
- ClientFormsIdentity.cs
- PromptStyle.cs
- OrderablePartitioner.cs
- FormDocumentDesigner.cs
- WebResourceAttribute.cs
- WrapperEqualityComparer.cs
- EntityAdapter.cs
- NamedPipeActivation.cs
- HiddenFieldPageStatePersister.cs
- DataGridItemAutomationPeer.cs
- XmlSchemaExternal.cs
- PropertyDescriptorCollection.cs
- FileDialogCustomPlacesCollection.cs
- InstanceLockLostException.cs
- PopOutPanel.cs
- ImpersonationContext.cs
- FormatConvertedBitmap.cs
- ButtonColumn.cs
- RegionData.cs
- DataGridColumnStyleMappingNameEditor.cs