2
Copyright (C) 2002-2012 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Collections.Generic;
26
#if STATIC_COMPILER || STUB_GENERATOR
27
using IKVM.Reflection;
28
using IKVM.Reflection.Emit;
29
using Type = IKVM.Reflection.Type;
31
using System.Reflection;
32
using System.Reflection.Emit;
34
using System.Diagnostics;
35
using System.Security;
36
using System.Security.Permissions;
37
using IKVM.Attributes;
39
namespace IKVM.Internal
41
static class StringConstants
43
internal static readonly string CLINIT = string.Intern("<clinit>");
44
internal static readonly string INIT = string.Intern("<init>");
45
internal static readonly string SIG_VOID = string.Intern("()V");
46
internal static readonly string FINALIZE = string.Intern("finalize");
47
internal static readonly string CLONE = string.Intern("clone");
52
internal readonly Modifiers Modifiers;
53
internal readonly bool IsInternal;
55
internal ExModifiers(Modifiers modifiers, bool isInternal)
57
this.Modifiers = modifiers;
58
this.IsInternal = isInternal;
62
static class AttributeHelper
64
private static CustomAttributeBuilder hideFromJavaAttribute;
66
private static CustomAttributeBuilder ghostInterfaceAttribute;
67
private static CustomAttributeBuilder deprecatedAttribute;
68
private static CustomAttributeBuilder editorBrowsableNever;
69
private static ConstructorInfo implementsAttribute;
70
private static ConstructorInfo throwsAttribute;
71
private static ConstructorInfo sourceFileAttribute;
72
private static ConstructorInfo lineNumberTableAttribute1;
73
private static ConstructorInfo lineNumberTableAttribute2;
74
private static ConstructorInfo enclosingMethodAttribute;
75
private static ConstructorInfo signatureAttribute;
76
private static CustomAttributeBuilder paramArrayAttribute;
77
private static ConstructorInfo nonNestedInnerClassAttribute;
78
private static ConstructorInfo nonNestedOuterClassAttribute;
79
private static Type typeofModifiers = JVM.LoadType(typeof(Modifiers));
80
private static Type typeofSourceFileAttribute = JVM.LoadType(typeof(SourceFileAttribute));
81
private static Type typeofLineNumberTableAttribute = JVM.LoadType(typeof(LineNumberTableAttribute));
82
#endif // STATIC_COMPILER
83
private static Type typeofRemappedClassAttribute = JVM.LoadType(typeof(RemappedClassAttribute));
84
private static Type typeofRemappedTypeAttribute = JVM.LoadType(typeof(RemappedTypeAttribute));
85
private static Type typeofModifiersAttribute = JVM.LoadType(typeof(ModifiersAttribute));
86
private static Type typeofRemappedInterfaceMethodAttribute = JVM.LoadType(typeof(RemappedInterfaceMethodAttribute));
87
private static Type typeofNameSigAttribute = JVM.LoadType(typeof(NameSigAttribute));
88
private static Type typeofJavaModuleAttribute = JVM.LoadType(typeof(JavaModuleAttribute));
89
private static Type typeofSignatureAttribute = JVM.LoadType(typeof(SignatureAttribute));
90
private static Type typeofInnerClassAttribute = JVM.LoadType(typeof(InnerClassAttribute));
91
private static Type typeofImplementsAttribute = JVM.LoadType(typeof(ImplementsAttribute));
92
private static Type typeofGhostInterfaceAttribute = JVM.LoadType(typeof(GhostInterfaceAttribute));
93
private static Type typeofExceptionIsUnsafeForMappingAttribute = JVM.LoadType(typeof(ExceptionIsUnsafeForMappingAttribute));
94
private static Type typeofThrowsAttribute = JVM.LoadType(typeof(ThrowsAttribute));
95
private static Type typeofHideFromReflectionAttribute = JVM.LoadType(typeof(HideFromReflectionAttribute));
96
private static Type typeofHideFromJavaAttribute = JVM.LoadType(typeof(HideFromJavaAttribute));
97
private static Type typeofNoPackagePrefixAttribute = JVM.LoadType(typeof(NoPackagePrefixAttribute));
98
private static Type typeofAnnotationAttributeAttribute = JVM.LoadType(typeof(AnnotationAttributeAttribute));
99
private static Type typeofNonNestedInnerClassAttribute = JVM.LoadType(typeof(NonNestedInnerClassAttribute));
100
private static Type typeofNonNestedOuterClassAttribute = JVM.LoadType(typeof(NonNestedOuterClassAttribute));
101
private static Type typeofEnclosingMethodAttribute = JVM.LoadType(typeof(EnclosingMethodAttribute));
104
private static object ParseValue(ClassLoaderWrapper loader, TypeWrapper tw, string val)
106
if(tw == CoreClasses.java.lang.String.Wrapper)
110
else if(tw.TypeAsTBD.IsEnum)
112
return EnumHelper.Parse(tw.TypeAsTBD, val);
114
else if(tw.TypeAsTBD == Types.Type)
116
TypeWrapper valtw = loader.LoadClassByDottedNameFast(val);
119
return valtw.TypeAsBaseType;
121
return StaticCompiler.Universe.GetType(val, true);
123
else if(tw == PrimitiveTypeWrapper.BOOLEAN)
125
return bool.Parse(val);
127
else if(tw == PrimitiveTypeWrapper.BYTE)
129
return (byte)sbyte.Parse(val);
131
else if(tw == PrimitiveTypeWrapper.CHAR)
133
return char.Parse(val);
135
else if(tw == PrimitiveTypeWrapper.SHORT)
137
return short.Parse(val);
139
else if(tw == PrimitiveTypeWrapper.INT)
141
return int.Parse(val);
143
else if(tw == PrimitiveTypeWrapper.FLOAT)
145
return float.Parse(val);
147
else if(tw == PrimitiveTypeWrapper.LONG)
149
return long.Parse(val);
151
else if(tw == PrimitiveTypeWrapper.DOUBLE)
153
return double.Parse(val);
157
throw new NotImplementedException();
161
internal static void SetCustomAttribute(ClassLoaderWrapper loader, TypeBuilder tb, IKVM.Internal.MapXml.Attribute attr)
163
bool declarativeSecurity;
164
CustomAttributeBuilder cab = CreateCustomAttribute(loader, attr, out declarativeSecurity);
165
if (declarativeSecurity)
167
tb.__AddDeclarativeSecurity(cab);
171
tb.SetCustomAttribute(cab);
175
internal static void SetCustomAttribute(ClassLoaderWrapper loader, FieldBuilder fb, IKVM.Internal.MapXml.Attribute attr)
177
fb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
180
internal static void SetCustomAttribute(ClassLoaderWrapper loader, ParameterBuilder pb, IKVM.Internal.MapXml.Attribute attr)
182
pb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
185
internal static void SetCustomAttribute(ClassLoaderWrapper loader, MethodBuilder mb, IKVM.Internal.MapXml.Attribute attr)
187
bool declarativeSecurity;
188
CustomAttributeBuilder cab = CreateCustomAttribute(loader, attr, out declarativeSecurity);
189
if (declarativeSecurity)
191
mb.__AddDeclarativeSecurity(cab);
195
mb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
199
internal static void SetCustomAttribute(ClassLoaderWrapper loader, PropertyBuilder pb, IKVM.Internal.MapXml.Attribute attr)
201
pb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
204
internal static void SetCustomAttribute(ClassLoaderWrapper loader, AssemblyBuilder ab, IKVM.Internal.MapXml.Attribute attr)
206
ab.SetCustomAttribute(CreateCustomAttribute(loader, attr));
209
private static void GetAttributeArgsAndTypes(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr, out Type[] argTypes, out object[] args)
211
// TODO add error handling
212
TypeWrapper[] twargs = loader.ArgTypeWrapperListFromSigNoThrow(attr.Sig);
213
argTypes = new Type[twargs.Length];
214
args = new object[argTypes.Length];
215
for(int i = 0; i < twargs.Length; i++)
217
argTypes[i] = twargs[i].TypeAsSignatureType;
218
TypeWrapper tw = twargs[i];
219
if(tw == CoreClasses.java.lang.Object.Wrapper)
221
tw = loader.FieldTypeWrapperFromSigNoThrow(attr.Params[i].Sig);
225
Array arr = Array.CreateInstance(Type.__GetSystemType(Type.GetTypeCode(tw.ElementTypeWrapper.TypeAsArrayType)), attr.Params[i].Elements.Length);
226
for(int j = 0; j < arr.Length; j++)
228
arr.SetValue(ParseValue(loader, tw.ElementTypeWrapper, attr.Params[i].Elements[j].Value), j);
234
args[i] = ParseValue(loader, tw, attr.Params[i].Value);
239
private static CustomAttributeBuilder CreateCustomAttribute(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr)
242
return CreateCustomAttribute(loader, attr, out ignore);
245
private static CustomAttributeBuilder CreateCustomAttribute(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr, out bool isDeclarativeSecurity)
247
// TODO add error handling
250
GetAttributeArgsAndTypes(loader, attr, out argTypes, out args);
251
if(attr.Type != null)
253
Type t = StaticCompiler.GetTypeForMapXml(loader, attr.Type);
254
isDeclarativeSecurity = t.IsSubclassOf(Types.SecurityAttribute);
255
ConstructorInfo ci = t.GetConstructor(argTypes);
258
throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{1}", attr.Type, attr.Sig));
260
PropertyInfo[] namedProperties;
261
object[] propertyValues;
262
if(attr.Properties != null)
264
namedProperties = new PropertyInfo[attr.Properties.Length];
265
propertyValues = new object[attr.Properties.Length];
266
for(int i = 0; i < namedProperties.Length; i++)
268
namedProperties[i] = t.GetProperty(attr.Properties[i].Name);
269
propertyValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Properties[i].Sig), attr.Properties[i].Value);
274
namedProperties = new PropertyInfo[0];
275
propertyValues = new object[0];
277
FieldInfo[] namedFields;
278
object[] fieldValues;
279
if(attr.Fields != null)
281
namedFields = new FieldInfo[attr.Fields.Length];
282
fieldValues = new object[attr.Fields.Length];
283
for(int i = 0; i < namedFields.Length; i++)
285
namedFields[i] = t.GetField(attr.Fields[i].Name);
286
fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Fields[i].Sig), attr.Fields[i].Value);
291
namedFields = new FieldInfo[0];
292
fieldValues = new object[0];
294
return new CustomAttributeBuilder(ci, args, namedProperties, propertyValues, namedFields, fieldValues);
298
if(attr.Properties != null)
300
throw new NotImplementedException("Setting property values on Java attributes is not implemented");
302
TypeWrapper t = loader.LoadClassByDottedName(attr.Class);
303
isDeclarativeSecurity = t.TypeAsBaseType.IsSubclassOf(Types.SecurityAttribute);
304
FieldInfo[] namedFields;
305
object[] fieldValues;
306
if(attr.Fields != null)
308
namedFields = new FieldInfo[attr.Fields.Length];
309
fieldValues = new object[attr.Fields.Length];
310
for(int i = 0; i < namedFields.Length; i++)
312
FieldWrapper fw = t.GetFieldWrapper(attr.Fields[i].Name, attr.Fields[i].Sig);
314
namedFields[i] = fw.GetField();
315
fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Fields[i].Sig), attr.Fields[i].Value);
320
namedFields = new FieldInfo[0];
321
fieldValues = new object[0];
323
MethodWrapper mw = t.GetMethodWrapper("<init>", attr.Sig, false);
326
throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{1}", attr.Class, attr.Sig));
329
ConstructorInfo ci = (mw.GetMethod() as ConstructorInfo) ?? ((MethodInfo)mw.GetMethod()).__AsConstructorInfo();
330
return new CustomAttributeBuilder(ci, args, namedFields, fieldValues);
334
private static Assembly GetSystemAssembly()
336
AssemblyName name = Types.Object.Assembly.GetName();
337
name.Name = "System";
338
return StaticCompiler.Load(name.FullName);
341
private static CustomAttributeBuilder GetEditorBrowsableNever()
343
if (editorBrowsableNever == null)
345
Assembly system = GetSystemAssembly();
346
editorBrowsableNever = new CustomAttributeBuilder(system.GetType("System.ComponentModel.EditorBrowsableAttribute", true).GetConstructor(new Type[] { system.GetType("System.ComponentModel.EditorBrowsableState", true) }), new object[] { (int)System.ComponentModel.EditorBrowsableState.Never });
348
return editorBrowsableNever;
351
internal static void SetEditorBrowsableNever(TypeBuilder tb)
353
tb.SetCustomAttribute(GetEditorBrowsableNever());
356
internal static void SetEditorBrowsableNever(MethodBuilder mb)
358
mb.SetCustomAttribute(GetEditorBrowsableNever());
361
internal static void SetEditorBrowsableNever(PropertyBuilder pb)
363
pb.SetCustomAttribute(GetEditorBrowsableNever());
366
internal static void SetDeprecatedAttribute(MethodBuilder mb)
368
if(deprecatedAttribute == null)
370
deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
372
mb.SetCustomAttribute(deprecatedAttribute);
375
internal static void SetDeprecatedAttribute(TypeBuilder tb)
377
if(deprecatedAttribute == null)
379
deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
381
tb.SetCustomAttribute(deprecatedAttribute);
384
internal static void SetDeprecatedAttribute(FieldBuilder fb)
386
if(deprecatedAttribute == null)
388
deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
390
fb.SetCustomAttribute(deprecatedAttribute);
393
internal static void SetDeprecatedAttribute(PropertyBuilder pb)
395
if(deprecatedAttribute == null)
397
deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
399
pb.SetCustomAttribute(deprecatedAttribute);
402
internal static void SetThrowsAttribute(MethodBuilder mb, string[] exceptions)
404
if(exceptions != null && exceptions.Length != 0)
406
if(throwsAttribute == null)
408
throwsAttribute = typeofThrowsAttribute.GetConstructor(new Type[] { JVM.Import(typeof(string[])) });
410
mb.SetCustomAttribute(new CustomAttributeBuilder(throwsAttribute, new object[] { exceptions }));
414
internal static void SetGhostInterface(TypeBuilder typeBuilder)
416
if(ghostInterfaceAttribute == null)
418
ghostInterfaceAttribute = new CustomAttributeBuilder(typeofGhostInterfaceAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
420
typeBuilder.SetCustomAttribute(ghostInterfaceAttribute);
423
internal static void SetNonNestedInnerClass(TypeBuilder typeBuilder, string className)
425
if(nonNestedInnerClassAttribute == null)
427
nonNestedInnerClassAttribute = typeofNonNestedInnerClassAttribute.GetConstructor(new Type[] { Types.String });
429
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedInnerClassAttribute, new object[] { className }));
432
internal static void SetNonNestedOuterClass(TypeBuilder typeBuilder, string className)
434
if(nonNestedOuterClassAttribute == null)
436
nonNestedOuterClassAttribute = typeofNonNestedOuterClassAttribute.GetConstructor(new Type[] { Types.String });
438
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedOuterClassAttribute, new object[] { className }));
440
#endif // STATIC_COMPILER
442
internal static void HideFromReflection(MethodBuilder mb)
444
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
445
mb.SetCustomAttribute(cab);
448
internal static void HideFromReflection(MethodBuilder mb, int reason)
450
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(new Type[] { Types.Int32 }), new object[] { reason });
451
mb.SetCustomAttribute(cab);
454
internal static void HideFromReflection(FieldBuilder fb)
456
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
457
fb.SetCustomAttribute(cab);
460
internal static void HideFromReflection(PropertyBuilder pb)
462
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
463
pb.SetCustomAttribute(cab);
466
internal static bool IsHideFromReflection(MemberInfo mi)
468
return mi.IsDefined(typeofHideFromReflectionAttribute, false);
471
internal static void HideFromJava(TypeBuilder typeBuilder)
473
if(hideFromJavaAttribute == null)
475
hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
477
typeBuilder.SetCustomAttribute(hideFromJavaAttribute);
480
internal static void HideFromJava(MethodBuilder mb)
482
if(hideFromJavaAttribute == null)
484
hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
486
mb.SetCustomAttribute(hideFromJavaAttribute);
489
internal static void HideFromJava(FieldBuilder fb)
491
if(hideFromJavaAttribute == null)
493
hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
495
fb.SetCustomAttribute(hideFromJavaAttribute);
499
internal static void HideFromJava(PropertyBuilder pb)
501
if(hideFromJavaAttribute == null)
503
hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
505
pb.SetCustomAttribute(hideFromJavaAttribute);
507
#endif // STATIC_COMPILER
509
internal static bool IsHideFromJava(Type type)
511
return type.IsDefined(typeofHideFromJavaAttribute, false)
512
|| (type.IsNested && (type.DeclaringType.IsDefined(typeofHideFromJavaAttribute, false) || type.Name.StartsWith("__<", StringComparison.Ordinal)));
515
internal static bool IsHideFromJava(MemberInfo mi)
517
// NOTE all privatescope fields and methods are "hideFromJava"
518
// because Java cannot deal with the potential name clashes
519
FieldInfo fi = mi as FieldInfo;
520
if(fi != null && (fi.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.PrivateScope)
524
MethodBase mb = mi as MethodBase;
525
if(mb != null && (mb.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope)
529
if (mi.Name.StartsWith("__<", StringComparison.Ordinal))
533
return mi.IsDefined(typeofHideFromJavaAttribute, false);
537
internal static void SetImplementsAttribute(TypeBuilder typeBuilder, TypeWrapper[] ifaceWrappers)
539
if(ifaceWrappers != null && ifaceWrappers.Length != 0)
541
string[] interfaces = new string[ifaceWrappers.Length];
542
for(int i = 0; i < interfaces.Length; i++)
544
interfaces[i] = ifaceWrappers[i].Name;
546
if(implementsAttribute == null)
548
implementsAttribute = typeofImplementsAttribute.GetConstructor(new Type[] { JVM.Import(typeof(string[])) });
550
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(implementsAttribute, new object[] { interfaces }));
555
internal static bool IsGhostInterface(Type type)
557
return type.IsDefined(typeofGhostInterfaceAttribute, false);
560
internal static bool IsRemappedType(Type type)
562
return type.IsDefined(typeofRemappedTypeAttribute, false);
565
internal static bool IsExceptionIsUnsafeForMapping(Type type)
567
return type.IsDefined(typeofExceptionIsUnsafeForMappingAttribute, false);
570
internal static ModifiersAttribute GetModifiersAttribute(MemberInfo member)
572
#if !STATIC_COMPILER && !STUB_GENERATOR
573
object[] attr = member.GetCustomAttributes(typeof(ModifiersAttribute), false);
574
return attr.Length == 1 ? (ModifiersAttribute)attr[0] : null;
576
IList<CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(member, typeofModifiersAttribute, false);
579
IList<CustomAttributeTypedArgument> args = attr[0].ConstructorArguments;
582
return new ModifiersAttribute((Modifiers)args[0].Value, (bool)args[1].Value);
584
return new ModifiersAttribute((Modifiers)args[0].Value);
590
internal static ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate)
592
ModifiersAttribute attr = GetModifiersAttribute(mb);
595
return new ExModifiers(attr.Modifiers, attr.IsInternal);
597
Modifiers modifiers = 0;
600
modifiers |= Modifiers.Public;
602
else if(mb.IsPrivate)
604
modifiers |= Modifiers.Private;
606
else if(mb.IsFamily || mb.IsFamilyOrAssembly)
608
modifiers |= Modifiers.Protected;
610
else if(assemblyIsPrivate)
612
modifiers |= Modifiers.Private;
614
// NOTE Java doesn't support non-virtual methods, but we set the Final modifier for
615
// non-virtual methods to approximate the semantics
616
if((mb.IsFinal || (!mb.IsVirtual && ((modifiers & Modifiers.Private) == 0))) && !mb.IsStatic && !mb.IsConstructor)
618
modifiers |= Modifiers.Final;
622
modifiers |= Modifiers.Abstract;
626
// Some .NET interfaces (like System._AppDomain) have synchronized methods,
627
// Java doesn't allow synchronized on an abstract methods, so we ignore it for
629
if((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0)
631
modifiers |= Modifiers.Synchronized;
636
modifiers |= Modifiers.Static;
638
if((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
640
modifiers |= Modifiers.Native;
642
ParameterInfo[] parameters = mb.GetParameters();
643
if(parameters.Length > 0 && parameters[parameters.Length - 1].IsDefined(JVM.Import(typeof(ParamArrayAttribute)), false))
645
modifiers |= Modifiers.VarArgs;
647
return new ExModifiers(modifiers, false);
650
internal static ExModifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate)
652
ModifiersAttribute attr = GetModifiersAttribute(fi);
655
return new ExModifiers(attr.Modifiers, attr.IsInternal);
657
Modifiers modifiers = 0;
660
modifiers |= Modifiers.Public;
662
else if(fi.IsPrivate)
664
modifiers |= Modifiers.Private;
666
else if(fi.IsFamily || fi.IsFamilyOrAssembly)
668
modifiers |= Modifiers.Protected;
670
else if(assemblyIsPrivate)
672
modifiers |= Modifiers.Private;
674
if(fi.IsInitOnly || fi.IsLiteral)
676
modifiers |= Modifiers.Final;
678
if(fi.IsNotSerialized)
680
modifiers |= Modifiers.Transient;
684
modifiers |= Modifiers.Static;
686
if(Array.IndexOf(fi.GetRequiredCustomModifiers(), Types.IsVolatile) != -1)
688
modifiers |= Modifiers.Volatile;
690
return new ExModifiers(modifiers, false);
694
internal static void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal)
696
CustomAttributeBuilder customAttributeBuilder;
699
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
703
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
705
mb.SetCustomAttribute(customAttributeBuilder);
708
internal static void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal)
710
CustomAttributeBuilder customAttributeBuilder;
713
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
717
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
719
fb.SetCustomAttribute(customAttributeBuilder);
722
internal static void SetModifiers(PropertyBuilder pb, Modifiers modifiers, bool isInternal)
724
CustomAttributeBuilder customAttributeBuilder;
727
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
731
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
733
pb.SetCustomAttribute(customAttributeBuilder);
736
internal static void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal)
738
CustomAttributeBuilder customAttributeBuilder;
741
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
745
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
747
tb.SetCustomAttribute(customAttributeBuilder);
750
internal static void SetNameSig(MethodBuilder mb, string name, string sig)
752
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofNameSigAttribute.GetConstructor(new Type[] { Types.String, Types.String }), new object[] { name, sig });
753
mb.SetCustomAttribute(customAttributeBuilder);
756
internal static byte[] FreezeDryType(Type type)
758
System.IO.MemoryStream mem = new System.IO.MemoryStream();
759
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(mem, System.Text.UTF8Encoding.UTF8);
761
bw.Write(type.FullName);
763
return mem.ToArray();
766
internal static void SetInnerClass(TypeBuilder typeBuilder, string innerClass, Modifiers modifiers)
768
Type[] argTypes = new Type[] { Types.String, typeofModifiers };
769
object[] args = new object[] { innerClass, modifiers };
770
ConstructorInfo ci = typeofInnerClassAttribute.GetConstructor(argTypes);
771
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(ci, args);
772
typeBuilder.SetCustomAttribute(customAttributeBuilder);
775
internal static void SetSourceFile(TypeBuilder typeBuilder, string filename)
777
if(sourceFileAttribute == null)
779
sourceFileAttribute = typeofSourceFileAttribute.GetConstructor(new Type[] { Types.String });
781
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename }));
784
internal static void SetSourceFile(ModuleBuilder moduleBuilder, string filename)
786
if(sourceFileAttribute == null)
788
sourceFileAttribute = typeofSourceFileAttribute.GetConstructor(new Type[] { Types.String });
790
moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename }));
793
internal static void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer)
797
if(writer.Count == 1)
799
if(lineNumberTableAttribute2 == null)
801
lineNumberTableAttribute2 = typeofLineNumberTableAttribute.GetConstructor(new Type[] { Types.UInt16 });
803
con = lineNumberTableAttribute2;
804
arg = (ushort)writer.LineNo;
808
if(lineNumberTableAttribute1 == null)
810
lineNumberTableAttribute1 = typeofLineNumberTableAttribute.GetConstructor(new Type[] { JVM.Import(typeof(byte[])) });
812
con = lineNumberTableAttribute1;
813
arg = writer.ToArray();
815
mb.SetCustomAttribute(new CustomAttributeBuilder(con, new object[] { arg }));
818
internal static void SetEnclosingMethodAttribute(TypeBuilder tb, string className, string methodName, string methodSig)
820
if(enclosingMethodAttribute == null)
822
enclosingMethodAttribute = typeofEnclosingMethodAttribute.GetConstructor(new Type[] { Types.String, Types.String, Types.String });
824
tb.SetCustomAttribute(new CustomAttributeBuilder(enclosingMethodAttribute, new object[] { className, methodName, methodSig }));
827
internal static void SetSignatureAttribute(TypeBuilder tb, string signature)
829
if(signatureAttribute == null)
831
signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
833
tb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
836
internal static void SetSignatureAttribute(FieldBuilder fb, string signature)
838
if(signatureAttribute == null)
840
signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
842
fb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
845
internal static void SetSignatureAttribute(MethodBuilder mb, string signature)
847
if(signatureAttribute == null)
849
signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
851
mb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
854
internal static void SetParamArrayAttribute(ParameterBuilder pb)
856
if(paramArrayAttribute == null)
858
paramArrayAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ParamArrayAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
860
pb.SetCustomAttribute(paramArrayAttribute);
862
#endif // STATIC_COMPILER
864
internal static NameSigAttribute GetNameSig(MemberInfo member)
866
#if !STATIC_COMPILER && !STUB_GENERATOR
867
object[] attr = member.GetCustomAttributes(typeof(NameSigAttribute), false);
868
return attr.Length == 1 ? (NameSigAttribute)attr[0] : null;
870
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, typeofNameSigAttribute, false))
872
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
873
return new NameSigAttribute((string)args[0].Value, (string)args[1].Value);
879
internal static T[] DecodeArray<T>(CustomAttributeTypedArgument arg)
881
IList<CustomAttributeTypedArgument> elems = (IList<CustomAttributeTypedArgument>)arg.Value;
882
T[] arr = new T[elems.Count];
883
for(int i = 0; i < arr.Length; i++)
885
arr[i] = (T)elems[i].Value;
890
internal static ImplementsAttribute GetImplements(Type type)
892
#if !STATIC_COMPILER && !STUB_GENERATOR
893
object[] attribs = type.GetCustomAttributes(typeof(ImplementsAttribute), false);
894
return attribs.Length == 1 ? (ImplementsAttribute)attribs[0] : null;
896
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofImplementsAttribute, false))
898
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
899
return new ImplementsAttribute(DecodeArray<string>(args[0]));
905
internal static ThrowsAttribute GetThrows(MethodBase mb)
907
#if !STATIC_COMPILER && !STUB_GENERATOR
908
object[] attribs = mb.GetCustomAttributes(typeof(ThrowsAttribute), false);
909
return attribs.Length == 1 ? (ThrowsAttribute)attribs[0] : null;
911
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(mb, typeofThrowsAttribute, false))
913
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
914
if (args[0].ArgumentType == Types.String.MakeArrayType())
916
return new ThrowsAttribute(DecodeArray<string>(args[0]));
918
else if (args[0].ArgumentType == Types.Type.MakeArrayType())
920
return new ThrowsAttribute(DecodeArray<Type>(args[0]));
924
return new ThrowsAttribute((Type)args[0].Value);
931
internal static string[] GetNonNestedInnerClasses(Type t)
933
#if !STATIC_COMPILER && !STUB_GENERATOR
934
object[] attribs = t.GetCustomAttributes(typeof(NonNestedInnerClassAttribute), false);
935
string[] classes = new string[attribs.Length];
936
for (int i = 0; i < attribs.Length; i++)
938
classes[i] = ((NonNestedInnerClassAttribute)attribs[i]).InnerClassName;
942
List<string> list = new List<string>();
943
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(t, typeofNonNestedInnerClassAttribute, false))
945
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
946
list.Add((string)args[0].Value);
948
return list.ToArray();
952
internal static string GetNonNestedOuterClasses(Type t)
954
#if !STATIC_COMPILER && !STUB_GENERATOR
955
object[] attribs = t.GetCustomAttributes(typeof(NonNestedOuterClassAttribute), false);
956
return attribs.Length == 1 ? ((NonNestedOuterClassAttribute)attribs[0]).OuterClassName : null;
958
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(t, typeofNonNestedOuterClassAttribute, false))
960
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
961
return (string)args[0].Value;
967
internal static SignatureAttribute GetSignature(MemberInfo member)
969
#if !STATIC_COMPILER && !STUB_GENERATOR
970
object[] attribs = member.GetCustomAttributes(typeof(SignatureAttribute), false);
971
return attribs.Length == 1 ? (SignatureAttribute)attribs[0] : null;
973
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, typeofSignatureAttribute, false))
975
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
976
return new SignatureAttribute((string)args[0].Value);
982
internal static InnerClassAttribute GetInnerClass(Type type)
984
#if !STATIC_COMPILER && !STUB_GENERATOR
985
object[] attribs = type.GetCustomAttributes(typeof(InnerClassAttribute), false);
986
return attribs.Length == 1 ? (InnerClassAttribute)attribs[0] : null;
988
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofInnerClassAttribute, false))
990
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
991
return new InnerClassAttribute((string)args[0].Value, (Modifiers)args[1].Value);
997
internal static RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(Type type)
999
#if !STATIC_COMPILER && !STUB_GENERATOR
1000
object[] attr = type.GetCustomAttributes(typeof(RemappedInterfaceMethodAttribute), false);
1001
RemappedInterfaceMethodAttribute[] attr1 = new RemappedInterfaceMethodAttribute[attr.Length];
1002
Array.Copy(attr, attr1, attr.Length);
1005
List<RemappedInterfaceMethodAttribute> attrs = new List<RemappedInterfaceMethodAttribute>();
1006
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofRemappedInterfaceMethodAttribute, false))
1008
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
1009
attrs.Add(new RemappedInterfaceMethodAttribute((string)args[0].Value, (string)args[1].Value, DecodeArray<string>(args[2])));
1011
return attrs.ToArray();
1015
internal static RemappedTypeAttribute GetRemappedType(Type type)
1017
#if !STATIC_COMPILER && !STUB_GENERATOR
1018
object[] attribs = type.GetCustomAttributes(typeof(RemappedTypeAttribute), false);
1019
return attribs.Length == 1 ? (RemappedTypeAttribute)attribs[0] : null;
1021
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofRemappedTypeAttribute, false))
1023
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
1024
return new RemappedTypeAttribute((Type)args[0].Value);
1030
internal static RemappedClassAttribute[] GetRemappedClasses(Assembly coreAssembly)
1032
#if !STATIC_COMPILER && !STUB_GENERATOR
1033
object[] attr = coreAssembly.GetCustomAttributes(typeof(RemappedClassAttribute), false);
1034
RemappedClassAttribute[] attr1 = new RemappedClassAttribute[attr.Length];
1035
Array.Copy(attr, attr1, attr.Length);
1038
List<RemappedClassAttribute> attrs = new List<RemappedClassAttribute>();
1039
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(coreAssembly, typeofRemappedClassAttribute, false))
1041
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
1042
attrs.Add(new RemappedClassAttribute((string)args[0].Value, (Type)args[1].Value));
1044
return attrs.ToArray();
1048
internal static string GetAnnotationAttributeType(Type type)
1050
#if !STATIC_COMPILER && !STUB_GENERATOR
1051
object[] attr = type.GetCustomAttributes(typeof(AnnotationAttributeAttribute), false);
1052
if(attr.Length == 1)
1054
return ((AnnotationAttributeAttribute)attr[0]).AttributeType;
1058
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofAnnotationAttributeAttribute, false))
1060
return (string)cad.ConstructorArguments[0].Value;
1066
internal static AssemblyName[] GetInternalsVisibleToAttributes(Assembly assembly)
1068
List<AssemblyName> list = new List<AssemblyName>();
1069
foreach(CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(assembly))
1071
if(cad.Constructor.DeclaringType == JVM.Import(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute)))
1075
list.Add(new AssemblyName((string)cad.ConstructorArguments[0].Value));
1079
// HACK since there is no list of exception that the AssemblyName constructor can throw, we simply catch all
1083
return list.ToArray();
1086
internal static bool IsJavaModule(Module mod)
1088
return mod.IsDefined(typeofJavaModuleAttribute, false);
1091
internal static object[] GetJavaModuleAttributes(Module mod)
1093
#if !STATIC_COMPILER && !STUB_GENERATOR
1094
return mod.GetCustomAttributes(typeofJavaModuleAttribute, false);
1096
List<JavaModuleAttribute> attrs = new List<JavaModuleAttribute>();
1097
foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(mod, typeofJavaModuleAttribute, false))
1099
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
1102
attrs.Add(new JavaModuleAttribute());
1106
attrs.Add(new JavaModuleAttribute(DecodeArray<string>(args[0])));
1109
return attrs.ToArray();
1113
internal static bool IsNoPackagePrefix(Type type)
1115
return type.IsDefined(typeofNoPackagePrefixAttribute, false) || type.Assembly.IsDefined(typeofNoPackagePrefixAttribute, false);
1118
internal static EnclosingMethodAttribute GetEnclosingMethodAttribute(Type type)
1120
#if !STATIC_COMPILER && !STUB_GENERATOR
1121
object[] attr = type.GetCustomAttributes(typeof(EnclosingMethodAttribute), false);
1122
if (attr.Length == 1)
1124
return (EnclosingMethodAttribute)attr[0];
1128
foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofEnclosingMethodAttribute, false))
1130
return new EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value);
1137
internal static void SetRemappedClass(AssemblyBuilder assemblyBuilder, string name, Type shadowType)
1139
ConstructorInfo remappedClassAttribute = typeofRemappedClassAttribute.GetConstructor(new Type[] { Types.String, Types.Type });
1140
assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedClassAttribute, new object[] { name, shadowType }));
1143
internal static void SetRemappedType(TypeBuilder typeBuilder, Type shadowType)
1145
ConstructorInfo remappedTypeAttribute = typeofRemappedTypeAttribute.GetConstructor(new Type[] { Types.Type });
1146
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedTypeAttribute, new object[] { shadowType }));
1149
internal static void SetRemappedInterfaceMethod(TypeBuilder typeBuilder, string name, string mappedTo, string[] throws)
1151
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofRemappedInterfaceMethodAttribute.GetConstructor(new Type[] { Types.String, Types.String, Types.String.MakeArrayType() }), new object[] { name, mappedTo, throws });
1152
typeBuilder.SetCustomAttribute(cab);
1155
internal static void SetExceptionIsUnsafeForMapping(TypeBuilder typeBuilder)
1157
CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofExceptionIsUnsafeForMappingAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
1158
typeBuilder.SetCustomAttribute(cab);
1160
#endif // STATIC_COMPILER
1162
internal static void SetRuntimeCompatibilityAttribute(AssemblyBuilder assemblyBuilder)
1164
Type runtimeCompatibilityAttribute = JVM.Import(typeof(System.Runtime.CompilerServices.RuntimeCompatibilityAttribute));
1165
assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(
1166
runtimeCompatibilityAttribute.GetConstructor(Type.EmptyTypes), new object[0],
1167
new PropertyInfo[] { runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows") }, new object[] { true },
1168
new FieldInfo[0], new object[0]));
1172
static class EnumHelper
1174
internal static Type GetUnderlyingType(Type enumType)
1176
#if STATIC_COMPILER || STUB_GENERATOR
1177
return enumType.GetEnumUnderlyingType();
1179
return Enum.GetUnderlyingType(enumType);
1184
internal static object Parse(Type type, string value)
1186
object retval = null;
1187
foreach (string str in value.Split(','))
1189
FieldInfo field = type.GetField(str.Trim(), BindingFlags.Public | BindingFlags.Static);
1192
throw new InvalidOperationException("Enum value '" + str + "' not found in " + type.FullName);
1196
retval = field.GetRawConstantValue();
1200
retval = OrBoxedIntegrals(retval, field.GetRawConstantValue());
1207
// note that we only support the integer types that C# supports
1208
// (the CLI also supports bool, char, IntPtr & UIntPtr)
1209
internal static object OrBoxedIntegrals(object v1, object v2)
1211
Debug.Assert(v1.GetType() == v2.GetType());
1214
ulong l1 = (ulong)v1;
1215
ulong l2 = (ulong)v2;
1220
long v = ((IConvertible)v1).ToInt64(null) | ((IConvertible)v2).ToInt64(null);
1221
switch (Type.GetTypeCode(JVM.Import(v1.GetType())))
1223
case TypeCode.SByte:
1227
case TypeCode.Int16:
1229
case TypeCode.UInt16:
1231
case TypeCode.Int32:
1233
case TypeCode.UInt32:
1235
case TypeCode.Int64:
1238
throw new InvalidOperationException();
1243
// this method can be used to convert an enum value or its underlying value to a Java primitive
1244
internal static object GetPrimitiveValue(Type underlyingType, object obj)
1246
// Note that this method doesn't trust that obj is of the correct type,
1247
// because it turns out there exist assemblies (e.g. gtk-sharp.dll) that
1248
// have incorrectly typed enum constant values (e.g. int32 instead of uint32).
1250
if (obj is ulong || (obj is Enum && underlyingType == Types.UInt64))
1252
value = unchecked((long)((IConvertible)obj).ToUInt64(null));
1256
value = ((IConvertible)obj).ToInt64(null);
1258
if (underlyingType == Types.SByte || underlyingType == Types.Byte)
1260
return unchecked((byte)value);
1262
else if (underlyingType == Types.Int16 || underlyingType == Types.UInt16)
1264
return unchecked((short)value);
1266
else if (underlyingType == Types.Int32 || underlyingType == Types.UInt32)
1268
return unchecked((int)value);
1270
else if (underlyingType == Types.Int64 || underlyingType == Types.UInt64)
1276
throw new InvalidOperationException();
1281
static class TypeNameUtil
1283
// note that MangleNestedTypeName() assumes that there are less than 16 special characters
1284
private const string specialCharactersString = "\\+,[]*&\u0000";
1286
internal static string ReplaceIllegalCharacters(string name)
1288
// only the NUL character is illegal in CLR type names, so we replace it with a space
1289
return name.Replace('\u0000', ' ');
1292
internal static string Unescape(string name)
1294
int pos = name.IndexOf('\\');
1299
System.Text.StringBuilder sb = new System.Text.StringBuilder(name.Length);
1300
sb.Append(name, 0, pos);
1301
for (int i = pos; i < name.Length; i++)
1310
return sb.ToString();
1313
internal static string MangleNestedTypeName(string name)
1315
System.Text.StringBuilder sb = new System.Text.StringBuilder();
1316
foreach (char c in name)
1318
int index = specialCharactersString.IndexOf(c);
1327
else if (index == -1)
1337
sb.Append('^').AppendFormat("{0:X1}", index);
1340
return sb.ToString();
1343
internal static string UnmangleNestedTypeName(string name)
1345
System.Text.StringBuilder sb = new System.Text.StringBuilder();
1346
for (int i = 0; i < name.Length; i++)
1349
int index = specialCharactersString.IndexOf(c);
1367
sb.Append(specialCharactersString[c - '0']);
1375
return sb.ToString();
1379
abstract class Annotation
1381
// NOTE this method returns null if the type could not be found
1382
// or if the type is not a Custom Attribute and we're not in the static compiler
1383
internal static Annotation Load(ClassLoaderWrapper loader, object[] def)
1385
Debug.Assert(def[0].Equals(AnnotationDefaultAttribute.TAG_ANNOTATION));
1386
string annotationClass = (string)def[1];
1387
#if !STATIC_COMPILER
1388
if(!annotationClass.EndsWith("$Annotation;")
1389
&& !annotationClass.EndsWith("$Annotation$__ReturnValue;")
1390
&& !annotationClass.EndsWith("$Annotation$__Multiple;"))
1392
// we don't want to try to load an annotation in dynamic mode,
1393
// unless it is a .NET custom attribute (which can affect runtime behavior)
1399
TypeWrapper annot = loader.RetTypeWrapperFromSig(annotationClass.Replace('/', '.'));
1400
return annot.Annotation;
1403
catch(ClassNotFoundException x)
1405
loader.IssueMessage(Message.ClassNotFound, x.Message);
1409
catch (RetargetableJavaException)
1411
Tracer.Warning(Tracer.Compiler, "Unable to load annotation class {0}", annotationClass);
1416
private static object LookupEnumValue(Type enumType, string value)
1418
FieldInfo field = enumType.GetField(value, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
1421
return field.GetRawConstantValue();
1423
// both __unspecified and missing values end up here
1424
return EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(enumType), 0);
1427
protected static object ConvertValue(ClassLoaderWrapper loader, Type targetType, object obj)
1429
if(targetType.IsEnum)
1431
// TODO check the obj descriptor matches the type we expect
1432
if(((object[])obj)[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY))
1434
object[] arr = (object[])obj;
1435
object value = null;
1436
for(int i = 1; i < arr.Length; i++)
1438
// TODO check the obj descriptor matches the type we expect
1439
string s = ((object[])arr[i])[2].ToString();
1440
object newval = LookupEnumValue(targetType, s);
1447
value = EnumHelper.OrBoxedIntegrals(value, newval);
1454
string s = ((object[])obj)[2].ToString();
1455
if(s == "__unspecified")
1457
// TODO we should probably return null and handle that
1459
return LookupEnumValue(targetType, s);
1462
else if(targetType == Types.Type)
1464
// TODO check the obj descriptor matches the type we expect
1465
return loader.FieldTypeWrapperFromSig(((string)((object[])obj)[1]).Replace('/', '.')).TypeAsTBD;
1467
else if(targetType.IsArray)
1469
// TODO check the obj descriptor matches the type we expect
1470
object[] arr = (object[])obj;
1471
Type elementType = targetType.GetElementType();
1472
object[] targetArray = new object[arr.Length - 1];
1473
for(int i = 1; i < arr.Length; i++)
1475
targetArray[i - 1] = ConvertValue(loader, elementType, arr[i]);
1485
#if !STATIC_COMPILER && !STUB_GENERATOR
1486
internal static bool MakeDeclSecurity(Type type, object annotation, out SecurityAction action, out PermissionSet permSet)
1488
ConstructorInfo ci = type.GetConstructor(new Type[] { typeof(SecurityAction) });
1491
// TODO should we support HostProtectionAttribute? (which has a no-arg constructor)
1492
// TODO issue message?
1497
SecurityAttribute attr = null;
1498
object[] arr = (object[])annotation;
1499
for (int i = 2; i < arr.Length; i += 2)
1501
string name = (string)arr[i];
1502
if (name == "value")
1504
attr = (SecurityAttribute)ci.Invoke(new object[] { ConvertValue(null, typeof(SecurityAction), arr[i + 1]) });
1509
// TODO issue message?
1514
for (int i = 2; i < arr.Length; i += 2)
1516
string name = (string)arr[i];
1517
if (name != "value")
1519
PropertyInfo pi = type.GetProperty(name);
1520
pi.SetValue(attr, ConvertValue(null, pi.PropertyType, arr[i + 1]), null);
1523
action = attr.Action;
1524
permSet = new PermissionSet(PermissionState.None);
1525
permSet.AddPermission(attr.CreatePermission());
1528
#endif // !STATIC_COMPILER && !STUB_GENERATOR
1530
internal static bool HasRetentionPolicyRuntime(object[] annotations)
1532
if(annotations != null)
1534
foreach(object[] def in annotations)
1536
if(def[1].Equals("Ljava/lang/annotation/Retention;"))
1538
for(int i = 2; i < def.Length; i += 2)
1540
if(def[i].Equals("value"))
1542
object[] val = def[i + 1] as object[];
1545
&& val[0].Equals(AnnotationDefaultAttribute.TAG_ENUM)
1546
&& val[1].Equals("Ljava/lang/annotation/RetentionPolicy;")
1547
&& val[2].Equals("RUNTIME"))
1559
protected static object QualifyClassNames(ClassLoaderWrapper loader, object annotation)
1562
object[] def = (object[])annotation;
1563
for(int i = 3; i < def.Length; i += 2)
1565
object[] val = def[i] as object[];
1568
object[] newval = ValueQualifyClassNames(loader, val);
1574
object[] newdef = new object[def.Length];
1575
Array.Copy(def, newdef, def.Length);
1585
private static object[] ValueQualifyClassNames(ClassLoaderWrapper loader, object[] val)
1587
if(val[0].Equals(AnnotationDefaultAttribute.TAG_ANNOTATION))
1589
return (object[])QualifyClassNames(loader, val);
1591
else if(val[0].Equals(AnnotationDefaultAttribute.TAG_CLASS))
1593
string sig = (string)val[1];
1594
if(sig.StartsWith("L"))
1596
TypeWrapper tw = loader.LoadClassByDottedNameFast(sig.Substring(1, sig.Length - 2).Replace('/', '.'));
1599
return new object[] { AnnotationDefaultAttribute.TAG_CLASS, "L" + tw.TypeAsBaseType.AssemblyQualifiedName.Replace('.', '/') + ";" };
1604
else if(val[0].Equals(AnnotationDefaultAttribute.TAG_ENUM))
1606
string sig = (string)val[1];
1607
TypeWrapper tw = loader.LoadClassByDottedNameFast(sig.Substring(1, sig.Length - 2).Replace('/', '.'));
1610
return new object[] { AnnotationDefaultAttribute.TAG_ENUM, "L" + tw.TypeAsBaseType.AssemblyQualifiedName.Replace('.', '/') + ";", val[2] };
1614
else if(val[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY))
1617
for(int i = 1; i < val.Length; i++)
1619
object[] nval = val[i] as object[];
1622
object newnval = ValueQualifyClassNames(loader, nval);
1628
object[] newval = new object[val.Length];
1629
Array.Copy(val, newval, val.Length);
1640
throw new InvalidOperationException();
1644
internal abstract void Apply(ClassLoaderWrapper loader, TypeBuilder tb, object annotation);
1645
internal abstract void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation);
1646
internal abstract void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation);
1647
internal abstract void Apply(ClassLoaderWrapper loader, ParameterBuilder pb, object annotation);
1648
internal abstract void Apply(ClassLoaderWrapper loader, AssemblyBuilder ab, object annotation);
1649
internal abstract void Apply(ClassLoaderWrapper loader, PropertyBuilder pb, object annotation);
1651
internal virtual void ApplyReturnValue(ClassLoaderWrapper loader, MethodBuilder mb, ref ParameterBuilder pb, object annotation)
1655
internal abstract bool IsCustomAttribute { get; }
1659
enum TypeFlags : ushort
1661
HasIncompleteInterfaceImplementation = 1,
1663
HasStaticInitializer = 4,
1665
ClassFormatError = 16,
1666
HasUnsupportedAbstractMethods = 32,
1669
static class NamePrefix
1671
internal const string Type2AccessStubBackingField = "__<>";
1672
internal const string AccessStub = "<accessstub>";
1673
internal const string NonVirtual = "<nonvirtual>";
1674
internal const string Bridge = "<bridge>";
1677
internal abstract class TypeWrapper
1679
private readonly string name; // java name (e.g. java.lang.Object)
1680
private readonly Modifiers modifiers;
1681
private TypeFlags flags;
1682
private MethodWrapper[] methods;
1683
private FieldWrapper[] fields;
1684
#if !STATIC_COMPILER && !STUB_GENERATOR
1685
private java.lang.Class classObject;
1687
internal static readonly TypeWrapper[] EmptyArray = new TypeWrapper[0];
1688
internal const Modifiers UnloadableModifiersHack = Modifiers.Final | Modifiers.Interface | Modifiers.Private;
1689
internal const Modifiers VerifierTypeModifiersHack = Modifiers.Final | Modifiers.Interface;
1691
internal TypeWrapper(Modifiers modifiers, string name)
1693
Profiler.Count("TypeWrapper");
1694
// class name should be dotted or null for primitives
1695
Debug.Assert(name == null || name.IndexOf('/') < 0);
1697
this.modifiers = modifiers;
1698
this.name = name == null ? null : String.Intern(name);
1702
internal void EmitClassLiteral(CodeEmitter ilgen)
1704
Debug.Assert(!this.IsPrimitive);
1706
Type type = GetClassLiteralType();
1708
// note that this has to be the same check as in LazyInitClass
1709
if (!this.IsFastClassLiteralSafe || IsForbiddenTypeParameterType(type))
1712
while (ReflectUtil.IsVector(type))
1715
type = type.GetElementType();
1719
ilgen.Emit(OpCodes.Ldtoken, type);
1720
Compiler.getClassFromTypeHandle.EmitCall(ilgen);
1724
ilgen.Emit(OpCodes.Ldtoken, type);
1725
ilgen.EmitLdc_I4(rank);
1726
Compiler.getClassFromTypeHandle2.EmitCall(ilgen);
1731
ilgen.Emit(OpCodes.Ldsfld, RuntimeHelperTypes.GetClassLiteralField(type));
1734
#endif // !STUB_GENERATOR
1736
private Type GetClassLiteralType()
1738
Debug.Assert(!this.IsPrimitive);
1740
TypeWrapper tw = this;
1741
if (tw.IsGhostArray)
1743
int rank = tw.ArrayRank;
1746
tw = tw.ElementTypeWrapper;
1748
return ArrayTypeWrapper.MakeArrayType(tw.TypeAsTBD, rank);
1752
return tw.IsRemapped ? tw.TypeAsBaseType : tw.TypeAsTBD;
1756
private static bool IsForbiddenTypeParameterType(Type type)
1758
// these are the types that may not be used as a type argument when instantiating a generic type
1759
return type == Types.Void
1760
|| type == JVM.Import(typeof(ArgIterator))
1761
|| type == JVM.Import(typeof(RuntimeArgumentHandle))
1762
|| type == JVM.Import(typeof(TypedReference))
1763
|| type.ContainsGenericParameters
1767
internal virtual bool IsFastClassLiteralSafe
1769
get { return false; }
1772
#if !STATIC_COMPILER && !STUB_GENERATOR
1773
internal void SetClassObject(java.lang.Class classObject)
1775
this.classObject = classObject;
1778
internal java.lang.Class ClassObject
1782
Debug.Assert(!IsUnloadable && !IsVerifierType);
1783
if (classObject == null)
1792
private java.lang.Class GetPrimitiveClass()
1794
if (this == PrimitiveTypeWrapper.BYTE)
1796
return java.lang.Byte.TYPE;
1798
else if (this == PrimitiveTypeWrapper.CHAR)
1800
return java.lang.Character.TYPE;
1802
else if (this == PrimitiveTypeWrapper.DOUBLE)
1804
return java.lang.Double.TYPE;
1806
else if (this == PrimitiveTypeWrapper.FLOAT)
1808
return java.lang.Float.TYPE;
1810
else if (this == PrimitiveTypeWrapper.INT)
1812
return java.lang.Integer.TYPE;
1814
else if (this == PrimitiveTypeWrapper.LONG)
1816
return java.lang.Long.TYPE;
1818
else if (this == PrimitiveTypeWrapper.SHORT)
1820
return java.lang.Short.TYPE;
1822
else if (this == PrimitiveTypeWrapper.BOOLEAN)
1824
return java.lang.Boolean.TYPE;
1826
else if (this == PrimitiveTypeWrapper.VOID)
1828
return java.lang.Void.TYPE;
1832
throw new InvalidOperationException();
1837
private void LazyInitClass()
1841
if (classObject == null)
1843
// DynamicTypeWrapper should haved already had SetClassObject explicitly
1844
Debug.Assert(!(this is DynamicTypeWrapper));
1846
java.lang.Class clazz;
1847
// note that this has to be the same check as in EmitClassLiteral
1848
if (!this.IsFastClassLiteralSafe)
1850
if (this.IsPrimitive)
1852
clazz = GetPrimitiveClass();
1856
clazz = new java.lang.Class(null);
1861
Type type = GetClassLiteralType();
1862
if (IsForbiddenTypeParameterType(type))
1864
clazz = new java.lang.Class(type);
1868
clazz = (java.lang.Class)typeof(ikvm.@internal.ClassLiteral<>).MakeGenericType(type).GetField("Value").GetValue(null);
1872
SetTypeWrapperHack(clazz, this);
1874
clazz.typeWrapper = this;
1876
// MONOBUG Interlocked.Exchange is broken on Mono, so we use CompareExchange
1877
System.Threading.Interlocked.CompareExchange(ref classObject, clazz, null);
1884
// MONOBUG this method is to work around an mcs bug
1885
internal static void SetTypeWrapperHack(object clazz, TypeWrapper type)
1888
typeof(java.lang.Class).GetField("typeWrapper", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(clazz, type);
1894
private static void ResolvePrimitiveTypeWrapperClasses()
1896
// note that we're evaluating all ClassObject properties for the side effect
1897
// (to initialize and associate the ClassObject with the TypeWrapper)
1898
if (PrimitiveTypeWrapper.BYTE.ClassObject == null
1899
|| PrimitiveTypeWrapper.CHAR.ClassObject == null
1900
|| PrimitiveTypeWrapper.DOUBLE.ClassObject == null
1901
|| PrimitiveTypeWrapper.FLOAT.ClassObject == null
1902
|| PrimitiveTypeWrapper.INT.ClassObject == null
1903
|| PrimitiveTypeWrapper.LONG.ClassObject == null
1904
|| PrimitiveTypeWrapper.SHORT.ClassObject == null
1905
|| PrimitiveTypeWrapper.BOOLEAN.ClassObject == null
1906
|| PrimitiveTypeWrapper.VOID.ClassObject == null)
1908
throw new InvalidOperationException();
1913
internal static TypeWrapper FromClass(java.lang.Class clazz)
1918
// MONOBUG redundant cast to workaround mcs bug
1919
TypeWrapper tw = (TypeWrapper)(object)clazz.typeWrapper;
1922
Type type = clazz.type;
1925
ResolvePrimitiveTypeWrapperClasses();
1926
return FromClass(clazz);
1928
if (type == typeof(void) || type.IsPrimitive || ClassLoaderWrapper.IsRemappedType(type))
1930
tw = DotNetTypeWrapper.GetWrapperFromDotNetType(type);
1934
tw = ClassLoaderWrapper.GetWrapperFromType(type);
1937
SetTypeWrapperHack(clazz, tw);
1939
clazz.typeWrapper = tw;
1945
#endif // !STATIC_COMPILER && !STUB_GENERATOR
1947
public override string ToString()
1949
return GetType().Name + "[" + name + "]";
1952
// For UnloadableTypeWrapper it tries to load the type through the specified loader
1953
// and if that fails it throw a NoClassDefFoundError (not a java.lang.NoClassDefFoundError),
1954
// for all other types this is a no-op.
1955
internal virtual TypeWrapper EnsureLoadable(ClassLoaderWrapper loader)
1960
internal bool HasIncompleteInterfaceImplementation
1964
TypeWrapper baseWrapper = this.BaseTypeWrapper;
1965
return (flags & TypeFlags.HasIncompleteInterfaceImplementation) != 0 || (baseWrapper != null && baseWrapper.HasIncompleteInterfaceImplementation);
1969
// TODO do we need locking here?
1972
flags |= TypeFlags.HasIncompleteInterfaceImplementation;
1976
flags &= ~TypeFlags.HasIncompleteInterfaceImplementation;
1981
internal bool HasUnsupportedAbstractMethods
1985
foreach(TypeWrapper iface in this.Interfaces)
1987
if(iface.HasUnsupportedAbstractMethods)
1992
TypeWrapper baseWrapper = this.BaseTypeWrapper;
1993
return (flags & TypeFlags.HasUnsupportedAbstractMethods) != 0 || (baseWrapper != null && baseWrapper.HasUnsupportedAbstractMethods);
1997
// TODO do we need locking here?
2000
flags |= TypeFlags.HasUnsupportedAbstractMethods;
2004
flags &= ~TypeFlags.HasUnsupportedAbstractMethods;
2009
internal virtual bool HasStaticInitializer
2013
return (flags & TypeFlags.HasStaticInitializer) != 0;
2017
// TODO do we need locking here?
2020
flags |= TypeFlags.HasStaticInitializer;
2024
flags &= ~TypeFlags.HasStaticInitializer;
2029
internal bool HasVerifyError
2033
return (flags & TypeFlags.VerifyError) != 0;
2037
// TODO do we need locking here?
2040
flags |= TypeFlags.VerifyError;
2044
flags &= ~TypeFlags.VerifyError;
2049
internal bool HasClassFormatError
2053
return (flags & TypeFlags.ClassFormatError) != 0;
2057
// TODO do we need locking here?
2060
flags |= TypeFlags.ClassFormatError;
2064
flags &= ~TypeFlags.ClassFormatError;
2069
internal virtual bool IsFakeTypeContainer
2077
internal virtual bool IsFakeNestedType
2085
// a ghost is an interface that appears to be implemented by a .NET type
2086
// (e.g. System.String (aka java.lang.String) appears to implement java.lang.CharSequence,
2087
// so java.lang.CharSequence is a ghost)
2088
internal virtual bool IsGhost
2096
// is this an array type of which the ultimate element type is a ghost?
2097
internal bool IsGhostArray
2101
return !IsUnloadable && IsArray && (ElementTypeWrapper.IsGhost || ElementTypeWrapper.IsGhostArray);
2105
internal virtual FieldInfo GhostRefField
2109
throw new InvalidOperationException();
2113
internal virtual bool IsRemapped
2121
internal bool IsArray
2125
return name != null && name[0] == '[';
2129
// NOTE for non-array types this returns 0
2130
internal int ArrayRank
2137
while(name[i] == '[')
2146
internal virtual TypeWrapper GetUltimateElementTypeWrapper()
2148
throw new InvalidOperationException();
2151
internal bool IsNonPrimitiveValueType
2155
return this != VerifierTypeWrapper.Null && !IsPrimitive && !IsGhost && TypeAsTBD.IsValueType;
2159
internal bool IsPrimitive
2163
return name == null;
2167
internal bool IsWidePrimitive
2171
return this == PrimitiveTypeWrapper.LONG || this == PrimitiveTypeWrapper.DOUBLE;
2175
internal bool IsIntOnStackPrimitive
2179
return name == null &&
2180
(this == PrimitiveTypeWrapper.BOOLEAN ||
2181
this == PrimitiveTypeWrapper.BYTE ||
2182
this == PrimitiveTypeWrapper.CHAR ||
2183
this == PrimitiveTypeWrapper.SHORT ||
2184
this == PrimitiveTypeWrapper.INT);
2188
private static bool IsJavaPrimitive(Type type)
2190
return type == PrimitiveTypeWrapper.BOOLEAN.TypeAsTBD
2191
|| type == PrimitiveTypeWrapper.BYTE.TypeAsTBD
2192
|| type == PrimitiveTypeWrapper.CHAR.TypeAsTBD
2193
|| type == PrimitiveTypeWrapper.DOUBLE.TypeAsTBD
2194
|| type == PrimitiveTypeWrapper.FLOAT.TypeAsTBD
2195
|| type == PrimitiveTypeWrapper.INT.TypeAsTBD
2196
|| type == PrimitiveTypeWrapper.LONG.TypeAsTBD
2197
|| type == PrimitiveTypeWrapper.SHORT.TypeAsTBD
2198
|| type == PrimitiveTypeWrapper.VOID.TypeAsTBD;
2201
internal bool IsBoxedPrimitive
2205
return !IsPrimitive && IsJavaPrimitive(TypeAsSignatureType);
2209
internal bool IsErasedOrBoxedPrimitiveOrRemapped
2213
bool erased = IsUnloadable || IsGhostArray;
2214
return erased || IsBoxedPrimitive || (IsRemapped && this is DotNetTypeWrapper);
2218
internal bool IsUnloadable
2222
// NOTE we abuse modifiers to note unloadable classes
2223
return modifiers == UnloadableModifiersHack;
2227
internal bool IsVerifierType
2231
// NOTE we abuse modifiers to note verifier types
2232
return modifiers == VerifierTypeModifiersHack;
2236
internal virtual bool IsMapUnsafeException
2244
internal Modifiers Modifiers
2252
// since for inner classes, the modifiers returned by Class.getModifiers are different from the actual
2253
// modifiers (as used by the VM access control mechanism), we have this additional property
2254
internal virtual Modifiers ReflectiveModifiers
2262
internal bool IsInternal
2266
return (flags & TypeFlags.InternalAccess) != 0;
2270
// TODO do we need locking here?
2273
flags |= TypeFlags.InternalAccess;
2277
flags &= ~TypeFlags.InternalAccess;
2282
internal bool IsPublic
2286
return (modifiers & Modifiers.Public) != 0;
2290
internal bool IsAbstract
2294
// interfaces don't need to marked abstract explicitly (and javac 1.1 didn't do it)
2295
return (modifiers & (Modifiers.Abstract | Modifiers.Interface)) != 0;
2299
internal bool IsFinal
2303
return (modifiers & Modifiers.Final) != 0;
2307
internal bool IsInterface
2311
Debug.Assert(!IsUnloadable && !IsVerifierType);
2312
return (modifiers & Modifiers.Interface) != 0;
2316
// this exists because interfaces and arrays of interfaces are treated specially
2317
// by the verifier, interfaces don't have a common base (other than java.lang.Object)
2318
// so any object reference or object array reference can be used where an interface
2319
// or interface array reference is expected (the compiler will insert the required casts).
2320
internal bool IsInterfaceOrInterfaceArray
2324
TypeWrapper tw = this;
2327
tw = tw.ElementTypeWrapper;
2329
return tw.IsInterface;
2333
internal abstract ClassLoaderWrapper GetClassLoader();
2335
internal FieldWrapper GetFieldWrapper(string fieldName, string fieldSig)
2337
foreach(FieldWrapper fw in GetFields())
2339
if(fw.Name == fieldName && fw.Signature == fieldSig)
2344
foreach(TypeWrapper iface in this.Interfaces)
2346
FieldWrapper fw = iface.GetFieldWrapper(fieldName, fieldSig);
2352
TypeWrapper baseWrapper = this.BaseTypeWrapper;
2353
if(baseWrapper != null)
2355
return baseWrapper.GetFieldWrapper(fieldName, fieldSig);
2360
protected virtual void LazyPublishMembers()
2364
methods = MethodWrapper.EmptyArray;
2368
fields = FieldWrapper.EmptyArray;
2372
protected virtual void LazyPublishMethods()
2374
LazyPublishMembers();
2377
protected virtual void LazyPublishFields()
2379
LazyPublishMembers();
2382
internal MethodWrapper[] GetMethods()
2390
LazyPublishMethods();
2397
internal FieldWrapper[] GetFields()
2405
LazyPublishFields();
2412
internal MethodWrapper GetMethodWrapper(string name, string sig, bool inherit)
2414
// We need to get the methods before calling String.IsInterned, because getting them might cause the strings to be interned
2415
MethodWrapper[] methods = GetMethods();
2416
// MemberWrapper interns the name and sig so we can use ref equality
2417
// profiling has shown this to be more efficient
2418
string _name = String.IsInterned(name);
2419
string _sig = String.IsInterned(sig);
2420
foreach(MethodWrapper mw in methods)
2422
// NOTE we can use ref equality, because names and signatures are
2423
// always interned by MemberWrapper
2424
if(ReferenceEquals(mw.Name, _name) && ReferenceEquals(mw.Signature, _sig))
2429
TypeWrapper baseWrapper = this.BaseTypeWrapper;
2430
if(inherit && baseWrapper != null)
2432
return baseWrapper.GetMethodWrapper(name, sig, inherit);
2437
internal void SetMethods(MethodWrapper[] methods)
2439
Debug.Assert(methods != null);
2440
this.methods = methods;
2443
internal void SetFields(FieldWrapper[] fields)
2445
Debug.Assert(fields != null);
2446
this.fields = fields;
2449
internal string Name
2457
// the name of the type as it appears in a Java signature string (e.g. "Ljava.lang.Object;" or "I")
2458
internal virtual string SigName
2462
return "L" + this.Name + ";";
2466
// returns true iff wrapper is allowed to access us
2467
internal bool IsAccessibleFrom(TypeWrapper wrapper)
2470
|| (IsInternal && InternalsVisibleTo(wrapper))
2471
|| IsPackageAccessibleFrom(wrapper);
2474
internal bool InternalsVisibleTo(TypeWrapper wrapper)
2476
return GetClassLoader().InternalsVisibleToImpl(this, wrapper);
2479
internal bool IsPackageAccessibleFrom(TypeWrapper wrapper)
2481
if (MatchingPackageNames(name, wrapper.name))
2484
CompilerClassLoader ccl = GetClassLoader() as CompilerClassLoader;
2487
// this is a hack for multi target -sharedclassloader compilation
2488
// (during compilation we have multiple CompilerClassLoader instances to represent the single shared runtime class loader)
2489
return ccl.IsEquivalentTo(wrapper.GetClassLoader());
2492
return GetClassLoader() == wrapper.GetClassLoader();
2500
private static bool MatchingPackageNames(string name1, string name2)
2502
int index1 = name1.LastIndexOf('.');
2503
int index2 = name2.LastIndexOf('.');
2504
if (index1 == -1 && index2 == -1)
2508
// for array types we need to skip the brackets
2511
while (name1[skip1] == '[')
2515
while (name2[skip2] == '[')
2521
// skip over the L that follows the brackets
2526
// skip over the L that follows the brackets
2529
if ((index1 - skip1) != (index2 - skip2))
2533
return String.CompareOrdinal(name1, skip1, name2, skip2, index1 - skip1) == 0;
2536
internal abstract Type TypeAsTBD
2541
internal Type TypeAsSignatureType
2547
return Types.Object;
2551
return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
2557
internal virtual Type TypeAsBaseType
2565
internal Type TypeAsLocalOrStackType
2569
if(IsUnloadable || IsGhost)
2571
return Types.Object;
2573
if(IsNonPrimitiveValueType)
2575
// return either System.ValueType or System.Enum
2576
return TypeAsTBD.BaseType;
2580
return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
2586
/** <summary>Use this if the type is used as an array or array element</summary> */
2587
internal Type TypeAsArrayType
2591
if(IsUnloadable || IsGhost)
2593
return Types.Object;
2597
return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
2603
internal Type TypeAsExceptionType
2609
return Types.Exception;
2615
internal abstract TypeWrapper BaseTypeWrapper
2620
internal TypeWrapper ElementTypeWrapper
2624
Debug.Assert(!this.IsUnloadable);
2625
Debug.Assert(this == VerifierTypeWrapper.Null || this.IsArray);
2627
if(this == VerifierTypeWrapper.Null)
2629
return VerifierTypeWrapper.Null;
2632
// TODO consider caching the element type
2636
// NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load
2637
// (because the ultimate element type was already loaded when this type was created)
2638
return GetClassLoader().LoadClassByDottedNameFast(name.Substring(1));
2640
// NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load
2641
// (because the ultimate element type was already loaded when this type was created)
2642
return GetClassLoader().LoadClassByDottedNameFast(name.Substring(2, name.Length - 3));
2644
return PrimitiveTypeWrapper.BOOLEAN;
2646
return PrimitiveTypeWrapper.BYTE;
2648
return PrimitiveTypeWrapper.SHORT;
2650
return PrimitiveTypeWrapper.CHAR;
2652
return PrimitiveTypeWrapper.INT;
2654
return PrimitiveTypeWrapper.LONG;
2656
return PrimitiveTypeWrapper.FLOAT;
2658
return PrimitiveTypeWrapper.DOUBLE;
2660
throw new InvalidOperationException(name);
2665
internal TypeWrapper MakeArrayType(int rank)
2667
Debug.Assert(rank != 0);
2668
// NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load
2669
return GetClassLoader().LoadClassByDottedNameFast(new String('[', rank) + this.SigName);
2672
internal bool ImplementsInterface(TypeWrapper interfaceWrapper)
2674
TypeWrapper typeWrapper = this;
2675
while(typeWrapper != null)
2677
TypeWrapper[] interfaces = typeWrapper.Interfaces;
2678
for(int i = 0; i < interfaces.Length; i++)
2680
if(interfaces[i] == interfaceWrapper)
2684
if(interfaces[i].ImplementsInterface(interfaceWrapper))
2689
typeWrapper = typeWrapper.BaseTypeWrapper;
2694
internal bool IsSubTypeOf(TypeWrapper baseType)
2696
// make sure IsSubTypeOf isn't used on primitives
2697
Debug.Assert(!this.IsPrimitive);
2698
Debug.Assert(!baseType.IsPrimitive);
2699
// can't be used on Unloadable
2700
Debug.Assert(!this.IsUnloadable);
2701
Debug.Assert(!baseType.IsUnloadable);
2703
if(baseType.IsInterface)
2705
if(baseType == this)
2709
return ImplementsInterface(baseType);
2711
// NOTE this isn't just an optimization, it is also required when this is an interface
2712
if(baseType == CoreClasses.java.lang.Object.Wrapper)
2716
TypeWrapper subType = this;
2717
while(subType != baseType)
2719
subType = subType.BaseTypeWrapper;
2728
internal bool IsAssignableTo(TypeWrapper wrapper)
2734
if(this.IsPrimitive || wrapper.IsPrimitive)
2738
if(this == VerifierTypeWrapper.Null)
2742
if(wrapper.IsInterface)
2744
return ImplementsInterface(wrapper);
2746
int rank1 = this.ArrayRank;
2747
int rank2 = wrapper.ArrayRank;
2748
if(rank1 > 0 && rank2 > 0)
2752
TypeWrapper elem1 = this.ElementTypeWrapper;
2753
TypeWrapper elem2 = wrapper.ElementTypeWrapper;
2754
while(rank1 != 0 && rank2 != 0)
2756
elem1 = elem1.ElementTypeWrapper;
2757
elem2 = elem2.ElementTypeWrapper;
2761
if(elem1.IsPrimitive || elem2.IsPrimitive)
2765
return (!elem1.IsNonPrimitiveValueType && elem1.IsSubTypeOf(elem2)) || (rank1 == rank2 && elem2.IsGhost && elem1 == CoreClasses.java.lang.Object.Wrapper);
2767
return this.IsSubTypeOf(wrapper);
2770
#if !STATIC_COMPILER && !STUB_GENERATOR
2771
internal bool IsInstance(object obj)
2775
TypeWrapper thisWrapper = this;
2776
TypeWrapper objWrapper = IKVM.NativeCode.ikvm.runtime.Util.GetTypeWrapperFromObject(obj);
2777
return objWrapper.IsAssignableTo(thisWrapper);
2783
internal abstract TypeWrapper[] Interfaces
2788
// NOTE this property can only be called for finished types!
2789
internal abstract TypeWrapper[] InnerClasses
2794
// NOTE this property can only be called for finished types!
2795
internal abstract TypeWrapper DeclaringTypeWrapper
2800
internal abstract void Finish();
2802
#if !STATIC_COMPILER
2803
[Conditional("DEBUG")]
2804
internal static void AssertFinished(Type type)
2808
while(type.HasElementType)
2810
type = type.GetElementType();
2812
Debug.Assert(!(type is TypeBuilder));
2817
#if !STATIC_COMPILER && !STUB_GENERATOR
2818
internal void RunClassInit()
2820
Type t = IsRemapped ? TypeAsBaseType : TypeAsTBD;
2823
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);
2829
internal void EmitUnbox(CodeEmitter ilgen)
2831
Debug.Assert(this.IsNonPrimitiveValueType);
2833
ilgen.EmitUnboxSpecial(this.TypeAsTBD);
2836
internal void EmitBox(CodeEmitter ilgen)
2838
Debug.Assert(this.IsNonPrimitiveValueType);
2840
ilgen.Emit(OpCodes.Box, this.TypeAsTBD);
2843
internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen)
2848
else if(this == PrimitiveTypeWrapper.BYTE)
2850
ilgen.Emit(OpCodes.Conv_I1);
2852
else if(IsNonPrimitiveValueType)
2858
CodeEmitterLocal local = ilgen.DeclareLocal(TypeAsSignatureType);
2859
ilgen.Emit(OpCodes.Stloc, local);
2860
ilgen.Emit(OpCodes.Ldloca, local);
2861
ilgen.Emit(OpCodes.Ldfld, GhostRefField);
2865
// NOTE sourceType is optional and only used for interfaces,
2866
// it is *not* used to automatically downcast
2867
internal void EmitConvStackTypeToSignatureType(CodeEmitter ilgen, TypeWrapper sourceType)
2873
CodeEmitterLocal local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType);
2874
ilgen.Emit(OpCodes.Stloc, local1);
2875
CodeEmitterLocal local2 = ilgen.DeclareLocal(TypeAsSignatureType);
2876
ilgen.Emit(OpCodes.Ldloca, local2);
2877
ilgen.Emit(OpCodes.Ldloc, local1);
2878
ilgen.Emit(OpCodes.Stfld, GhostRefField);
2879
ilgen.Emit(OpCodes.Ldloca, local2);
2880
ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
2882
// because of the way interface merging works, any reference is valid
2883
// for any interface reference
2884
else if(IsInterfaceOrInterfaceArray && (sourceType == null || sourceType.IsUnloadable || !sourceType.IsAssignableTo(this)))
2886
ilgen.EmitAssertType(TypeAsTBD);
2887
Profiler.Count("InterfaceDownCast");
2889
else if(IsNonPrimitiveValueType)
2893
else if(sourceType != null && sourceType.IsUnloadable)
2895
ilgen.Emit(OpCodes.Castclass, TypeAsSignatureType);
2900
internal virtual void EmitCheckcast(TypeWrapper context, CodeEmitter ilgen)
2904
ilgen.Emit(OpCodes.Dup);
2905
// TODO make sure we get the right "Cast" method and cache it
2906
// NOTE for dynamic ghosts we don't end up here because AotTypeWrapper overrides this method,
2907
// so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here)
2908
ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod("Cast"));
2909
ilgen.Emit(OpCodes.Pop);
2911
else if(IsGhostArray)
2913
ilgen.Emit(OpCodes.Dup);
2914
// TODO make sure we get the right "CastArray" method and cache it
2915
// NOTE for dynamic ghosts we don't end up here because AotTypeWrapper overrides this method,
2916
// so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here)
2917
TypeWrapper tw = this;
2922
tw = tw.ElementTypeWrapper;
2924
ilgen.EmitLdc_I4(rank);
2925
ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray"));
2926
ilgen.Emit(OpCodes.Castclass, ArrayTypeWrapper.MakeArrayType(Types.Object, rank));
2930
ilgen.EmitCastclass(TypeAsTBD);
2934
internal virtual void EmitInstanceOf(TypeWrapper context, CodeEmitter ilgen)
2938
// TODO make sure we get the right "IsInstance" method and cache it
2939
// NOTE for dynamic ghosts we don't end up here because DynamicTypeWrapper overrides this method,
2940
// so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here)
2941
ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod("IsInstance"));
2943
else if(IsGhostArray)
2945
// TODO make sure we get the right "IsInstanceArray" method and cache it
2946
// NOTE for dynamic ghosts we don't end up here because DynamicTypeWrapper overrides this method,
2947
// so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here)
2948
TypeWrapper tw = this;
2953
tw = tw.ElementTypeWrapper;
2955
ilgen.EmitLdc_I4(rank);
2956
ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("IsInstanceArray"));
2960
ilgen.Emit_instanceof(TypeAsTBD);
2963
#endif // !STUB_GENERATOR
2965
// NOTE don't call this method, call MethodWrapper.Link instead
2966
internal virtual MethodBase LinkMethod(MethodWrapper mw)
2968
return mw.GetMethod();
2971
// NOTE don't call this method, call FieldWrapper.Link instead
2972
internal virtual FieldInfo LinkField(FieldWrapper fw)
2974
return fw.GetField();
2978
internal virtual void EmitRunClassConstructor(CodeEmitter ilgen)
2981
#endif // !STUB_GENERATOR
2983
internal virtual string GetGenericSignature()
2988
internal virtual string GetGenericMethodSignature(MethodWrapper mw)
2993
internal virtual string GetGenericFieldSignature(FieldWrapper fw)
2998
#if !STATIC_COMPILER && !STUB_GENERATOR
2999
internal virtual string[] GetEnclosingMethod()
3004
internal virtual object[] GetDeclaredAnnotations()
3009
internal virtual object[] GetMethodAnnotations(MethodWrapper mw)
3014
internal virtual object[][] GetParameterAnnotations(MethodWrapper mw)
3019
internal virtual object[] GetFieldAnnotations(FieldWrapper fw)
3024
internal virtual string GetSourceFileName()
3029
internal virtual int GetSourceLineNumber(MethodBase mb, int ilOffset)
3034
internal virtual object GetAnnotationDefault(MethodWrapper mw)
3036
MethodBase mb = mw.GetMethod();
3039
object[] attr = mb.GetCustomAttributes(typeof(AnnotationDefaultAttribute), false);
3040
if(attr.Length == 1)
3042
return JVM.NewAnnotationElementValue(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), mw.ReturnType.ClassObject, ((AnnotationDefaultAttribute)attr[0]).Value);
3047
#endif // !STATIC_COMPILER && !STUB_GENERATOR
3049
internal virtual Annotation Annotation
3057
internal virtual Type EnumType
3065
protected static TypeWrapper[] GetImplementedInterfacesAsTypeWrappers(Type type)
3067
Type[] interfaceTypes = type.GetInterfaces();
3068
TypeWrapper[] interfaces = new TypeWrapper[interfaceTypes.Length];
3069
for (int i = 0; i < interfaceTypes.Length; i++)
3071
Type decl = interfaceTypes[i].DeclaringType;
3072
if (decl != null && AttributeHelper.IsGhostInterface(decl))
3074
// we have to return the declaring type for ghost interfaces
3075
interfaces[i] = ClassLoaderWrapper.GetWrapperFromType(decl);
3079
interfaces[i] = ClassLoaderWrapper.GetWrapperFromType(interfaceTypes[i]);
3082
for (int i = 0; i < interfaceTypes.Length; i++)
3084
if (interfaces[i].IsRemapped)
3086
// for remapped interfaces, we also return the original interface (Java types will ignore it, if it isn't listed in the ImplementsAttribute)
3087
TypeWrapper twRemapped = interfaces[i];
3088
TypeWrapper tw = DotNetTypeWrapper.GetWrapperFromDotNetType(interfaceTypes[i]);
3090
if (Array.IndexOf(interfaces, twRemapped) == -1)
3092
Array.Resize(ref interfaces, interfaces.Length + 1);
3093
interfaces[interfaces.Length - 1] = twRemapped;
3100
internal TypeWrapper GetPublicBaseTypeWrapper()
3102
Debug.Assert(!this.IsPublic);
3103
if (this.IsUnloadable || this.IsInterface)
3105
return CoreClasses.java.lang.Object.Wrapper;
3107
for (TypeWrapper tw = this; ; tw = tw.BaseTypeWrapper)
3117
// return the constructor used for automagic .NET serialization
3118
internal virtual MethodBase GetSerializationConstructor()
3120
Debug.Assert(!(this is DynamicTypeWrapper));
3121
return this.TypeAsBaseType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] {
3122
JVM.Import(typeof(System.Runtime.Serialization.SerializationInfo)), JVM.Import(typeof(System.Runtime.Serialization.StreamingContext)) }, null);
3125
internal virtual MethodBase GetBaseSerializationConstructor()
3127
return BaseTypeWrapper.GetSerializationConstructor();
3132
sealed class UnloadableTypeWrapper : TypeWrapper
3134
private Type customModifier;
3136
internal UnloadableTypeWrapper(string name)
3137
: base(TypeWrapper.UnloadableModifiersHack, name)
3141
internal UnloadableTypeWrapper(string name, Type customModifier)
3144
this.customModifier = customModifier;
3147
internal override TypeWrapper BaseTypeWrapper
3149
get { return null; }
3152
internal override ClassLoaderWrapper GetClassLoader()
3157
internal override TypeWrapper EnsureLoadable(ClassLoaderWrapper loader)
3159
TypeWrapper tw = loader.LoadClassByDottedNameFast(this.Name);
3162
throw new NoClassDefFoundError(this.Name);
3167
internal override string SigName
3172
if(name.StartsWith("["))
3176
return "L" + name + ";";
3180
protected override void LazyPublishMembers()
3182
throw new InvalidOperationException("LazyPublishMembers called on UnloadableTypeWrapper: " + Name);
3185
internal override Type TypeAsTBD
3189
throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
3193
internal override TypeWrapper[] Interfaces
3197
throw new InvalidOperationException("get_Interfaces called on UnloadableTypeWrapper: " + Name);
3201
internal override TypeWrapper[] InnerClasses
3205
throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper: " + Name);
3209
internal override TypeWrapper DeclaringTypeWrapper
3213
throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
3217
internal override void Finish()
3219
throw new InvalidOperationException("Finish called on UnloadableTypeWrapper: " + Name);
3222
internal Type CustomModifier
3224
get { return customModifier; }
3227
internal void SetCustomModifier(Type type)
3229
this.customModifier = type;
3233
internal Type GetCustomModifier(TypeWrapperFactory context)
3235
// we don't need to lock, because we're only supposed to be called while holding the finish lock
3236
return customModifier ?? (customModifier = context.DefineUnloadable(this.Name));
3239
internal override void EmitCheckcast(TypeWrapper context, CodeEmitter ilgen)
3241
ilgen.Emit(OpCodes.Ldtoken, context.TypeAsTBD);
3242
ilgen.Emit(OpCodes.Ldstr, Name);
3243
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCast);
3246
internal override void EmitInstanceOf(TypeWrapper context, CodeEmitter ilgen)
3248
ilgen.Emit(OpCodes.Ldtoken, context.TypeAsTBD);
3249
ilgen.Emit(OpCodes.Ldstr, Name);
3250
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicInstanceOf);
3252
#endif // !STUB_GENERATOR
3255
sealed class PrimitiveTypeWrapper : TypeWrapper
3257
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(Types.Byte, "B");
3258
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(Types.Char, "C");
3259
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(Types.Double, "D");
3260
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(Types.Single, "F");
3261
internal static readonly PrimitiveTypeWrapper INT = new PrimitiveTypeWrapper(Types.Int32, "I");
3262
internal static readonly PrimitiveTypeWrapper LONG = new PrimitiveTypeWrapper(Types.Int64, "J");
3263
internal static readonly PrimitiveTypeWrapper SHORT = new PrimitiveTypeWrapper(Types.Int16, "S");
3264
internal static readonly PrimitiveTypeWrapper BOOLEAN = new PrimitiveTypeWrapper(Types.Boolean, "Z");
3265
internal static readonly PrimitiveTypeWrapper VOID = new PrimitiveTypeWrapper(Types.Void, "V");
3267
private readonly Type type;
3268
private readonly string sigName;
3270
private PrimitiveTypeWrapper(Type type, string sigName)
3271
: base(Modifiers.Public | Modifiers.Abstract | Modifiers.Final, null)
3274
this.sigName = sigName;
3277
internal override TypeWrapper BaseTypeWrapper
3279
get { return null; }
3282
internal static bool IsPrimitiveType(Type type)
3284
return type == BYTE.type
3285
|| type == CHAR.type
3286
|| type == DOUBLE.type
3287
|| type == FLOAT.type
3289
|| type == LONG.type
3290
|| type == SHORT.type
3291
|| type == BOOLEAN.type
3292
|| type == VOID.type;
3295
internal override string SigName
3303
internal override ClassLoaderWrapper GetClassLoader()
3305
return ClassLoaderWrapper.GetBootstrapClassLoader();
3308
internal override Type TypeAsTBD
3316
internal override TypeWrapper[] Interfaces
3320
return TypeWrapper.EmptyArray;
3324
internal override TypeWrapper[] InnerClasses
3328
return TypeWrapper.EmptyArray;
3332
internal override TypeWrapper DeclaringTypeWrapper
3340
internal override void Finish()
3344
public override string ToString()
3346
return "PrimitiveTypeWrapper[" + sigName + "]";
3350
class CompiledTypeWrapper : TypeWrapper
3352
private readonly Type type;
3353
private TypeWrapper baseTypeWrapper;
3354
private TypeWrapper[] interfaces;
3355
private MethodInfo clinitMethod;
3356
private bool clinitMethodSet;
3357
private Modifiers reflectiveModifiers;
3359
internal static CompiledTypeWrapper newInstance(string name, Type type)
3361
// TODO since ghost and remapped types can only exist in the core library assembly, we probably
3362
// should be able to remove the Type.IsDefined() tests in most cases
3363
if(type.IsValueType && AttributeHelper.IsGhostInterface(type))
3365
return new CompiledGhostTypeWrapper(name, type);
3367
else if(AttributeHelper.IsRemappedType(type))
3369
return new CompiledRemappedTypeWrapper(name, type);
3373
return new CompiledTypeWrapper(name, type);
3377
private sealed class CompiledRemappedTypeWrapper : CompiledTypeWrapper
3379
private readonly Type remappedType;
3381
internal CompiledRemappedTypeWrapper(string name, Type type)
3384
RemappedTypeAttribute attr = AttributeHelper.GetRemappedType(type);
3387
throw new InvalidOperationException();
3389
remappedType = attr.Type;
3392
internal override Type TypeAsTBD
3396
return remappedType;
3400
internal override bool IsRemapped
3408
protected override void LazyPublishMethods()
3410
List<MethodWrapper> list = new List<MethodWrapper>();
3411
const BindingFlags bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
3412
foreach(ConstructorInfo ctor in type.GetConstructors(bindingFlags))
3414
AddMethod(list, ctor);
3416
foreach(MethodInfo method in type.GetMethods(bindingFlags))
3418
AddMethod(list, method);
3420
// if we're a remapped interface, we need to get the methods from the real interface
3421
if(remappedType.IsInterface)
3423
Type nestedHelper = type.GetNestedType("__Helper", BindingFlags.Public | BindingFlags.Static);
3424
foreach(RemappedInterfaceMethodAttribute m in AttributeHelper.GetRemappedInterfaceMethods(type))
3426
MethodInfo method = remappedType.GetMethod(m.MappedTo);
3427
MethodInfo mbHelper = method;
3428
ExModifiers modifiers = AttributeHelper.GetModifiers(method, false);
3431
TypeWrapper retType;
3432
TypeWrapper[] paramTypes;
3433
MemberFlags flags = MemberFlags.None;
3434
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes, ref flags);
3435
if(nestedHelper != null)
3437
mbHelper = nestedHelper.GetMethod(m.Name);
3438
if(mbHelper == null)
3443
MethodWrapper mw = new CompiledRemappedMethodWrapper(this, m.Name, sig, method, retType, paramTypes, modifiers, false, mbHelper, null);
3444
mw.SetDeclaredExceptions(m.Throws);
3448
SetMethods(list.ToArray());
3451
private void AddMethod(List<MethodWrapper> list, MethodBase method)
3453
if(!AttributeHelper.IsHideFromJava(method)
3454
&& (remappedType.IsSealed || !method.Name.StartsWith("instancehelper_"))
3455
&& (!remappedType.IsSealed || method.IsStatic))
3457
list.Add(CreateRemappedMethodWrapper(method));
3461
protected override void LazyPublishFields()
3463
List<FieldWrapper> list = new List<FieldWrapper>();
3464
FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
3465
foreach(FieldInfo field in fields)
3467
if(!AttributeHelper.IsHideFromJava(field))
3469
list.Add(CreateFieldWrapper(field));
3472
SetFields(list.ToArray());
3475
private MethodWrapper CreateRemappedMethodWrapper(MethodBase mb)
3477
ExModifiers modifiers = AttributeHelper.GetModifiers(mb, false);
3480
TypeWrapper retType;
3481
TypeWrapper[] paramTypes;
3482
MemberFlags flags = MemberFlags.None;
3483
GetNameSigFromMethodBase(mb, out name, out sig, out retType, out paramTypes, ref flags);
3484
MethodInfo mbHelper = mb as MethodInfo;
3485
bool hideFromReflection = mbHelper != null && AttributeHelper.IsHideFromReflection(mbHelper);
3486
MethodInfo mbNonvirtualHelper = null;
3487
if(!mb.IsStatic && !mb.IsConstructor)
3489
ParameterInfo[] parameters = mb.GetParameters();
3490
Type[] argTypes = new Type[parameters.Length + 1];
3491
argTypes[0] = remappedType;
3492
for(int i = 0; i < parameters.Length; i++)
3494
argTypes[i + 1] = parameters[i].ParameterType;
3496
MethodInfo helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null);
3501
mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null);
3503
return new CompiledRemappedMethodWrapper(this, name, sig, mb, retType, paramTypes, modifiers, hideFromReflection, mbHelper, mbNonvirtualHelper);
3507
private sealed class CompiledGhostTypeWrapper : CompiledTypeWrapper
3509
private FieldInfo ghostRefField;
3510
private Type typeAsBaseType;
3512
internal CompiledGhostTypeWrapper(string name, Type type)
3517
internal override Type TypeAsBaseType
3521
if(typeAsBaseType == null)
3523
typeAsBaseType = type.GetNestedType("__Interface");
3525
return typeAsBaseType;
3529
internal override FieldInfo GhostRefField
3533
if(ghostRefField == null)
3535
ghostRefField = type.GetField("__<ref>");
3537
return ghostRefField;
3541
internal override bool IsGhost
3550
internal static string GetName(Type type)
3552
Debug.Assert(!type.HasElementType);
3553
Debug.Assert(!type.IsGenericType);
3554
Debug.Assert(AttributeHelper.IsJavaModule(type.Module));
3556
// look for our custom attribute, that contains the real name of the type (for inner classes)
3557
InnerClassAttribute attr = AttributeHelper.GetInnerClass(type);
3560
string name = attr.InnerClassName;
3565
if(type.DeclaringType != null)
3567
return GetName(type.DeclaringType) + "$" + TypeNameUtil.Unescape(type.Name);
3570
return TypeNameUtil.Unescape(type.FullName);
3573
private static TypeWrapper GetBaseTypeWrapper(Type type)
3575
if(type.IsInterface || AttributeHelper.IsGhostInterface(type))
3579
else if(type.BaseType == null)
3581
// System.Object must appear to be derived from java.lang.Object
3582
return CoreClasses.java.lang.Object.Wrapper;
3586
RemappedTypeAttribute attr = AttributeHelper.GetRemappedType(type);
3589
if(attr.Type == Types.Object)
3595
return CoreClasses.java.lang.Object.Wrapper;
3598
else if(ClassLoaderWrapper.IsRemappedType(type.BaseType))
3600
// if we directly extend System.Object or System.Exception, the base class must be cli.System.Object or cli.System.Exception
3601
return DotNetTypeWrapper.GetWrapperFromDotNetType(type.BaseType);
3603
TypeWrapper tw = null;
3606
type = type.BaseType;
3607
tw = ClassLoaderWrapper.GetWrapperFromType(type);
3613
private CompiledTypeWrapper(ExModifiers exmod, string name)
3614
: base(exmod.Modifiers, name)
3616
this.IsInternal = exmod.IsInternal;
3619
private CompiledTypeWrapper(string name, Type type)
3620
: this(GetModifiers(type), name)
3622
Debug.Assert(!(type is TypeBuilder));
3623
Debug.Assert(!type.Name.EndsWith("[]"));
3628
internal override TypeWrapper BaseTypeWrapper
3630
get { return baseTypeWrapper ?? (baseTypeWrapper = GetBaseTypeWrapper(type)); }
3633
internal override ClassLoaderWrapper GetClassLoader()
3635
return AssemblyClassLoader.FromAssembly(type.Assembly);
3638
private static ExModifiers GetModifiers(Type type)
3640
ModifiersAttribute attr = AttributeHelper.GetModifiersAttribute(type);
3643
return new ExModifiers(attr.Modifiers, attr.IsInternal);
3645
// only returns public, protected, private, final, static, abstract and interface (as per
3646
// the documentation of Class.getModifiers())
3647
Modifiers modifiers = 0;
3648
if(type.IsPublic || type.IsNestedPublic)
3650
modifiers |= Modifiers.Public;
3654
modifiers |= Modifiers.Final;
3658
modifiers |= Modifiers.Abstract;
3660
if(type.IsInterface)
3662
modifiers |= Modifiers.Interface;
3666
modifiers |= Modifiers.Super;
3668
return new ExModifiers(modifiers, false);
3671
internal override bool HasStaticInitializer
3675
if(!clinitMethodSet)
3677
clinitMethod = type.GetMethod("__<clinit>", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
3678
clinitMethodSet = true;
3680
return clinitMethod != null;
3684
internal override TypeWrapper[] Interfaces
3688
if(interfaces == null)
3690
interfaces = GetInterfaces();
3696
private TypeWrapper[] GetInterfaces()
3698
// NOTE instead of getting the interfaces list from Type, we use a custom
3699
// attribute to list the implemented interfaces, because Java reflection only
3700
// reports the interfaces *directly* implemented by the type, not the inherited
3701
// interfaces. This is significant for serialVersionUID calculation (for example).
3702
ImplementsAttribute attr = AttributeHelper.GetImplements(type);
3705
return TypeWrapper.EmptyArray;
3707
string[] interfaceNames = attr.Interfaces;
3708
TypeWrapper[] interfaceWrappers = new TypeWrapper[interfaceNames.Length];
3709
if (this.IsRemapped)
3711
for (int i = 0; i < interfaceWrappers.Length; i++)
3713
interfaceWrappers[i] = ClassLoaderWrapper.LoadClassCritical(interfaceNames[i]);
3718
TypeWrapper[] typeWrappers = GetImplementedInterfacesAsTypeWrappers(type);
3719
for (int i = 0; i < interfaceWrappers.Length; i++)
3721
for (int j = 0; j < typeWrappers.Length; j++)
3723
if (typeWrappers[j].Name == interfaceNames[i])
3725
interfaceWrappers[i] = typeWrappers[j];
3729
if (interfaceWrappers[i] == null)
3732
throw new FatalCompilerErrorException(Message.UnableToResolveInterface, interfaceNames[i], this);
3734
JVM.CriticalFailure("Unable to resolve interface " + interfaceNames[i] + " on type " + this, null);
3739
return interfaceWrappers;
3742
internal override TypeWrapper[] InnerClasses
3746
Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
3747
List<TypeWrapper> wrappers = new List<TypeWrapper>();
3748
for(int i = 0; i < nestedTypes.Length; i++)
3750
if(nestedTypes[i].Name.EndsWith("Attribute", StringComparison.Ordinal)
3751
&& nestedTypes[i].IsClass
3752
&& nestedTypes[i].BaseType.FullName == "ikvm.internal.AnnotationAttributeBase")
3754
// HACK it's the custom attribute we generated for a corresponding annotation, so we shouldn't surface it as an inner classes
3755
// (we can't put a HideFromJavaAttribute on it, because we do want the class to be visible as a $Proxy)
3758
if(!AttributeHelper.IsHideFromJava(nestedTypes[i]))
3760
wrappers.Add(ClassLoaderWrapper.GetWrapperFromType(nestedTypes[i]));
3763
foreach(string s in AttributeHelper.GetNonNestedInnerClasses(type))
3765
wrappers.Add(GetClassLoader().LoadClassByDottedName(s));
3767
return wrappers.ToArray();
3771
internal override TypeWrapper DeclaringTypeWrapper
3775
Type declaringType = type.DeclaringType;
3776
if(declaringType != null)
3778
return ClassLoaderWrapper.GetWrapperFromType(declaringType);
3780
string decl = AttributeHelper.GetNonNestedOuterClasses(type);
3783
return GetClassLoader().LoadClassByDottedName(decl);
3789
internal override Modifiers ReflectiveModifiers
3793
if (reflectiveModifiers == 0)
3796
InnerClassAttribute attr = AttributeHelper.GetInnerClass(type);
3799
// the mask comes from RECOGNIZED_INNER_CLASS_MODIFIERS in src/hotspot/share/vm/classfile/classFileParser.cpp
3800
// (minus ACC_SUPER)
3801
mods = attr.Modifiers & (Modifiers)0x761F;
3805
// the mask comes from JVM_RECOGNIZED_CLASS_MODIFIERS in src/hotspot/share/vm/prims/jvm.h
3806
// (minus ACC_SUPER)
3807
mods = Modifiers & (Modifiers)0x7611;
3811
mods |= Modifiers.Abstract;
3813
reflectiveModifiers = mods;
3815
return reflectiveModifiers;
3819
internal override Type TypeAsBaseType
3827
private void SigTypePatchUp(string sigtype, ref TypeWrapper type)
3829
if(sigtype != type.SigName)
3831
// if type is an array, we know that it is a ghost array, because arrays of unloadable are compiled
3832
// as object (not as arrays of object)
3835
type = GetClassLoader().FieldTypeWrapperFromSig(sigtype);
3837
else if(type.IsPrimitive)
3839
type = DotNetTypeWrapper.GetWrapperFromDotNetType(type.TypeAsTBD);
3840
if(sigtype != type.SigName)
3842
throw new InvalidOperationException();
3845
else if(type.IsNonPrimitiveValueType)
3847
// this can't happen and even if it does happen we cannot return
3848
// UnloadableTypeWrapper because that would result in incorrect code
3850
throw new InvalidOperationException();
3854
if(sigtype[0] == 'L')
3856
sigtype = sigtype.Substring(1, sigtype.Length - 2);
3860
TypeWrapper tw = GetClassLoader().LoadClassByDottedNameFast(sigtype);
3861
if(tw != null && tw.IsRemapped)
3867
catch(RetargetableJavaException)
3870
type = new UnloadableTypeWrapper(sigtype);
3875
private static void ParseSig(string sig, out string[] sigparam, out string sigret)
3877
List<string> list = new List<string>();
3885
int end = sig.IndexOf(';', pos) + 1;
3886
list.Add(sig.Substring(pos, end - pos));
3893
while(sig[pos + skip] == '[') skip++;
3894
if(sig[pos + skip] == 'L')
3896
int end = sig.IndexOf(';', pos) + 1;
3897
list.Add(sig.Substring(pos, end - pos));
3903
list.Add(sig.Substring(pos, skip));
3909
sigparam = list.ToArray();
3910
sigret = sig.Substring(pos + 1);
3913
list.Add(sig.Substring(pos, 1));
3920
private bool IsCallerID(Type type)
3923
return type.FullName == "ikvm.internal.CallerID";
3925
return type == CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType
3926
&& GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader();
3930
private void GetNameSigFromMethodBase(MethodBase method, out string name, out string sig, out TypeWrapper retType, out TypeWrapper[] paramTypes, ref MemberFlags flags)
3932
retType = method is ConstructorInfo ? PrimitiveTypeWrapper.VOID : GetParameterTypeWrapper(((MethodInfo)method).ReturnParameter);
3933
ParameterInfo[] parameters = method.GetParameters();
3934
int len = parameters.Length;
3936
&& IsCallerID(parameters[len - 1].ParameterType)
3937
&& !method.DeclaringType.IsInterface)
3940
flags |= MemberFlags.CallerID;
3942
paramTypes = new TypeWrapper[len];
3943
for(int i = 0; i < len; i++)
3945
paramTypes[i] = GetParameterTypeWrapper(parameters[i]);
3947
NameSigAttribute attr = AttributeHelper.GetNameSig(method);
3954
ParseSig(sig, out sigparams, out sigret);
3955
// HACK newhelper methods have a return type, but it should be void
3956
if(name == "<init>")
3958
retType = PrimitiveTypeWrapper.VOID;
3960
SigTypePatchUp(sigret, ref retType);
3961
// if we have a remapped method, the paramTypes array contains an additional entry for "this" so we have
3963
if(paramTypes.Length == sigparams.Length + 1)
3965
TypeWrapper[] temp = paramTypes;
3966
paramTypes = new TypeWrapper[sigparams.Length];
3967
Array.Copy(temp, 1, paramTypes, 0, paramTypes.Length);
3969
Debug.Assert(sigparams.Length == paramTypes.Length);
3970
for(int i = 0; i < sigparams.Length; i++)
3972
SigTypePatchUp(sigparams[i], ref paramTypes[i]);
3977
if(method is ConstructorInfo)
3979
name = method.IsStatic ? "<clinit>" : "<init>";
3984
if(name.StartsWith(NamePrefix.Bridge, StringComparison.Ordinal))
3986
name = name.Substring(NamePrefix.Bridge.Length);
3989
System.Text.StringBuilder sb = new System.Text.StringBuilder("(");
3990
foreach(TypeWrapper tw in paramTypes)
3992
sb.Append(tw.SigName);
3995
sb.Append(retType.SigName);
3996
sig = sb.ToString();
4000
private sealed class DelegateConstructorMethodWrapper : MethodWrapper
4002
private readonly ConstructorInfo constructor;
4003
private MethodInfo invoke;
4005
private DelegateConstructorMethodWrapper(TypeWrapper tw, TypeWrapper iface, ExModifiers mods)
4006
: base(tw, StringConstants.INIT, "(" + iface.SigName + ")V", null, PrimitiveTypeWrapper.VOID, new TypeWrapper[] { iface }, mods.Modifiers, mods.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None)
4010
internal DelegateConstructorMethodWrapper(TypeWrapper tw, MethodBase method)
4011
: this(tw, tw.GetClassLoader().LoadClassByDottedName(tw.Name + DotNetTypeWrapper.DelegateInterfaceSuffix), AttributeHelper.GetModifiers(method, false))
4013
constructor = (ConstructorInfo)method;
4016
protected override void DoLinkMethod()
4018
MethodWrapper mw = GetParameters()[0].GetMethods()[0];
4020
invoke = (MethodInfo)mw.GetMethod();
4024
internal override void EmitNewobj(CodeEmitter ilgen)
4026
ilgen.Emit(OpCodes.Dup);
4027
ilgen.Emit(OpCodes.Ldvirtftn, invoke);
4028
ilgen.Emit(OpCodes.Newobj, constructor);
4030
#endif // !STUB_GENERATOR
4033
protected override void LazyPublishMethods()
4035
bool isDelegate = type.BaseType == Types.MulticastDelegate;
4036
List<MethodWrapper> methods = new List<MethodWrapper>();
4037
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
4038
foreach(ConstructorInfo ctor in type.GetConstructors(flags))
4040
if(isDelegate && !ctor.IsStatic && !AttributeHelper.IsHideFromJava(ctor))
4042
methods.Add(new DelegateConstructorMethodWrapper(this, ctor));
4046
AddMethodOrConstructor(ctor, methods);
4049
foreach(MethodInfo method in type.GetMethods(flags))
4051
AddMethodOrConstructor(method, methods);
4053
SetMethods(methods.ToArray());
4056
private void AddMethodOrConstructor(MethodBase method, List<MethodWrapper> methods)
4058
if(!AttributeHelper.IsHideFromJava(method))
4060
if(method.IsSpecialName && method.Name.StartsWith("__<"))
4068
TypeWrapper retType;
4069
TypeWrapper[] paramTypes;
4070
MethodInfo mi = method as MethodInfo;
4071
bool hideFromReflection = mi != null ? AttributeHelper.IsHideFromReflection(mi) : false;
4072
MemberFlags flags = hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None;
4073
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes, ref flags);
4074
ExModifiers mods = AttributeHelper.GetModifiers(method, false);
4077
flags |= MemberFlags.InternalAccess;
4079
if(hideFromReflection && name.StartsWith(NamePrefix.AccessStub, StringComparison.Ordinal))
4081
int id = Int32.Parse(name.Substring(NamePrefix.AccessStub.Length, name.IndexOf('|', NamePrefix.AccessStub.Length) - NamePrefix.AccessStub.Length));
4082
name = name.Substring(name.IndexOf('|', NamePrefix.AccessStub.Length) + 1);
4083
flags |= MemberFlags.AccessStub;
4084
MethodInfo nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance);
4085
methods.Add(new AccessStubMethodWrapper(this, name, sig, mi, mi, nonvirt ?? mi, retType, paramTypes, mods.Modifiers & ~Modifiers.Final, flags));
4091
Type[] types = new Type[paramTypes.Length];
4092
for (int i = 0; i < types.Length; i++)
4094
types[i] = paramTypes[i].TypeAsSignatureType;
4096
MethodInfo ifmethod = TypeAsBaseType.GetMethod(method.Name, types);
4097
mw = new GhostMethodWrapper(this, name, sig, ifmethod, (MethodInfo)method, retType, paramTypes, mods.Modifiers, flags);
4101
mw = new TypicalMethodWrapper(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags);
4103
if (mw.HasNonPublicTypeInSignature)
4107
MethodInfo stubVirt;
4108
MethodInfo stubNonVirt;
4109
if (GetType2AccessStubs(name, sig, out stubVirt, out stubNonVirt))
4111
mw = new AccessStubMethodWrapper(this, name, sig, mi, stubVirt, stubNonVirt ?? stubVirt, retType, paramTypes, mw.Modifiers, flags);
4116
ConstructorInfo stub;
4117
if (GetType2AccessStub(sig, out stub))
4119
mw = new AccessStubConstructorMethodWrapper(this, sig, (ConstructorInfo)method, stub, paramTypes, mw.Modifiers, flags);
4128
private bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out MethodInfo stubNonVirt)
4132
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
4133
foreach (MethodInfo method in type.GetMethods(flags))
4135
if (AttributeHelper.IsHideFromJava(method))
4137
NameSigAttribute attr = AttributeHelper.GetNameSig(method);
4138
if (attr != null && attr.Name == name && attr.Sig == sig)
4140
if (method.Name.StartsWith(NamePrefix.NonVirtual, StringComparison.Ordinal))
4142
stubNonVirt = method;
4151
return stubVirt != null;
4154
private bool GetType2AccessStub(string sig, out ConstructorInfo stub)
4157
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
4158
foreach (ConstructorInfo ctor in type.GetConstructors(flags))
4160
if (AttributeHelper.IsHideFromJava(ctor))
4162
NameSigAttribute attr = AttributeHelper.GetNameSig(ctor);
4163
if (attr != null && attr.Sig == sig)
4169
return stub != null;
4172
private static int SortFieldByToken(FieldInfo field1, FieldInfo field2)
4174
return field1.MetadataToken.CompareTo(field2.MetadataToken);
4177
protected override void LazyPublishFields()
4179
List<FieldWrapper> fields = new List<FieldWrapper>();
4180
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
4181
FieldInfo[] rawfields = type.GetFields(flags);
4182
Array.Sort(rawfields, SortFieldByToken);
4183
// FXBUG on .NET 3.5 and Mono Type.GetProperties() will not return "duplicate" properties (i.e. that have the same name and type, but differ in custom modifiers).
4184
// .NET 4.0 works as expected. We don't have a workaround, because that would require name mangling again and this situation is very unlikely anyway.
4185
PropertyInfo[] properties = type.GetProperties(flags);
4186
foreach(FieldInfo field in rawfields)
4188
if(AttributeHelper.IsHideFromJava(field))
4190
if(field.Name.StartsWith(NamePrefix.Type2AccessStubBackingField, StringComparison.Ordinal))
4192
TypeWrapper tw = GetFieldTypeWrapper(field);
4193
string name = field.Name.Substring(NamePrefix.Type2AccessStubBackingField.Length);
4194
for(int i = 0; i < properties.Length; i++)
4196
if(properties[i] != null
4197
&& name == properties[i].Name
4198
&& MatchTypes(tw, GetPropertyTypeWrapper(properties[i])))
4200
fields.Add(new CompiledAccessStubFieldWrapper(this, properties[i], field, tw));
4201
properties[i] = null;
4209
if(field.IsSpecialName && field.Name.StartsWith("__<", StringComparison.Ordinal))
4215
fields.Add(CreateFieldWrapper(field));
4219
foreach(PropertyInfo property in properties)
4221
if(property != null)
4223
AddPropertyFieldWrapper(fields, property, null);
4226
SetFields(fields.ToArray());
4229
private static bool MatchTypes(TypeWrapper tw1, TypeWrapper tw2)
4231
return tw1 == tw2 || (tw1.IsUnloadable && tw2.IsUnloadable && tw1.Name == tw2.Name);
4234
private void AddPropertyFieldWrapper(List<FieldWrapper> fields, PropertyInfo property, FieldInfo field)
4236
// NOTE explictly defined properties (in map.xml) are decorated with HideFromJava,
4237
// so we don't need to worry about them here
4238
if(!AttributeHelper.IsHideFromJava(property))
4240
// is it a type 1 access stub?
4241
if(AttributeHelper.IsHideFromReflection(property))
4243
fields.Add(new CompiledAccessStubFieldWrapper(this, property, GetPropertyTypeWrapper(property)));
4247
// It must be an explicit property
4248
// (defined in Java source by an @ikvm.lang.Property annotation)
4249
ModifiersAttribute mods = AttributeHelper.GetModifiersAttribute(property);
4250
fields.Add(new CompiledPropertyFieldWrapper(this, property, new ExModifiers(mods.Modifiers, mods.IsInternal)));
4255
private sealed class CompiledRemappedMethodWrapper : SmartMethodWrapper
4257
private MethodInfo mbHelper;
4258
#if !STATIC_COMPILER
4259
private MethodInfo mbNonvirtualHelper;
4262
internal CompiledRemappedMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, ExModifiers modifiers, bool hideFromReflection, MethodInfo mbHelper, MethodInfo mbNonvirtualHelper)
4263
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers.Modifiers,
4264
(modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) | (hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None))
4266
this.mbHelper = mbHelper;
4267
#if !STATIC_COMPILER
4268
this.mbNonvirtualHelper = mbNonvirtualHelper;
4273
protected override void CallImpl(CodeEmitter ilgen)
4275
MethodBase mb = GetMethod();
4276
MethodInfo mi = mb as MethodInfo;
4279
if(!IsStatic && IsFinal)
4281
// When calling a final instance method on a remapped type from a class derived from a .NET class (i.e. a cli.System.Object or cli.System.Exception derived base class)
4282
// then we can't call the java.lang.Object or java.lang.Throwable methods and we have to go through the instancehelper_ method. Note that since the method
4283
// is final, this won't affect the semantics.
4284
CallvirtImpl(ilgen);
4288
ilgen.Emit(OpCodes.Call, mi);
4293
ilgen.Emit(OpCodes.Call, mb);
4297
protected override void CallvirtImpl(CodeEmitter ilgen)
4299
Debug.Assert(!mbHelper.IsStatic || mbHelper.Name.StartsWith("instancehelper_") || mbHelper.DeclaringType.Name == "__Helper");
4300
if(mbHelper.IsPublic)
4302
ilgen.Emit(mbHelper.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mbHelper);
4306
// HACK the helper is not public, this means that we're dealing with finalize or clone
4307
ilgen.Emit(OpCodes.Callvirt, GetMethod());
4311
protected override void NewobjImpl(CodeEmitter ilgen)
4313
MethodBase mb = GetMethod();
4314
MethodInfo mi = mb as MethodInfo;
4317
Debug.Assert(mi.Name == "newhelper");
4318
ilgen.Emit(OpCodes.Call, mi);
4322
ilgen.Emit(OpCodes.Newobj, mb);
4325
#endif // !STUB_GENERATOR
4327
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
4329
protected override object InvokeNonvirtualRemapped(object obj, object[] args)
4331
Type[] p1 = GetParametersForDefineMethod();
4332
Type[] argTypes = new Type[p1.Length + 1];
4333
p1.CopyTo(argTypes, 1);
4334
argTypes[0] = this.DeclaringType.TypeAsSignatureType;
4335
MethodInfo mi = mbNonvirtualHelper;
4340
object[] args1 = new object[args.Length + 1];
4342
args.CopyTo(args1, 1);
4343
return mi.Invoke(null, args1);
4346
internal override void EmitCallvirtReflect(CodeEmitter ilgen)
4348
MethodBase mb = mbHelper != null ? mbHelper : GetMethod();
4349
ilgen.Emit(mb.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mb);
4351
#endif // !STATIC_COMPILER
4353
internal string GetGenericSignature()
4355
SignatureAttribute attr = AttributeHelper.GetSignature(mbHelper != null ? mbHelper : GetMethod());
4358
return attr.Signature;
4364
private static TypeWrapper TypeWrapperFromModOpt(Type[] modopt)
4367
TypeWrapper tw = null;
4368
foreach (Type type in modopt)
4370
if (type == JVM.LoadType(typeof(IKVM.Attributes.AccessStub)))
4374
else if (type == Types.Array)
4378
else if (type == Types.Void || type.IsPrimitive || ClassLoaderWrapper.IsRemappedType(type))
4380
tw = DotNetTypeWrapper.GetWrapperFromDotNetType(type);
4384
tw = ClassLoaderWrapper.GetWrapperFromType(type)
4385
?? new UnloadableTypeWrapper(TypeNameUtil.UnmangleNestedTypeName(type.Name), type);
4390
tw = tw.MakeArrayType(rank);
4395
private static TypeWrapper GetPropertyTypeWrapper(PropertyInfo property)
4397
return TypeWrapperFromModOpt(property.GetOptionalCustomModifiers())
4398
?? ClassLoaderWrapper.GetWrapperFromType(property.PropertyType);
4401
private static TypeWrapper GetFieldTypeWrapper(FieldInfo field)
4403
return TypeWrapperFromModOpt(field.GetOptionalCustomModifiers())
4404
?? ClassLoaderWrapper.GetWrapperFromType(field.FieldType);
4407
private static TypeWrapper GetParameterTypeWrapper(ParameterInfo param)
4409
TypeWrapper tw = TypeWrapperFromModOpt(param.GetOptionalCustomModifiers());
4414
Type parameterType = param.ParameterType;
4415
if (parameterType.IsByRef)
4417
// we only support ByRef parameters for automatically generated delegate invoke stubs
4418
parameterType = parameterType.GetElementType().MakeArrayType();
4420
return ClassLoaderWrapper.GetWrapperFromType(parameterType);
4423
private FieldWrapper CreateFieldWrapper(FieldInfo field)
4425
ExModifiers modifiers = AttributeHelper.GetModifiers(field, false);
4426
TypeWrapper type = GetFieldTypeWrapper(field);
4430
MemberFlags flags = MemberFlags.None;
4431
if(AttributeHelper.IsHideFromReflection(field))
4433
flags |= MemberFlags.HideFromReflection;
4435
if(modifiers.IsInternal)
4437
flags |= MemberFlags.InternalAccess;
4439
return new ConstantFieldWrapper(this, type, field.Name, type.SigName, modifiers.Modifiers, field, null, flags);
4443
return FieldWrapper.Create(this, type, field, field.Name, type.SigName, modifiers);
4447
internal override Type TypeAsTBD
4455
internal override bool IsMapUnsafeException
4459
return AttributeHelper.IsExceptionIsUnsafeForMapping(type);
4463
internal override void Finish()
4465
if(BaseTypeWrapper != null)
4467
BaseTypeWrapper.Finish();
4469
foreach(TypeWrapper tw in this.Interfaces)
4476
internal override void EmitRunClassConstructor(CodeEmitter ilgen)
4478
if(HasStaticInitializer)
4480
ilgen.Emit(OpCodes.Call, clinitMethod);
4483
#endif // !STUB_GENERATOR
4485
internal override string GetGenericSignature()
4487
SignatureAttribute attr = AttributeHelper.GetSignature(type);
4490
return attr.Signature;
4495
internal override string GetGenericMethodSignature(MethodWrapper mw)
4497
if(mw is CompiledRemappedMethodWrapper)
4499
return ((CompiledRemappedMethodWrapper)mw).GetGenericSignature();
4501
MethodBase mb = mw.GetMethod();
4504
SignatureAttribute attr = AttributeHelper.GetSignature(mb);
4507
return attr.Signature;
4513
internal override string GetGenericFieldSignature(FieldWrapper fw)
4515
FieldInfo fi = fw.GetField();
4518
SignatureAttribute attr = AttributeHelper.GetSignature(fi);
4521
return attr.Signature;
4527
#if !STATIC_COMPILER && !STUB_GENERATOR
4528
internal override string[] GetEnclosingMethod()
4530
EnclosingMethodAttribute enc = AttributeHelper.GetEnclosingMethodAttribute(type);
4533
return new string[] { enc.ClassName, enc.MethodName, enc.MethodSignature };
4538
internal override object[] GetDeclaredAnnotations()
4540
return type.GetCustomAttributes(false);
4543
internal override object[] GetMethodAnnotations(MethodWrapper mw)
4545
MethodBase mb = mw.GetMethod();
4548
// delegate constructor
4551
return mb.GetCustomAttributes(false);
4554
internal override object[][] GetParameterAnnotations(MethodWrapper mw)
4556
MethodBase mb = mw.GetMethod();
4559
// delegate constructor
4562
ParameterInfo[] parameters = mb.GetParameters();
4564
if(mb.IsStatic && !mw.IsStatic && mw.Name != "<init>")
4573
object[][] attribs = new object[parameters.Length - skip - skipEnd][];
4574
for(int i = skip; i < parameters.Length - skipEnd; i++)
4576
attribs[i - skip] = parameters[i].GetCustomAttributes(false);
4581
internal override object[] GetFieldAnnotations(FieldWrapper fw)
4583
FieldInfo field = fw.GetField();
4586
return field.GetCustomAttributes(false);
4588
CompiledPropertyFieldWrapper prop = fw as CompiledPropertyFieldWrapper;
4591
return prop.GetProperty().GetCustomAttributes(false);
4593
return new object[0];
4597
private sealed class CompiledAnnotation : Annotation
4601
internal CompiledAnnotation(Type type)
4606
private CustomAttributeBuilder MakeCustomAttributeBuilder(object annotation)
4608
return new CustomAttributeBuilder(type.GetConstructor(new Type[] { JVM.Import(typeof(object[])) }), new object[] { annotation });
4611
internal override void Apply(ClassLoaderWrapper loader, TypeBuilder tb, object annotation)
4613
annotation = QualifyClassNames(loader, annotation);
4614
tb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4617
internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation)
4619
annotation = QualifyClassNames(loader, annotation);
4620
mb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4623
internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation)
4625
annotation = QualifyClassNames(loader, annotation);
4626
fb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4629
internal override void Apply(ClassLoaderWrapper loader, ParameterBuilder pb, object annotation)
4631
annotation = QualifyClassNames(loader, annotation);
4632
pb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4635
internal override void Apply(ClassLoaderWrapper loader, AssemblyBuilder ab, object annotation)
4637
annotation = QualifyClassNames(loader, annotation);
4638
ab.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4641
internal override void Apply(ClassLoaderWrapper loader, PropertyBuilder pb, object annotation)
4643
annotation = QualifyClassNames(loader, annotation);
4644
pb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
4647
internal override bool IsCustomAttribute
4649
get { return false; }
4653
internal override Annotation Annotation
4657
string annotationAttribute = AttributeHelper.GetAnnotationAttributeType(type);
4658
if(annotationAttribute != null)
4660
return new CompiledAnnotation(type.Assembly.GetType(annotationAttribute, true));
4666
internal override Type EnumType
4670
if((this.Modifiers & Modifiers.Enum) != 0)
4672
return type.GetNestedType("__Enum");
4678
#if !STATIC_COMPILER && !STUB_GENERATOR
4679
internal override string GetSourceFileName()
4681
object[] attr = type.GetCustomAttributes(typeof(SourceFileAttribute), false);
4682
if(attr.Length == 1)
4684
return ((SourceFileAttribute)attr[0]).SourceFile;
4686
if(type.Module.IsDefined(typeof(SourceFileAttribute), false))
4688
return type.Name + ".java";
4693
internal override int GetSourceLineNumber(MethodBase mb, int ilOffset)
4695
object[] attr = mb.GetCustomAttributes(typeof(LineNumberTableAttribute), false);
4696
if(attr.Length == 1)
4698
return ((LineNumberTableAttribute)attr[0]).GetLineNumber(ilOffset);
4704
internal override bool IsFastClassLiteralSafe
4706
get { return true; }
4710
sealed class ArrayTypeWrapper : TypeWrapper
4712
private static TypeWrapper[] interfaces;
4713
private static MethodInfo clone;
4714
private readonly TypeWrapper ultimateElementTypeWrapper;
4715
private Type arrayType;
4716
private bool finished;
4718
internal ArrayTypeWrapper(TypeWrapper ultimateElementTypeWrapper, string name)
4719
: base(Modifiers.Final | Modifiers.Abstract | (ultimateElementTypeWrapper.Modifiers & Modifiers.Public), name)
4721
Debug.Assert(!ultimateElementTypeWrapper.IsArray);
4722
this.ultimateElementTypeWrapper = ultimateElementTypeWrapper;
4723
this.IsInternal = ultimateElementTypeWrapper.IsInternal;
4726
internal override TypeWrapper BaseTypeWrapper
4728
get { return CoreClasses.java.lang.Object.Wrapper; }
4731
internal override ClassLoaderWrapper GetClassLoader()
4733
return ultimateElementTypeWrapper.GetClassLoader();
4736
internal static MethodInfo CloneMethod
4742
clone = Types.Array.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
4748
protected override void LazyPublishMembers()
4750
MethodWrapper mw = new SimpleCallMethodWrapper(this, "clone", "()Ljava.lang.Object;", CloneMethod, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, Modifiers.Public, MemberFlags.HideFromReflection, SimpleOpCode.Callvirt, SimpleOpCode.Callvirt);
4752
SetMethods(new MethodWrapper[] { mw });
4753
SetFields(FieldWrapper.EmptyArray);
4756
internal override Modifiers ReflectiveModifiers
4760
return Modifiers.Final | Modifiers.Abstract | (ultimateElementTypeWrapper.ReflectiveModifiers & Modifiers.AccessMask);
4764
internal override string SigName
4768
// for arrays the signature name is the same as the normal name
4773
internal override TypeWrapper[] Interfaces
4777
if(interfaces == null)
4779
TypeWrapper[] tw = new TypeWrapper[2];
4780
tw[0] = ClassLoaderWrapper.LoadClassCritical("java.lang.Cloneable");
4781
tw[1] = ClassLoaderWrapper.LoadClassCritical("java.io.Serializable");
4788
internal override TypeWrapper[] InnerClasses
4792
return TypeWrapper.EmptyArray;
4796
internal override TypeWrapper DeclaringTypeWrapper
4804
internal override Type TypeAsTBD
4808
while (arrayType == null)
4810
bool prevFinished = finished;
4811
Type type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank);
4814
// We were already finished prior to the call to MakeArrayType, so we can safely
4815
// set arrayType to the finished type.
4816
// Note that this takes advantage of the fact that once we've been finished,
4817
// we can never become unfinished.
4824
// To prevent a race with Finish, we can only set arrayType in this case
4825
// (inside the locked region) if we've not already finished. If we have
4826
// finished, we need to rerun MakeArrayType on the now finished element type.
4827
// Note that there is a benign race left, because it is possible that another
4828
// thread finishes right after we've set arrayType and exited the locked
4829
// region. This is not problem, because TypeAsTBD is only guaranteed to
4830
// return a finished type *after* Finish has been called.
4842
internal override void Finish()
4846
ultimateElementTypeWrapper.Finish();
4849
// Now that we've finished the element type, we must clear arrayType,
4850
// because it may still refer to a TypeBuilder. Note that we have to
4851
// do this atomically with setting "finished", to prevent a race
4859
internal override bool IsFastClassLiteralSafe
4861
// here we have to deal with the somewhat strange fact that in Java you cannot represent primitive type class literals,
4862
// but you can represent arrays of primitive types as a class literal
4863
get { return ultimateElementTypeWrapper.IsFastClassLiteralSafe || ultimateElementTypeWrapper.IsPrimitive; }
4866
internal override TypeWrapper GetUltimateElementTypeWrapper()
4868
return ultimateElementTypeWrapper;
4871
internal static Type MakeArrayType(Type type, int dims)
4873
// NOTE this is not just an optimization, but it is also required to
4874
// make sure that ReflectionOnly types stay ReflectionOnly types
4875
// (in particular instantiations of generic types from mscorlib that
4876
// have ReflectionOnly type parameters).
4877
for(int i = 0; i < dims; i++)
4879
type = type.MakeArrayType();
4885
// this is a container for the special verifier TypeWrappers
4886
sealed class VerifierTypeWrapper : TypeWrapper
4888
// the TypeWrapper constructor interns the name, so we have to pre-intern here to make sure we have the same string object
4889
// (if it has only been interned previously)
4890
private static readonly string This = string.Intern("this");
4891
private static readonly string New = string.Intern("new");
4892
private static readonly string Fault = string.Intern("<fault>");
4893
internal static readonly TypeWrapper Invalid = null;
4894
internal static readonly TypeWrapper Null = new VerifierTypeWrapper("null", 0, null, null);
4895
internal static readonly TypeWrapper UninitializedThis = new VerifierTypeWrapper("uninitialized-this", 0, null, null);
4896
internal static readonly TypeWrapper Unloadable = new UnloadableTypeWrapper("<verifier>");
4897
internal static readonly TypeWrapper ExtendedFloat = new VerifierTypeWrapper("<extfloat>", 0, null, null);
4898
internal static readonly TypeWrapper ExtendedDouble = new VerifierTypeWrapper("<extdouble>", 0, null, null);
4901
private TypeWrapper underlyingType;
4902
private MethodAnalyzer methodAnalyzer;
4905
internal class MethodAnalyzer
4907
internal void ClearFaultBlockException(int dummy) { }
4911
public override string ToString()
4913
return GetType().Name + "[" + Name + "," + index + "," + underlyingType + "]";
4916
internal static TypeWrapper MakeNew(TypeWrapper type, int bytecodeIndex)
4918
return new VerifierTypeWrapper(New, bytecodeIndex, type, null);
4921
internal static TypeWrapper MakeFaultBlockException(MethodAnalyzer ma, int handlerIndex)
4923
return new VerifierTypeWrapper(Fault, handlerIndex, null, ma);
4926
// NOTE the "this" type is special, it can only exist in local[0] and on the stack
4927
// as soon as the type on the stack is merged or popped it turns into its underlying type.
4928
// It exists to capture the verification rules for non-virtual base class method invocation in .NET 2.0,
4929
// which requires that the invocation is done on a "this" reference that was directly loaded onto the
4930
// stack (using ldarg_0).
4931
internal static TypeWrapper MakeThis(TypeWrapper type)
4933
return new VerifierTypeWrapper(This, 0, type, null);
4936
internal static bool IsNotPresentOnStack(TypeWrapper w)
4938
return IsNew(w) || IsFaultBlockException(w);
4941
internal static bool IsNew(TypeWrapper w)
4943
return w != null && w.IsVerifierType && ReferenceEquals(w.Name, New);
4946
internal static bool IsFaultBlockException(TypeWrapper w)
4948
return w != null && w.IsVerifierType && ReferenceEquals(w.Name, Fault);
4951
internal static bool IsNullOrUnloadable(TypeWrapper w)
4953
return w == Null || w.IsUnloadable;
4956
internal static bool IsThis(TypeWrapper w)
4958
return w != null && w.IsVerifierType && ReferenceEquals(w.Name, This);
4961
internal static void ClearFaultBlockException(TypeWrapper w)
4963
VerifierTypeWrapper vtw = (VerifierTypeWrapper)w;
4964
vtw.methodAnalyzer.ClearFaultBlockException(vtw.Index);
4975
internal TypeWrapper UnderlyingType
4979
return underlyingType;
4983
private VerifierTypeWrapper(string name, int index, TypeWrapper underlyingType, MethodAnalyzer methodAnalyzer)
4984
: base(TypeWrapper.VerifierTypeModifiersHack, name)
4987
this.underlyingType = underlyingType;
4988
this.methodAnalyzer = methodAnalyzer;
4991
internal override TypeWrapper BaseTypeWrapper
4993
get { return null; }
4996
internal override ClassLoaderWrapper GetClassLoader()
5001
protected override void LazyPublishMembers()
5003
throw new InvalidOperationException("LazyPublishMembers called on " + this);
5006
internal override Type TypeAsTBD
5010
throw new InvalidOperationException("get_Type called on " + this);
5014
internal override TypeWrapper[] Interfaces
5018
throw new InvalidOperationException("get_Interfaces called on " + this);
5022
internal override TypeWrapper[] InnerClasses
5026
throw new InvalidOperationException("get_InnerClasses called on " + this);
5030
internal override TypeWrapper DeclaringTypeWrapper
5034
throw new InvalidOperationException("get_DeclaringTypeWrapper called on " + this);
5038
internal override void Finish()
5040
throw new InvalidOperationException("Finish called on " + this);