using Mono.Security;
using Mono.Security.Cryptography;
-namespace System.Reflection.Emit {
+namespace System.Reflection.Emit
+{
+ internal enum NativeResourceType
+ {
+ None,
+ Unmanaged,
+ Assembly,
+ Explicit
+ }
internal struct RefEmitPermissionSet {
public SecurityAction action;
#endif
[ClassInterface (ClassInterfaceType.None)]
public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder {
+#pragma warning disable 169, 414
#region Sync with object-internals.h
- private IntPtr dynamic_assembly;
+ private UIntPtr dynamic_assembly; /* GC-tracked */
private MethodInfo entry_point;
private ModuleBuilder[] modules;
private string name;
bool corlib_internal;
Type[] type_forwarders;
#endregion
+#pragma warning restore 169, 414
+
internal Type corlib_object_type = typeof (System.Object);
internal Type corlib_value_type = typeof (System.ValueType);
internal Type corlib_enum_type = typeof (System.Enum);
bool created;
bool is_module_only;
private Mono.Security.StrongName sn;
+ NativeResourceType native_resource;
+ readonly bool is_compiler_context;
+ string versioninfo_culture;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void basic_init (AssemblyBuilder ab);
-
+
+ /* Keep this in sync with codegen.cs in mcs */
+ private const AssemblyBuilderAccess COMPILER_ACCESS = (AssemblyBuilderAccess) 0x800;
+
internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access, bool corlib_internal)
{
+#if BOOTSTRAP_WITH_OLDLIB
+ is_compiler_context = true;
+#else
+ is_compiler_context = (access & COMPILER_ACCESS) != 0;
+#endif
+
+ // remove Mono specific flag to allow enum check to pass
+ access &= ~COMPILER_ACCESS;
+
+#if NET_2_0
+ if (!Enum.IsDefined (typeof (AssemblyBuilderAccess), access))
+ throw new ArgumentException (string.Format (CultureInfo.InvariantCulture,
+ "Argument value {0} is not valid.", (int) access),
+ "access");
+#endif
+
+#if NET_4_0
+ if ((access & AssemblyBuilderAccess.RunAndCollect) == AssemblyBuilderAccess.RunAndCollect)
+ throw new NotSupportedException ("RunAndCollect not yet supported.");
+#endif
+
name = n.Name;
this.access = (uint)access;
+ flags = (uint) n.Flags;
// don't call GetCurrentDirectory for Run-only builders (CAS may not like that)
- if (IsSave && (directory == null || directory == String.Empty)) {
+ if (IsSave && (directory == null || directory.Length == 0)) {
dir = Directory.GetCurrentDirectory ();
} else {
dir = directory;
/* Set defaults from n */
if (n.CultureInfo != null) {
culture = n.CultureInfo.Name;
+ versioninfo_culture = n.CultureInfo.Name;
}
Version v = n.Version;
if (v != null) {
if (n.KeyPair != null) {
// full keypair is available (for signing)
sn = n.KeyPair.StrongName ();
- }
- else {
+ } else {
// public key is available (for delay-signing)
byte[] pk = n.GetPublicKey ();
if ((pk != null) && (pk.Length > 0)) {
}
}
+ if (sn != null)
+ flags |= (uint) AssemblyNameFlags.PublicKey;
+
this.corlib_internal = corlib_internal;
basic_init (this);
}
#endif
+#if NET_2_0
+ [MonoTODO]
+ public override bool ReflectionOnly {
+ get { return base.ReflectionOnly; }
+ }
+#endif
+
public void AddResourceFile (string name, string fileName)
{
AddResourceFile (name, fileName, ResourceAttributes.Public);
} else {
Type[] arr = new Type [type_forwarders.Length + 1];
Array.Copy (type_forwarders, arr, type_forwarders.Length);
+ arr [type_forwarders.Length] = t;
type_forwarders = arr;
}
}
return DefineDynamicModule (name, fileName, emitSymbolInfo, false);
}
- private ModuleBuilder DefineDynamicModule (string name, string fileName,
- bool emitSymbolInfo, bool transient)
+ private ModuleBuilder DefineDynamicModule (string name, string fileName, bool emitSymbolInfo, bool transient)
{
check_name_and_filename (name, fileName, false);
{
if (resource == null)
throw new ArgumentNullException ("resource");
+ if (native_resource != NativeResourceType.None)
+ throw new ArgumentException ("Native resource has already been defined.");
+
+ // avoid definition of more than one unmanaged resource
+ native_resource = NativeResourceType.Unmanaged;
/*
* The format of the argument byte array is not documented
{
if (resourceFileName == null)
throw new ArgumentNullException ("resourceFileName");
- if (resourceFileName == String.Empty)
+ if (resourceFileName.Length == 0)
throw new ArgumentException ("resourceFileName");
if (!File.Exists (resourceFileName) || Directory.Exists (resourceFileName))
throw new FileNotFoundException ("File '" + resourceFileName + "' does not exists or is a directory.");
+ if (native_resource != NativeResourceType.None)
+ throw new ArgumentException ("Native resource has already been defined.");
+
+ // avoid definition of more than one unmanaged resource
+ native_resource = NativeResourceType.Unmanaged;
- using (FileStream fs = new FileStream (resourceFileName, FileMode.Open)) {
+ using (FileStream fs = new FileStream (resourceFileName, FileMode.Open, FileAccess.Read)) {
Win32ResFileReader reader = new Win32ResFileReader (fs);
foreach (Win32EncodedResource res in reader.ReadResources ()) {
public void DefineVersionInfoResource ()
{
- if (version_res != null)
- throw new ArgumentException ("Native resource has already been defined.");
+ if (native_resource != NativeResourceType.None)
+ throw new ArgumentException ("Native resource has already been defined.");
- version_res = new Win32VersionResource (1, 0);
+ // avoid definition of more than one unmanaged resource
+ native_resource = NativeResourceType.Assembly;
- if (cattrs != null) {
- foreach (CustomAttributeBuilder cb in cattrs) {
- string attrname = cb.Ctor.ReflectedType.FullName;
-
- if (attrname == "System.Reflection.AssemblyProductAttribute")
- version_res.ProductName = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyCompanyAttribute")
- version_res.CompanyName = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyCopyrightAttribute")
- version_res.LegalCopyright = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyTrademarkAttribute")
- version_res.LegalTrademarks = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyCultureAttribute"){
- int lcid;
-
- try {
- lcid = new CultureInfo (GetCultureString (cb.string_arg ())).LCID;
- } catch (ArgumentException){
- //
- // This means that the resource is set to the invariant, but
- // the locale encoded will come from the AssemblyName anyways.
- //
- // In fact, my exploration of MS.NEt shows that this is always
- // set to zero, so I wonder if we should completely drop this
- // code from here.
- //
- lcid = CultureInfo.InvariantCulture.LCID;
- }
- version_res.FileLanguage = lcid;
- }
- else if (attrname == "System.Reflection.AssemblyFileVersionAttribute")
- version_res.FileVersion = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyInformationalVersionAttribute")
- version_res.ProductVersion = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyTitleAttribute")
- version_res.FileDescription = cb.string_arg ();
- else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
- version_res.Comments = cb.string_arg ();
- }
- }
+ version_res = new Win32VersionResource (1, 0, IsCompilerContext);
}
public void DefineVersionInfoResource (string product, string productVersion,
string company, string copyright, string trademark)
{
- if (version_res != null)
+ if (native_resource != NativeResourceType.None)
throw new ArgumentException ("Native resource has already been defined.");
+ // avoid definition of more than one unmanaged resource
+ native_resource = NativeResourceType.Explicit;
+
/*
* We can only create the resource later, when the file name and
* the binary version is known.
*/
- version_res = new Win32VersionResource (1, 0);
- version_res.ProductName = product;
- version_res.ProductVersion = productVersion;
- version_res.CompanyName = company;
- version_res.LegalCopyright = copyright;
- version_res.LegalTrademarks = trademark;
+ version_res = new Win32VersionResource (1, 0, false);
+ version_res.ProductName = product != null ? product : " ";
+ version_res.ProductVersion = productVersion != null ? productVersion : " ";
+ version_res.CompanyName = company != null ? company : " ";
+ version_res.LegalCopyright = copyright != null ? copyright : " ";
+ version_res.LegalTrademarks = trademark != null ? trademark : " ";
}
/*
{
if (iconFileName == null)
throw new ArgumentNullException ("iconFileName");
- if (iconFileName == String.Empty)
+ if (iconFileName.Length == 0)
throw new ArgumentException ("iconFileName");
if (!File.Exists (iconFileName) || Directory.Exists (iconFileName))
throw new FileNotFoundException ("File '" + iconFileName + "' does not exists or is a directory.");
- using (FileStream fs = new FileStream (iconFileName, FileMode.Open)) {
+ using (FileStream fs = new FileStream (iconFileName, FileMode.Open, FileAccess.Read)) {
Win32IconFileReader reader = new Win32IconFileReader (fs);
ICONDIRENTRY[] entries = reader.ReadIcons ();
}
}
- private void DefineVersionInfoResourceImpl (string fileName) {
- // Add missing info
- if (version_res.Version == "0.0.0.0")
- version_res.Version = version;
- if (version_res.FileVersion.Trim () == String.Empty && version != null)
- version_res.FileVersion = version;
- version_res.InternalName = Path.GetFileNameWithoutExtension (fileName);
+ private void DefineVersionInfoResourceImpl (string fileName)
+ {
+ if (versioninfo_culture != null)
+ version_res.FileLanguage = new CultureInfo (versioninfo_culture).LCID;
+ version_res.Version = version == null ? "0.0.0.0" : version;
+
+ if (cattrs != null) {
+ switch (native_resource) {
+ case NativeResourceType.Assembly:
+ foreach (CustomAttributeBuilder cb in cattrs) {
+ string attrname = cb.Ctor.ReflectedType.FullName;
+
+ if (attrname == "System.Reflection.AssemblyProductAttribute")
+ version_res.ProductName = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyCompanyAttribute")
+ version_res.CompanyName = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyCopyrightAttribute")
+ version_res.LegalCopyright = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyTrademarkAttribute")
+ version_res.LegalTrademarks = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
+ if (!IsCompilerContext)
+ version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
+ } else if (attrname == "System.Reflection.AssemblyFileVersionAttribute") {
+ string fileversion = cb.string_arg ();
+ if (!IsCompilerContext || fileversion != null && fileversion.Length != 0)
+ version_res.FileVersion = fileversion;
+ } else if (attrname == "System.Reflection.AssemblyInformationalVersionAttribute")
+ version_res.ProductVersion = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyTitleAttribute")
+ version_res.FileDescription = cb.string_arg ();
+ else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
+ version_res.Comments = cb.string_arg ();
+ }
+ break;
+ case NativeResourceType.Explicit:
+ foreach (CustomAttributeBuilder cb in cattrs) {
+ string attrname = cb.Ctor.ReflectedType.FullName;
+
+ if (attrname == "System.Reflection.AssemblyCultureAttribute") {
+ if (!IsCompilerContext)
+ version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
+ } else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
+ version_res.Comments = cb.string_arg ();
+ }
+ break;
+ }
+ }
+
version_res.OriginalFilename = fileName;
+ if (IsCompilerContext) {
+ version_res.InternalName = fileName;
+ if (version_res.ProductVersion.Trim ().Length == 0)
+ version_res.ProductVersion = version_res.FileVersion;
+ } else {
+ version_res.InternalName = Path.GetFileNameWithoutExtension (fileName);
+ }
+
AddUnmanagedResource (version_res);
}
{
if (name == null)
throw new ArgumentNullException ("name");
- if (name == String.Empty)
- throw new ArgumentException ("Name can't be null");
+ if (name.Length == 0)
+ throw new ArgumentException ("Empty name is not legal.", "name");
if (modules != null)
for (int i = 0; i < modules.Length; ++i)
throw not_supported ();
}
+ internal override Module[] GetModulesInternal () {
+ if (modules == null)
+ return new Module [0];
+ else
+ return (Module[])modules.Clone ();
+ }
+
+ internal override Type[] GetTypes (bool exportedOnly) {
+ Type[] res = null;
+ if (modules != null) {
+ for (int i = 0; i < modules.Length; ++i) {
+ Type[] types = modules [i].GetTypes ();
+ if (res == null)
+ res = types;
+ else {
+ Type[] tmp = new Type [res.Length + types.Length];
+ Array.Copy (res, 0, tmp, 0, res.Length);
+ Array.Copy (types, 0, tmp, res.Length, types.Length);
+ }
+ }
+ }
+ if (loaded_modules != null) {
+ for (int i = 0; i < loaded_modules.Length; ++i) {
+ Type[] types = loaded_modules [i].GetTypes ();
+ if (res == null)
+ res = types;
+ else {
+ Type[] tmp = new Type [res.Length + types.Length];
+ Array.Copy (res, 0, tmp, 0, res.Length);
+ Array.Copy (types, 0, tmp, res.Length, types.Length);
+ }
+ }
+ }
+
+ return res == null ? Type.EmptyTypes : res;
+ }
+
public override ManifestResourceInfo GetManifestResourceInfo(string resourceName) {
throw not_supported ();
}
throw not_supported ();
}
+ /*
+ * This is set when the the AssemblyBuilder is created by (g)mcs
+ * or vbnc.
+ */
+ internal bool IsCompilerContext
+ {
+ get { return is_compiler_context; }
+ }
+
internal bool IsSave {
get {
return access != (uint)AssemblyBuilderAccess.Run;
}
}
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ ModuleBuilder manifest_module;
+
+ //
+ // MS.NET seems to return a ModuleBuilder when GetManifestModule () is called
+ // on an assemblybuilder.
+ //
+ internal override Module GetManifestModule () {
+ if (manifest_module == null)
+ manifest_module = DefineDynamicModule ("Default Dynamic Module");
+ return manifest_module;
+ }
+#endif
+
#if NET_2_0
public
#else
if (entry_point.GetParameters ().Length == 1)
paramTypes = new Type [] { typeof (string) };
else
- paramTypes = new Type [0];
+ paramTypes = Type.EmptyTypes;
MethodBuilder mb = mainModule.DefineGlobalMethod ("__EntryPoint$", MethodAttributes.Static|MethodAttributes.PrivateScope, entry_point.ReturnType, paramTypes);
ILGenerator ilgen = mb.GetILGenerator ();
if (customBuilder == null)
throw new ArgumentNullException ("customBuilder");
- string attrname = customBuilder.Ctor.ReflectedType.FullName;
- byte[] data;
- int pos;
-
- if (attrname == "System.Reflection.AssemblyVersionAttribute") {
- version = create_assembly_version (customBuilder.string_arg ());
- return;
- } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
- culture = GetCultureString (customBuilder.string_arg ());
- } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
- data = customBuilder.Data;
- pos = 2;
- algid = (uint)data [pos];
- algid |= ((uint)data [pos + 1]) << 8;
- algid |= ((uint)data [pos + 2]) << 16;
- algid |= ((uint)data [pos + 3]) << 24;
- } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
- data = customBuilder.Data;
- pos = 2;
- flags = (uint)data [pos];
- flags |= ((uint)data [pos + 1]) << 8;
- flags |= ((uint)data [pos + 2]) << 16;
- flags |= ((uint)data [pos + 3]) << 24;
- return;
+ if (IsCompilerContext) {
+ string attrname = customBuilder.Ctor.ReflectedType.FullName;
+ byte [] data;
+ int pos;
+
+ if (attrname == "System.Reflection.AssemblyVersionAttribute") {
+ version = create_assembly_version (customBuilder.string_arg ());
+ return;
+ } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
+ culture = GetCultureString (customBuilder.string_arg ());
+ } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
+ data = customBuilder.Data;
+ pos = 2;
+ algid = (uint) data [pos];
+ algid |= ((uint) data [pos + 1]) << 8;
+ algid |= ((uint) data [pos + 2]) << 16;
+ algid |= ((uint) data [pos + 3]) << 24;
+ } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
+ data = customBuilder.Data;
+ pos = 2;
+ flags |= (uint) data [pos];
+ flags |= ((uint) data [pos + 1]) << 8;
+ flags |= ((uint) data [pos + 2]) << 16;
+ flags |= ((uint) data [pos + 3]) << 24;
+
+#if NET_2_0
+ // ignore PublicKey flag if assembly is not strongnamed
+ if (sn == null)
+ flags &= ~(uint) AssemblyNameFlags.PublicKey;
+#endif
+ }
}
if (cattrs != null) {
throw new ArgumentNullException ("name");
if (fileName == null)
throw new ArgumentNullException ("fileName");
- if (name == String.Empty)
- throw new ArgumentException ("name cannot be empty", "name");
- if (fileName == String.Empty)
- throw new ArgumentException ("fileName cannot be empty", "fileName");
+ if (name.Length == 0)
+ throw new ArgumentException ("Empty name is not legal.", "name");
+ if (fileName.Length == 0)
+ throw new ArgumentException ("Empty file name is not legal.", "fileName");
if (Path.GetFileName (fileName) != fileName)
- throw new ArgumentException ("fileName '" + fileName + "' must not include a path.");
+ throw new ArgumentException ("fileName '" + fileName + "' must not include a path.", "fileName");
// Resource files are created/searched under the assembly storage
// directory
AssemblyName an = base.UnprotectedGetName ();
if (sn != null) {
an.SetPublicKey (sn.PublicKey);
+ an.SetPublicKeyToken (sn.PublicKeyToken);
}
return an;
}