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
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2014-07-09 16:25:08 +0400
committerjfrijters <jfrijters>2014-07-09 16:25:08 +0400
commite714b27336d2382f7c365c16579a687aa4ad5136 (patch)
treeb7f6bc3bfa9c0482e70dda43ce1aac84246643ed
parentbb2d12a8a4a7c1070ac19499170a26e96252704c (diff)
Added method and field reflection support for lambda classes.
-rw-r--r--runtime/LambdaMetafactory.cs22
-rw-r--r--runtime/TypeWrapper.cs53
2 files changed, 61 insertions, 14 deletions
diff --git a/runtime/LambdaMetafactory.cs b/runtime/LambdaMetafactory.cs
index 7ea26157..f2a5bc81 100644
--- a/runtime/LambdaMetafactory.cs
+++ b/runtime/LambdaMetafactory.cs
@@ -403,7 +403,7 @@ namespace IKVM.Internal
{
attr |= FieldAttributes.InitOnly;
}
- capturedFields[i] = tb.DefineField("c" + i, capturedTypes[i], attr);
+ capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr);
}
// constructor
@@ -479,7 +479,11 @@ namespace IKVM.Internal
private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters,
ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields)
{
- MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
+ MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
+ if (interfaceMethod.Name != interfaceMethod.RealName)
+ {
+ tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod());
+ }
CodeEmitter ilgen = CodeEmitter.Create(mb);
for (int i = 0; i < capturedFields.Length; i++)
{
@@ -680,17 +684,27 @@ namespace IKVM.Internal
private static void AddDefaultInterfaceMethods(DynamicTypeWrapper.FinishContext context, MethodWrapper[] methodList, TypeBuilder tb)
{
+ // we use special name to hide these from Java reflection
+ const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName;
TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory();
foreach (MethodWrapper mw in methodList)
{
if (!mw.IsAbstract)
{
- MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
+ MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr);
+ if (mw.Name != mw.RealName)
+ {
+ tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
+ }
DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw);
}
else if (IsObjectMethod(mw))
{
- MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
+ MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr);
+ if (mw.Name != mw.RealName)
+ {
+ tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
+ }
CodeEmitter ilgen = CodeEmitter.Create(mb);
for (int i = 0, count = mw.GetParameters().Length; i <= count; i++)
{
diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs
index e85879ac..8efd4d69 100644
--- a/runtime/TypeWrapper.cs
+++ b/runtime/TypeWrapper.cs
@@ -4989,13 +4989,13 @@ namespace IKVM.Internal
?? ClassLoaderWrapper.GetWrapperFromType(property.PropertyType);
}
- private static TypeWrapper GetFieldTypeWrapper(FieldInfo field)
+ internal static TypeWrapper GetFieldTypeWrapper(FieldInfo field)
{
return TypeWrapperFromModOpt(field.GetOptionalCustomModifiers())
?? ClassLoaderWrapper.GetWrapperFromType(field.FieldType);
}
- private static TypeWrapper GetParameterTypeWrapper(ParameterInfo param)
+ internal static TypeWrapper GetParameterTypeWrapper(ParameterInfo param)
{
TypeWrapper tw = TypeWrapperFromModOpt(param.GetOptionalCustomModifiers());
if (tw != null)
@@ -5760,18 +5760,51 @@ namespace IKVM.Internal
protected override void LazyPublishMembers()
{
- MethodInfo mi = type.GetMethod("writeReplace", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null);
- if (mi != null)
+ List<MethodWrapper> methods = new List<MethodWrapper>();
+ foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
- SetMethods(new MethodWrapper[] {
- new TypicalMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", mi, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, Modifiers.Private, MemberFlags.None)
- });
+ if (mi.IsSpecialName)
+ {
+ // we use special name to hide default methods
+ }
+ else if (mi.IsPublic)
+ {
+ TypeWrapper returnType;
+ TypeWrapper[] parameterTypes;
+ string signature;
+ GetSig(mi, out returnType, out parameterTypes, out signature);
+ methods.Add(new TypicalMethodWrapper(this, mi.Name, signature, mi, returnType, parameterTypes, Modifiers.Public, MemberFlags.None));
+ }
+ else if (mi.Name == "writeReplace")
+ {
+ methods.Add(new TypicalMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", mi, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray,
+ Modifiers.Private | Modifiers.Final, MemberFlags.None));
+ }
}
- else
+ SetMethods(methods.ToArray());
+ List<FieldWrapper> fields = new List<FieldWrapper>();
+ foreach (FieldInfo fi in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
- SetMethods(MethodWrapper.EmptyArray);
+ TypeWrapper fieldType = CompiledTypeWrapper.GetFieldTypeWrapper(fi);
+ fields.Add(new SimpleFieldWrapper(this, fieldType, fi, fi.Name, fieldType.SigName, new ExModifiers(Modifiers.Private | Modifiers.Final, false)));
}
- SetFields(FieldWrapper.EmptyArray);
+ SetFields(fields.ToArray());
+ }
+
+ private void GetSig(MethodInfo mi, out TypeWrapper returnType, out TypeWrapper[] parameterTypes, out string signature)
+ {
+ returnType = CompiledTypeWrapper.GetParameterTypeWrapper(mi.ReturnParameter);
+ ParameterInfo[] parameters = mi.GetParameters();
+ parameterTypes = new TypeWrapper[parameters.Length];
+ System.Text.StringBuilder sb = new System.Text.StringBuilder("(");
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ parameterTypes[i] = CompiledTypeWrapper.GetParameterTypeWrapper(parameters[i]);
+ sb.Append(parameterTypes[i].SigName);
+ }
+ sb.Append(')');
+ sb.Append(returnType.SigName);
+ signature = sb.ToString();
}
}
}