Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/ikvmc
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2011-07-11 11:32:40 +0400
committerjfrijters <jfrijters>2011-07-11 11:32:40 +0400
commit141e584ee62343bbfffa6b75dac9f25a4aaf5452 (patch)
tree880981eb7f520046be84967199391c3eb645202c /ikvmc
parent939499a05638bc6c690f46a14557907f955a84dd (diff)
Extended map file support for ldtoken opcode to support loading method and field tokens.
Diffstat (limited to 'ikvmc')
-rw-r--r--ikvmc/CompilerClassLoader.cs8
-rw-r--r--ikvmc/remapper.cs153
2 files changed, 160 insertions, 1 deletions
diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs
index 9f319c56..3ccd79f0 100644
--- a/ikvmc/CompilerClassLoader.cs
+++ b/ikvmc/CompilerClassLoader.cs
@@ -3405,6 +3405,8 @@ namespace IKVM.Internal
StartErrors = 4000,
UnableToCreateProxy = 4001,
DuplicateProxy = 4002,
+ MapXmlUnableToResolveOpCode = 4003,
+ MapXmlError = 4004,
}
static class StaticCompiler
@@ -3623,6 +3625,12 @@ namespace IKVM.Internal
case Message.DuplicateProxy:
msg = "duplicate proxy \"{0}\"";
break;
+ case Message.MapXmlUnableToResolveOpCode:
+ msg = "unable to resolve opcode in remap file: {0}";
+ break;
+ case Message.MapXmlError:
+ msg = "error in remap file: {0}";
+ break;
case Message.UnknownWarning:
msg = "{0}";
break;
diff --git a/ikvmc/remapper.cs b/ikvmc/remapper.cs
index e121e66f..c21a8b0d 100644
--- a/ikvmc/remapper.cs
+++ b/ikvmc/remapper.cs
@@ -71,6 +71,38 @@ namespace IKVM.Internal.MapXml
}
internal abstract void Generate(CodeGenContext context, CodeEmitter ilgen);
+
+ public override string ToString()
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ sb.Append('<');
+ object[] attr = GetType().GetCustomAttributes(typeof(XmlTypeAttribute), false);
+ if (attr.Length == 1)
+ {
+ sb.Append(((XmlTypeAttribute)attr[0]).TypeName);
+ }
+ else
+ {
+ sb.Append(GetType().Name);
+ }
+ foreach (System.Reflection.FieldInfo field in GetType().GetFields())
+ {
+ if (!field.IsStatic)
+ {
+ object value = field.GetValue(this);
+ if (value != null)
+ {
+ attr = field.GetCustomAttributes(typeof(XmlAttributeAttribute), false);
+ if (attr.Length == 1)
+ {
+ sb.AppendFormat(" {0}=\"{1}\"", ((XmlAttributeAttribute)attr[0]).AttributeName, value);
+ }
+ }
+ }
+ }
+ sb.Append(" />");
+ return sb.ToString();
+ }
}
[XmlType("ldstr")]
@@ -1179,10 +1211,129 @@ namespace IKVM.Internal.MapXml
{
[XmlAttribute("type")]
public string type;
+ [XmlAttribute("class")]
+ public string Class;
+ [XmlAttribute("method")]
+ public string Method;
+ [XmlAttribute("field")]
+ public string Field;
+ [XmlAttribute("sig")]
+ public string Sig;
internal override void Generate(CodeGenContext context, CodeEmitter ilgen)
{
- ilgen.Emit(OpCodes.Ldtoken, StaticCompiler.GetTypeForMapXml(context.ClassLoader, type));
+ if (!Validate())
+ {
+ return;
+ }
+
+ MemberInfo member = Resolve(context);
+ Type type = member as Type;
+ MethodInfo method = member as MethodInfo;
+ ConstructorInfo constructor = member as ConstructorInfo;
+ FieldInfo field = member as FieldInfo;
+
+ if (type != null)
+ {
+ ilgen.Emit(OpCodes.Ldtoken, type);
+ }
+ else if (method != null)
+ {
+ ilgen.Emit(OpCodes.Ldtoken, method);
+ }
+ else if (constructor != null)
+ {
+ ilgen.Emit(OpCodes.Ldtoken, constructor);
+ }
+ else if (field != null)
+ {
+ ilgen.Emit(OpCodes.Ldtoken, field);
+ }
+ else
+ {
+ StaticCompiler.IssueMessage(Message.MapXmlUnableToResolveOpCode, ToString());
+ }
+ }
+
+ private bool Validate()
+ {
+ if (type != null && Class == null)
+ {
+ if (Method != null || Field != null || Sig != null)
+ {
+ StaticCompiler.IssueMessage(Message.MapXmlError, "not implemented: cannot use 'type' attribute with 'method' or 'field' attribute for ldtoken");
+ return false;
+ }
+ return true;
+ }
+ else if (Class != null && type == null)
+ {
+ if (Method == null && Field == null)
+ {
+ if (Sig != null)
+ {
+ StaticCompiler.IssueMessage(Message.MapXmlError, "cannot specify 'sig' attribute without either 'method' or 'field' attribute for ldtoken");
+ }
+ return true;
+ }
+ if (Method != null && Field != null)
+ {
+ StaticCompiler.IssueMessage(Message.MapXmlError, "cannot specify both 'method' and 'field' attribute for ldtoken");
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ StaticCompiler.IssueMessage(Message.MapXmlError, "must specify either 'type' or 'class' attribute for ldtoken");
+ return false;
+ }
+ }
+
+ private MemberInfo Resolve(CodeGenContext context)
+ {
+ if (type != null)
+ {
+ if (Class != null || Method != null || Field != null || Sig != null)
+ {
+ throw new NotImplementedException();
+ }
+ return StaticCompiler.GetTypeForMapXml(context.ClassLoader, type);
+ }
+ else if (Class != null)
+ {
+ TypeWrapper tw = context.ClassLoader.LoadClassByDottedNameFast(Class);
+ if (tw == null)
+ {
+ return null;
+ }
+ else if (Method != null)
+ {
+ MethodWrapper mw = tw.GetMethodWrapper(Method, Sig, false);
+ if (mw == null)
+ {
+ return null;
+ }
+ return mw.GetMethod();
+ }
+ else if (Field != null)
+ {
+ FieldWrapper fw = tw.GetFieldWrapper(Field, Sig);
+ if (fw == null)
+ {
+ return null;
+ }
+ return fw.GetField();
+ }
+ else
+ {
+ return tw.TypeAsBaseType;
+ }
+ }
+ else
+ {
+ return null;
+ }
}
}