using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
{
try {
Assembly.Builder.Save (Basename (name));
- } catch (System.IO.IOException io){
+ }
+ catch (COMException) {
+ if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))
+ throw;
+
+ // FIXME: it seems Microsoft AssemblyBuilder doesn't like to delay sign assemblies
+ Report.Error (1548, "Couldn't delay-sign the assembly with the '" +
+ RootContext.StrongNameKeyFile +
+ "', Use MCS with the Mono runtime or CSC to compile this assembly.");
+ }
+ catch (System.IO.IOException io) {
Report.Error (16, "Could not write to file `"+name+"', cause: " + io.Message);
}
}
//
public void EmitThis ()
{
- ig.Emit (OpCodes.Ldarg_0);
-
- if (!IsStatic){
- if (InIterator)
- ig.Emit (OpCodes.Ldfld, IteratorHandler.Current.this_field);
- else
- throw new Exception ("EmitThis for an unknown state");
- }
+ if (InIterator){
+ ig.Emit (OpCodes.Ldarg_0);
+ if (!IsStatic){
+ FieldBuilder this_field = IteratorHandler.Current.this_field;
+ if (TypeManager.IsValueType (this_field.FieldType))
+ ig.Emit (OpCodes.Ldflda, this_field);
+ else
+ ig.Emit (OpCodes.Ldfld, this_field);
+ }
+ } else
+ ig.Emit (OpCodes.Ldarg_0);
}
public Expression GetThis (Location loc)
}
- public abstract class CommonAssemblyModulClass: IAttributeSupport {
- protected Hashtable m_attributes;
+ public abstract class CommonAssemblyModulClass: Attributable {
+ static string[] attribute_targets = new string [] { "assembly", "module" };
- protected CommonAssemblyModulClass ()
+ protected CommonAssemblyModulClass ():
+ base (null)
{
- m_attributes = new Hashtable ();
}
- //
- // Adds a global attribute that was declared in `container',
- // the attribute is in `attr', and it was defined at `loc'
- //
- public void AddAttribute (TypeContainer container, AttributeSection attr)
+ // TODO: The error can be reported more than once
+ public void AddAttributes (ArrayList attrs)
{
- NamespaceEntry ns = container.NamespaceEntry;
- Attributes a = (Attributes) m_attributes [ns];
-
- if (a == null) {
- m_attributes [ns] = new Attributes (attr);
+ if (OptAttributes == null) {
+ OptAttributes = new Attributes (attrs);
+ OptAttributes.CheckTargets (ValidAttributeTargets);
return;
}
-
- a.AddAttributeSection (attr);
+ OptAttributes.AddAttributes (attrs);
+ OptAttributes.CheckTargets (ValidAttributeTargets);
}
- public virtual void Emit ()
+ public virtual void Emit (TypeContainer tc)
{
- if (m_attributes.Count < 1)
+ if (OptAttributes == null)
return;
- TypeContainer dummy = new TypeContainer ();
- EmitContext temp_ec = new EmitContext (dummy, Mono.CSharp.Location.Null, null, null, 0, false);
-
- foreach (DictionaryEntry de in m_attributes)
- {
- NamespaceEntry ns = (NamespaceEntry) de.Key;
- Attributes attrs = (Attributes) de.Value;
-
- dummy.NamespaceEntry = ns;
- Attribute.ApplyAttributes (temp_ec, null, this, attrs);
- }
+ EmitContext ec = new EmitContext (tc, Mono.CSharp.Location.Null, null, null, 0, false);
+ OptAttributes.Emit (ec, this);
}
-
+
protected Attribute GetClsCompliantAttribute ()
{
- if (m_attributes.Count < 1)
+ if (OptAttributes == null)
return null;
EmitContext temp_ec = new EmitContext (new TypeContainer (), Mono.CSharp.Location.Null, null, null, 0, false);
-
- foreach (DictionaryEntry de in m_attributes) {
-
- NamespaceEntry ns = (NamespaceEntry) de.Key;
- Attributes attrs = (Attributes) de.Value;
- temp_ec.TypeContainer.NamespaceEntry = ns;
-
- foreach (AttributeSection attr_section in attrs.AttributeSections) {
- foreach (Attribute a in attr_section.Attributes) {
- TypeExpr attributeType = RootContext.LookupType (temp_ec.DeclSpace, Attributes.GetAttributeFullName (a.Name), true, Location.Null);
- if (attributeType.Type == TypeManager.cls_compliant_attribute_type) {
- a.Resolve (temp_ec);
- return a;
- }
- }
- }
+ Attribute a = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, temp_ec);
+ if (a != null) {
+ a.Resolve (temp_ec);
}
- return null;
+ return a;
}
-
- #region IAttributeSupport Members
- public abstract void SetCustomAttribute(CustomAttributeBuilder customBuilder);
- #endregion
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
-
public class AssemblyClass: CommonAssemblyModulClass {
// TODO: make it private and move all builder based methods here
}
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Assembly;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return is_cls_compliant;
+ }
+
public void ResolveClsCompliance ()
{
Attribute a = GetClsCompliantAttribute ();
public AssemblyName GetAssemblyName (string name, string output)
{
- // scan assembly attributes for strongname related attr
- foreach (DictionaryEntry nsattr in m_attributes) {
- ArrayList list = ((Attributes)nsattr.Value).AttributeSections;
- for (int i=0; i < list.Count; i++) {
- AttributeSection asect = (AttributeSection) list [i];
- if (asect.Target != "assembly")
+ if (OptAttributes != null) {
+ foreach (Attribute a in OptAttributes.Attrs) {
+ if (a.Target != "assembly")
continue;
- // strongname attributes don't support AllowMultiple
- Attribute a = (Attribute) asect.Attributes [0];
+ // TODO: This code is buggy: comparing Attribute name without resolving it is wrong.
+ // However, this is invoked by CodeGen.Init, at which time none of the namespaces
+ // are loaded yet.
switch (a.Name) {
case "AssemblyKeyFile":
+ case "AssemblyKeyFileAttribute":
+ case "System.Reflection.AssemblyKeyFileAttribute":
if (RootContext.StrongNameKeyFile != null) {
Report.Warning (1616, "Compiler option -keyfile overrides " +
"AssemblyKeyFileAttribute");
}
break;
case "AssemblyKeyName":
+ case "AssemblyKeyNameAttribute":
+ case "System.Reflection.AssemblyKeyNameAttribute":
if (RootContext.StrongNameKeyContainer != null) {
Report.Warning (1616, "Compiler option -keycontainer overrides " +
"AssemblyKeyNameAttribute");
}
break;
case "AssemblyDelaySign":
+ case "AssemblyDelaySignAttribute":
+ case "System.Reflection.AssemblyDelaySignAttribute":
RootContext.StrongNameDelaySign = a.GetBoolean ();
break;
}
}
if (exist) {
- using (FileStream fs = new FileStream (filename, FileMode.Open)) {
+ using (FileStream fs = new FileStream (filename, FileMode.Open, FileAccess.Read)) {
byte[] snkeypair = new byte [fs.Length];
fs.Read (snkeypair, 0, snkeypair.Length);
- try {
- // this will import public or private/public keys
- RSA rsa = CryptoConvert.FromCapiKeyBlob (snkeypair);
- // only the public part must be supplied if signature is delayed
- byte[] key = CryptoConvert.ToCapiKeyBlob (rsa, !RootContext.StrongNameDelaySign);
- an.KeyPair = new StrongNameKeyPair (key);
+ if (RootContext.StrongNameDelaySign) {
+ // delayed signing - DO NOT include private key
+ try {
+ // check for possible ECMA key
+ if (snkeypair.Length == 16) {
+ // will be rejected if not "the" ECMA key
+ an.KeyPair = new StrongNameKeyPair (snkeypair);
+ }
+ else {
+ // take it, with or without, a private key
+ RSA rsa = CryptoConvert.FromCapiKeyBlob (snkeypair);
+ // and make sure we only feed the public part to Sys.Ref
+ byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob (rsa);
+ an.KeyPair = new StrongNameKeyPair (publickey);
+ }
+ }
+ catch (Exception) {
+ Report.Error (1548, "Could not strongname the assembly. File `" +
+ RootContext.StrongNameKeyFile + "' incorrectly encoded.");
+ Environment.Exit (1);
+ }
}
- catch (CryptographicException) {
- Report.Error (1548, "Could not strongname the assembly. File `" +
- RootContext.StrongNameKeyFile + "' incorrectly encoded.");
- Environment.Exit (1);
+ else {
+ // no delay so we make sure we have the private key
+ try {
+ CryptoConvert.FromCapiPrivateKeyBlob (snkeypair);
+ an.KeyPair = new StrongNameKeyPair (snkeypair);
+ }
+ catch (CryptographicException) {
+ if (snkeypair.Length == 16) {
+ // error # is different for ECMA key
+ Report.Error (1606, "Could not strongname the assembly. " +
+ "ECMA key can only be used to delay-sign assemblies");
+ }
+ else {
+ Report.Error (1548, "Could not strongname the assembly. File `" +
+ RootContext.StrongNameKeyFile +
+ "' doesn't have a private key.");
+ }
+ Environment.Exit (1);
+ }
}
}
}
return an;
}
- public override void SetCustomAttribute(CustomAttributeBuilder customBuilder)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
{
Builder.SetCustomAttribute (customBuilder);
}
public class ModuleClass: CommonAssemblyModulClass {
// TODO: make it private and move all builder based methods here
public ModuleBuilder Builder;
-
bool m_module_is_unsafe;
public ModuleClass (bool is_unsafe)
m_module_is_unsafe = is_unsafe;
}
- public override void Emit ()
- {
- base.Emit ();
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Module;
+ }
+ }
- Attribute a = GetClsCompliantAttribute ();
- if (a != null) {
- Report.Warning (3012, a.Location);
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return CodeGen.Assembly.IsClsCompliant;
}
+ public override void Emit (TypeContainer tc)
+ {
+ base.Emit (tc);
+
if (!m_module_is_unsafe)
return;
return;
}
- SetCustomAttribute (new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]));
+ ApplyAttributeBuilder (null, new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]));
}
- public override void SetCustomAttribute(CustomAttributeBuilder customBuilder)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
{
+ if (a != null && a.Type == TypeManager.cls_compliant_attribute_type) {
+ Report.Warning_T (3012, a.Location);
+ return;
+ }
+
Builder.SetCustomAttribute (customBuilder);
}
}