~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/runtime/TypeWrapper.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2002-2012 Jeroen Frijters
 
3
 
 
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.
 
7
 
 
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:
 
11
 
 
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.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
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;
 
30
#else
 
31
using System.Reflection;
 
32
using System.Reflection.Emit;
 
33
#endif
 
34
using System.Diagnostics;
 
35
using System.Security;
 
36
using System.Security.Permissions;
 
37
using IKVM.Attributes;
 
38
 
 
39
namespace IKVM.Internal
 
40
{
 
41
        static class StringConstants
 
42
        {
 
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");
 
48
        }
 
49
 
 
50
        struct ExModifiers
 
51
        {
 
52
                internal readonly Modifiers Modifiers;
 
53
                internal readonly bool IsInternal;
 
54
 
 
55
                internal ExModifiers(Modifiers modifiers, bool isInternal)
 
56
                {
 
57
                        this.Modifiers = modifiers;
 
58
                        this.IsInternal = isInternal;
 
59
                }
 
60
        }
 
61
 
 
62
        static class AttributeHelper
 
63
        {
 
64
                private static CustomAttributeBuilder hideFromJavaAttribute;
 
65
#if STATIC_COMPILER
 
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));
 
102
 
 
103
#if STATIC_COMPILER
 
104
                private static object ParseValue(ClassLoaderWrapper loader, TypeWrapper tw, string val)
 
105
                {
 
106
                        if(tw == CoreClasses.java.lang.String.Wrapper)
 
107
                        {
 
108
                                return val;
 
109
                        }
 
110
                        else if(tw.TypeAsTBD.IsEnum)
 
111
                        {
 
112
                                return EnumHelper.Parse(tw.TypeAsTBD, val);
 
113
                        }
 
114
                        else if(tw.TypeAsTBD == Types.Type)
 
115
                        {
 
116
                                TypeWrapper valtw = loader.LoadClassByDottedNameFast(val);
 
117
                                if(valtw != null)
 
118
                                {
 
119
                                        return valtw.TypeAsBaseType;
 
120
                                }
 
121
                                return StaticCompiler.Universe.GetType(val, true);
 
122
                        }
 
123
                        else if(tw == PrimitiveTypeWrapper.BOOLEAN)
 
124
                        {
 
125
                                return bool.Parse(val);
 
126
                        }
 
127
                        else if(tw == PrimitiveTypeWrapper.BYTE)
 
128
                        {
 
129
                                return (byte)sbyte.Parse(val);
 
130
                        }
 
131
                        else if(tw == PrimitiveTypeWrapper.CHAR)
 
132
                        {
 
133
                                return char.Parse(val);
 
134
                        }
 
135
                        else if(tw == PrimitiveTypeWrapper.SHORT)
 
136
                        {
 
137
                                return short.Parse(val);
 
138
                        }
 
139
                        else if(tw == PrimitiveTypeWrapper.INT)
 
140
                        {
 
141
                                return int.Parse(val);
 
142
                        }
 
143
                        else if(tw == PrimitiveTypeWrapper.FLOAT)
 
144
                        {
 
145
                                return float.Parse(val);
 
146
                        }
 
147
                        else if(tw == PrimitiveTypeWrapper.LONG)
 
148
                        {
 
149
                                return long.Parse(val);
 
150
                        }
 
151
                        else if(tw == PrimitiveTypeWrapper.DOUBLE)
 
152
                        {
 
153
                                return double.Parse(val);
 
154
                        }
 
155
                        else
 
156
                        {
 
157
                                throw new NotImplementedException();
 
158
                        }
 
159
                }
 
160
 
 
161
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, TypeBuilder tb, IKVM.Internal.MapXml.Attribute attr)
 
162
                {
 
163
                        bool declarativeSecurity;
 
164
                        CustomAttributeBuilder cab = CreateCustomAttribute(loader, attr, out declarativeSecurity);
 
165
                        if (declarativeSecurity)
 
166
                        {
 
167
                                tb.__AddDeclarativeSecurity(cab);
 
168
                        }
 
169
                        else
 
170
                        {
 
171
                                tb.SetCustomAttribute(cab);
 
172
                        }
 
173
                }
 
174
 
 
175
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, FieldBuilder fb, IKVM.Internal.MapXml.Attribute attr)
 
176
                {
 
177
                        fb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
 
178
                }
 
179
 
 
180
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, ParameterBuilder pb, IKVM.Internal.MapXml.Attribute attr)
 
181
                {
 
182
                        pb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
 
183
                }
 
184
 
 
185
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, MethodBuilder mb, IKVM.Internal.MapXml.Attribute attr)
 
186
                {
 
187
                        bool declarativeSecurity;
 
188
                        CustomAttributeBuilder cab = CreateCustomAttribute(loader, attr, out declarativeSecurity);
 
189
                        if (declarativeSecurity)
 
190
                        {
 
191
                                mb.__AddDeclarativeSecurity(cab);
 
192
                        }
 
193
                        else
 
194
                        {
 
195
                                mb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
 
196
                        }
 
197
                }
 
198
 
 
199
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, PropertyBuilder pb, IKVM.Internal.MapXml.Attribute attr)
 
200
                {
 
201
                        pb.SetCustomAttribute(CreateCustomAttribute(loader, attr));
 
202
                }
 
203
 
 
204
                internal static void SetCustomAttribute(ClassLoaderWrapper loader, AssemblyBuilder ab, IKVM.Internal.MapXml.Attribute attr)
 
205
                {
 
206
                        ab.SetCustomAttribute(CreateCustomAttribute(loader, attr));
 
207
                }
 
208
 
 
209
                private static void GetAttributeArgsAndTypes(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr, out Type[] argTypes, out object[] args)
 
210
                {
 
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++)
 
216
                        {
 
217
                                argTypes[i] = twargs[i].TypeAsSignatureType;
 
218
                                TypeWrapper tw = twargs[i];
 
219
                                if(tw == CoreClasses.java.lang.Object.Wrapper)
 
220
                                {
 
221
                                        tw = loader.FieldTypeWrapperFromSigNoThrow(attr.Params[i].Sig);
 
222
                                }
 
223
                                if(tw.IsArray)
 
224
                                {
 
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++)
 
227
                                        {
 
228
                                                arr.SetValue(ParseValue(loader, tw.ElementTypeWrapper, attr.Params[i].Elements[j].Value), j);
 
229
                                        }
 
230
                                        args[i] = arr;
 
231
                                }
 
232
                                else
 
233
                                {
 
234
                                        args[i] = ParseValue(loader, tw, attr.Params[i].Value);
 
235
                                }
 
236
                        }
 
237
                }
 
238
 
 
239
                private static CustomAttributeBuilder CreateCustomAttribute(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr)
 
240
                {
 
241
                        bool ignore;
 
242
                        return CreateCustomAttribute(loader, attr, out ignore);
 
243
                }
 
244
 
 
245
                private static CustomAttributeBuilder CreateCustomAttribute(ClassLoaderWrapper loader, IKVM.Internal.MapXml.Attribute attr, out bool isDeclarativeSecurity)
 
246
                {
 
247
                        // TODO add error handling
 
248
                        Type[] argTypes;
 
249
                        object[] args;
 
250
                        GetAttributeArgsAndTypes(loader, attr, out argTypes, out args);
 
251
                        if(attr.Type != null)
 
252
                        {
 
253
                                Type t = StaticCompiler.GetTypeForMapXml(loader, attr.Type);
 
254
                                isDeclarativeSecurity = t.IsSubclassOf(Types.SecurityAttribute);
 
255
                                ConstructorInfo ci = t.GetConstructor(argTypes);
 
256
                                if(ci == null)
 
257
                                {
 
258
                                        throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{1}", attr.Type, attr.Sig));
 
259
                                }
 
260
                                PropertyInfo[] namedProperties;
 
261
                                object[] propertyValues;
 
262
                                if(attr.Properties != null)
 
263
                                {
 
264
                                        namedProperties = new PropertyInfo[attr.Properties.Length];
 
265
                                        propertyValues = new object[attr.Properties.Length];
 
266
                                        for(int i = 0; i < namedProperties.Length; i++)
 
267
                                        {
 
268
                                                namedProperties[i] = t.GetProperty(attr.Properties[i].Name);
 
269
                                                propertyValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Properties[i].Sig), attr.Properties[i].Value);
 
270
                                        }
 
271
                                }
 
272
                                else
 
273
                                {
 
274
                                        namedProperties = new PropertyInfo[0];
 
275
                                        propertyValues = new object[0];
 
276
                                }
 
277
                                FieldInfo[] namedFields;
 
278
                                object[] fieldValues;
 
279
                                if(attr.Fields != null)
 
280
                                {
 
281
                                        namedFields = new FieldInfo[attr.Fields.Length];
 
282
                                        fieldValues = new object[attr.Fields.Length];
 
283
                                        for(int i = 0; i < namedFields.Length; i++)
 
284
                                        {
 
285
                                                namedFields[i] = t.GetField(attr.Fields[i].Name);
 
286
                                                fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Fields[i].Sig), attr.Fields[i].Value);
 
287
                                        }
 
288
                                }
 
289
                                else
 
290
                                {
 
291
                                        namedFields = new FieldInfo[0];
 
292
                                        fieldValues = new object[0];
 
293
                                }
 
294
                                return new CustomAttributeBuilder(ci, args, namedProperties, propertyValues, namedFields, fieldValues);
 
295
                        }
 
296
                        else
 
297
                        {
 
298
                                if(attr.Properties != null)
 
299
                                {
 
300
                                        throw new NotImplementedException("Setting property values on Java attributes is not implemented");
 
301
                                }
 
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)
 
307
                                {
 
308
                                        namedFields = new FieldInfo[attr.Fields.Length];
 
309
                                        fieldValues = new object[attr.Fields.Length];
 
310
                                        for(int i = 0; i < namedFields.Length; i++)
 
311
                                        {
 
312
                                                FieldWrapper fw = t.GetFieldWrapper(attr.Fields[i].Name, attr.Fields[i].Sig);
 
313
                                                fw.Link();
 
314
                                                namedFields[i] = fw.GetField();
 
315
                                                fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSigNoThrow(attr.Fields[i].Sig), attr.Fields[i].Value);
 
316
                                        }
 
317
                                }
 
318
                                else
 
319
                                {
 
320
                                        namedFields = new FieldInfo[0];
 
321
                                        fieldValues = new object[0];
 
322
                                }
 
323
                                MethodWrapper mw = t.GetMethodWrapper("<init>", attr.Sig, false);
 
324
                                if (mw == null)
 
325
                                {
 
326
                                        throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{1}", attr.Class, attr.Sig));
 
327
                                }
 
328
                                mw.Link();
 
329
                                ConstructorInfo ci = (mw.GetMethod() as ConstructorInfo) ?? ((MethodInfo)mw.GetMethod()).__AsConstructorInfo();
 
330
                                return new CustomAttributeBuilder(ci, args, namedFields, fieldValues);
 
331
                        }
 
332
                }
 
333
 
 
334
                private static Assembly GetSystemAssembly()
 
335
                {
 
336
                        AssemblyName name = Types.Object.Assembly.GetName();
 
337
                        name.Name = "System";
 
338
                        return StaticCompiler.Load(name.FullName);
 
339
                }
 
340
 
 
341
                private static CustomAttributeBuilder GetEditorBrowsableNever()
 
342
                {
 
343
                        if (editorBrowsableNever == null)
 
344
                        {
 
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 });
 
347
                        }
 
348
                        return editorBrowsableNever;
 
349
                }
 
350
 
 
351
                internal static void SetEditorBrowsableNever(TypeBuilder tb)
 
352
                {
 
353
                        tb.SetCustomAttribute(GetEditorBrowsableNever());
 
354
                }
 
355
 
 
356
                internal static void SetEditorBrowsableNever(MethodBuilder mb)
 
357
                {
 
358
                        mb.SetCustomAttribute(GetEditorBrowsableNever());
 
359
                }
 
360
 
 
361
                internal static void SetEditorBrowsableNever(PropertyBuilder pb)
 
362
                {
 
363
                        pb.SetCustomAttribute(GetEditorBrowsableNever());
 
364
                }
 
365
 
 
366
                internal static void SetDeprecatedAttribute(MethodBuilder mb)
 
367
                {
 
368
                        if(deprecatedAttribute == null)
 
369
                        {
 
370
                                deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
371
                        }
 
372
                        mb.SetCustomAttribute(deprecatedAttribute);
 
373
                }
 
374
 
 
375
                internal static void SetDeprecatedAttribute(TypeBuilder tb)
 
376
                {
 
377
                        if(deprecatedAttribute == null)
 
378
                        {
 
379
                                deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
380
                        }
 
381
                        tb.SetCustomAttribute(deprecatedAttribute);
 
382
                }
 
383
 
 
384
                internal static void SetDeprecatedAttribute(FieldBuilder fb)
 
385
                {
 
386
                        if(deprecatedAttribute == null)
 
387
                        {
 
388
                                deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
389
                        }
 
390
                        fb.SetCustomAttribute(deprecatedAttribute);
 
391
                }
 
392
 
 
393
                internal static void SetDeprecatedAttribute(PropertyBuilder pb)
 
394
                {
 
395
                        if(deprecatedAttribute == null)
 
396
                        {
 
397
                                deprecatedAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
398
                        }
 
399
                        pb.SetCustomAttribute(deprecatedAttribute);
 
400
                }
 
401
 
 
402
                internal static void SetThrowsAttribute(MethodBuilder mb, string[] exceptions)
 
403
                {
 
404
                        if(exceptions != null && exceptions.Length != 0)
 
405
                        {
 
406
                                if(throwsAttribute == null)
 
407
                                {
 
408
                                        throwsAttribute = typeofThrowsAttribute.GetConstructor(new Type[] { JVM.Import(typeof(string[])) });
 
409
                                }
 
410
                                mb.SetCustomAttribute(new CustomAttributeBuilder(throwsAttribute, new object[] { exceptions }));
 
411
                        }
 
412
                }
 
413
 
 
414
                internal static void SetGhostInterface(TypeBuilder typeBuilder)
 
415
                {
 
416
                        if(ghostInterfaceAttribute == null)
 
417
                        {
 
418
                                ghostInterfaceAttribute = new CustomAttributeBuilder(typeofGhostInterfaceAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
419
                        }
 
420
                        typeBuilder.SetCustomAttribute(ghostInterfaceAttribute);
 
421
                }
 
422
 
 
423
                internal static void SetNonNestedInnerClass(TypeBuilder typeBuilder, string className)
 
424
                {
 
425
                        if(nonNestedInnerClassAttribute == null)
 
426
                        {
 
427
                                nonNestedInnerClassAttribute = typeofNonNestedInnerClassAttribute.GetConstructor(new Type[] { Types.String });
 
428
                        }
 
429
                        typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedInnerClassAttribute, new object[] { className }));
 
430
                }
 
431
 
 
432
                internal static void SetNonNestedOuterClass(TypeBuilder typeBuilder, string className)
 
433
                {
 
434
                        if(nonNestedOuterClassAttribute == null)
 
435
                        {
 
436
                                nonNestedOuterClassAttribute = typeofNonNestedOuterClassAttribute.GetConstructor(new Type[] { Types.String });
 
437
                        }
 
438
                        typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedOuterClassAttribute, new object[] { className }));
 
439
                }
 
440
#endif // STATIC_COMPILER
 
441
 
 
442
                internal static void HideFromReflection(MethodBuilder mb)
 
443
                {
 
444
                        CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
445
                        mb.SetCustomAttribute(cab);
 
446
                }
 
447
 
 
448
                internal static void HideFromReflection(MethodBuilder mb, int reason)
 
449
                {
 
450
                        CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(new Type[] { Types.Int32 }), new object[] { reason });
 
451
                        mb.SetCustomAttribute(cab);
 
452
                }
 
453
 
 
454
                internal static void HideFromReflection(FieldBuilder fb)
 
455
                {
 
456
                        CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
457
                        fb.SetCustomAttribute(cab);
 
458
                }
 
459
 
 
460
                internal static void HideFromReflection(PropertyBuilder pb)
 
461
                {
 
462
                        CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofHideFromReflectionAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
463
                        pb.SetCustomAttribute(cab);
 
464
                }
 
465
 
 
466
                internal static bool IsHideFromReflection(MemberInfo mi)
 
467
                {
 
468
                        return mi.IsDefined(typeofHideFromReflectionAttribute, false);
 
469
                }
 
470
 
 
471
                internal static void HideFromJava(TypeBuilder typeBuilder)
 
472
                {
 
473
                        if(hideFromJavaAttribute == null)
 
474
                        {
 
475
                                hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
476
                        }
 
477
                        typeBuilder.SetCustomAttribute(hideFromJavaAttribute);
 
478
                }
 
479
 
 
480
                internal static void HideFromJava(MethodBuilder mb)
 
481
                {
 
482
                        if(hideFromJavaAttribute == null)
 
483
                        {
 
484
                                hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
485
                        }
 
486
                        mb.SetCustomAttribute(hideFromJavaAttribute);
 
487
                }
 
488
 
 
489
                internal static void HideFromJava(FieldBuilder fb)
 
490
                {
 
491
                        if(hideFromJavaAttribute == null)
 
492
                        {
 
493
                                hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
494
                        }
 
495
                        fb.SetCustomAttribute(hideFromJavaAttribute);
 
496
                }
 
497
 
 
498
#if STATIC_COMPILER
 
499
                internal static void HideFromJava(PropertyBuilder pb)
 
500
                {
 
501
                        if(hideFromJavaAttribute == null)
 
502
                        {
 
503
                                hideFromJavaAttribute = new CustomAttributeBuilder(typeofHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
504
                        }
 
505
                        pb.SetCustomAttribute(hideFromJavaAttribute);
 
506
                }
 
507
#endif // STATIC_COMPILER
 
508
 
 
509
                internal static bool IsHideFromJava(Type type)
 
510
                {
 
511
                        return type.IsDefined(typeofHideFromJavaAttribute, false)
 
512
                                || (type.IsNested && (type.DeclaringType.IsDefined(typeofHideFromJavaAttribute, false) || type.Name.StartsWith("__<", StringComparison.Ordinal)));
 
513
                }
 
514
 
 
515
                internal static bool IsHideFromJava(MemberInfo mi)
 
516
                {
 
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)
 
521
                        {
 
522
                                return true;
 
523
                        }
 
524
                        MethodBase mb = mi as MethodBase;
 
525
                        if(mb != null && (mb.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope)
 
526
                        {
 
527
                                return true;
 
528
                        }
 
529
                        if (mi.Name.StartsWith("__<", StringComparison.Ordinal))
 
530
                        {
 
531
                                return true;
 
532
                        }
 
533
                        return mi.IsDefined(typeofHideFromJavaAttribute, false);
 
534
                }
 
535
 
 
536
#if STATIC_COMPILER
 
537
                internal static void SetImplementsAttribute(TypeBuilder typeBuilder, TypeWrapper[] ifaceWrappers)
 
538
                {
 
539
                        if(ifaceWrappers != null && ifaceWrappers.Length != 0)
 
540
                        {
 
541
                                string[] interfaces = new string[ifaceWrappers.Length];
 
542
                                for(int i = 0; i < interfaces.Length; i++)
 
543
                                {
 
544
                                        interfaces[i] = ifaceWrappers[i].Name;
 
545
                                }
 
546
                                if(implementsAttribute == null)
 
547
                                {
 
548
                                        implementsAttribute = typeofImplementsAttribute.GetConstructor(new Type[] { JVM.Import(typeof(string[])) });
 
549
                                }
 
550
                                typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(implementsAttribute, new object[] { interfaces }));
 
551
                        }
 
552
                }
 
553
#endif
 
554
 
 
555
                internal static bool IsGhostInterface(Type type)
 
556
                {
 
557
                        return type.IsDefined(typeofGhostInterfaceAttribute, false);
 
558
                }
 
559
 
 
560
                internal static bool IsRemappedType(Type type)
 
561
                {
 
562
                        return type.IsDefined(typeofRemappedTypeAttribute, false);
 
563
                }
 
564
 
 
565
                internal static bool IsExceptionIsUnsafeForMapping(Type type)
 
566
                {
 
567
                        return type.IsDefined(typeofExceptionIsUnsafeForMappingAttribute, false);
 
568
                }
 
569
 
 
570
                internal static ModifiersAttribute GetModifiersAttribute(MemberInfo member)
 
571
                {
 
572
#if !STATIC_COMPILER && !STUB_GENERATOR
 
573
                        object[] attr = member.GetCustomAttributes(typeof(ModifiersAttribute), false);
 
574
                        return attr.Length == 1 ? (ModifiersAttribute)attr[0] : null;
 
575
#else
 
576
                        IList<CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(member, typeofModifiersAttribute, false);
 
577
                        if(attr.Count == 1)
 
578
                        {
 
579
                                IList<CustomAttributeTypedArgument> args = attr[0].ConstructorArguments;
 
580
                                if(args.Count == 2)
 
581
                                {
 
582
                                        return new ModifiersAttribute((Modifiers)args[0].Value, (bool)args[1].Value);
 
583
                                }
 
584
                                return new ModifiersAttribute((Modifiers)args[0].Value);
 
585
                        }
 
586
                        return null;
 
587
#endif
 
588
                }
 
589
 
 
590
                internal static ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate)
 
591
                {
 
592
                        ModifiersAttribute attr = GetModifiersAttribute(mb);
 
593
                        if(attr != null)
 
594
                        {
 
595
                                return new ExModifiers(attr.Modifiers, attr.IsInternal);
 
596
                        }
 
597
                        Modifiers modifiers = 0;
 
598
                        if(mb.IsPublic)
 
599
                        {
 
600
                                modifiers |= Modifiers.Public;
 
601
                        }
 
602
                        else if(mb.IsPrivate)
 
603
                        {
 
604
                                modifiers |= Modifiers.Private;
 
605
                        }
 
606
                        else if(mb.IsFamily || mb.IsFamilyOrAssembly)
 
607
                        {
 
608
                                modifiers |= Modifiers.Protected;
 
609
                        }
 
610
                        else if(assemblyIsPrivate)
 
611
                        {
 
612
                                modifiers |= Modifiers.Private;
 
613
                        }
 
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)
 
617
                        {
 
618
                                modifiers |= Modifiers.Final;
 
619
                        }
 
620
                        if(mb.IsAbstract)
 
621
                        {
 
622
                                modifiers |= Modifiers.Abstract;
 
623
                        }
 
624
                        else
 
625
                        {
 
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
 
628
                                // abstract methods.
 
629
                                if((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0)
 
630
                                {
 
631
                                        modifiers |= Modifiers.Synchronized;
 
632
                                }
 
633
                        }
 
634
                        if(mb.IsStatic)
 
635
                        {
 
636
                                modifiers |= Modifiers.Static;
 
637
                        }
 
638
                        if((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
 
639
                        {
 
640
                                modifiers |= Modifiers.Native;
 
641
                        }
 
642
                        ParameterInfo[] parameters = mb.GetParameters();
 
643
                        if(parameters.Length > 0 && parameters[parameters.Length - 1].IsDefined(JVM.Import(typeof(ParamArrayAttribute)), false))
 
644
                        {
 
645
                                modifiers |= Modifiers.VarArgs;
 
646
                        }
 
647
                        return new ExModifiers(modifiers, false);
 
648
                }
 
649
 
 
650
                internal static ExModifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate)
 
651
                {
 
652
                        ModifiersAttribute attr = GetModifiersAttribute(fi);
 
653
                        if(attr != null)
 
654
                        {
 
655
                                return new ExModifiers(attr.Modifiers, attr.IsInternal);
 
656
                        }
 
657
                        Modifiers modifiers = 0;
 
658
                        if(fi.IsPublic)
 
659
                        {
 
660
                                modifiers |= Modifiers.Public;
 
661
                        }
 
662
                        else if(fi.IsPrivate)
 
663
                        {
 
664
                                modifiers |= Modifiers.Private;
 
665
                        }
 
666
                        else if(fi.IsFamily || fi.IsFamilyOrAssembly)
 
667
                        {
 
668
                                modifiers |= Modifiers.Protected;
 
669
                        }
 
670
                        else if(assemblyIsPrivate)
 
671
                        {
 
672
                                modifiers |= Modifiers.Private;
 
673
                        }
 
674
                        if(fi.IsInitOnly || fi.IsLiteral)
 
675
                        {
 
676
                                modifiers |= Modifiers.Final;
 
677
                        }
 
678
                        if(fi.IsNotSerialized)
 
679
                        {
 
680
                                modifiers |= Modifiers.Transient;
 
681
                        }
 
682
                        if(fi.IsStatic)
 
683
                        {
 
684
                                modifiers |= Modifiers.Static;
 
685
                        }
 
686
                        if(Array.IndexOf(fi.GetRequiredCustomModifiers(), Types.IsVolatile) != -1)
 
687
                        {
 
688
                                modifiers |= Modifiers.Volatile;
 
689
                        }
 
690
                        return new ExModifiers(modifiers, false);
 
691
                }
 
692
 
 
693
#if STATIC_COMPILER
 
694
                internal static void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal)
 
695
                {
 
696
                        CustomAttributeBuilder customAttributeBuilder;
 
697
                        if (isInternal)
 
698
                        {
 
699
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
 
700
                        }
 
701
                        else
 
702
                        {
 
703
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
 
704
                        }
 
705
                        mb.SetCustomAttribute(customAttributeBuilder);
 
706
                }
 
707
 
 
708
                internal static void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal)
 
709
                {
 
710
                        CustomAttributeBuilder customAttributeBuilder;
 
711
                        if (isInternal)
 
712
                        {
 
713
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
 
714
                        }
 
715
                        else
 
716
                        {
 
717
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
 
718
                        }
 
719
                        fb.SetCustomAttribute(customAttributeBuilder);
 
720
                }
 
721
 
 
722
                internal static void SetModifiers(PropertyBuilder pb, Modifiers modifiers, bool isInternal)
 
723
                {
 
724
                        CustomAttributeBuilder customAttributeBuilder;
 
725
                        if (isInternal)
 
726
                        {
 
727
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
 
728
                        }
 
729
                        else
 
730
                        {
 
731
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
 
732
                        }
 
733
                        pb.SetCustomAttribute(customAttributeBuilder);
 
734
                }
 
735
 
 
736
                internal static void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal)
 
737
                {
 
738
                        CustomAttributeBuilder customAttributeBuilder;
 
739
                        if (isInternal)
 
740
                        {
 
741
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, Types.Boolean }), new object[] { modifiers, isInternal });
 
742
                        }
 
743
                        else
 
744
                        {
 
745
                                customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
 
746
                        }
 
747
                        tb.SetCustomAttribute(customAttributeBuilder);
 
748
                }
 
749
 
 
750
                internal static void SetNameSig(MethodBuilder mb, string name, string sig)
 
751
                {
 
752
                        CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofNameSigAttribute.GetConstructor(new Type[] { Types.String, Types.String }), new object[] { name, sig });
 
753
                        mb.SetCustomAttribute(customAttributeBuilder);
 
754
                }
 
755
 
 
756
                internal static byte[] FreezeDryType(Type type)
 
757
                {
 
758
                        System.IO.MemoryStream mem = new System.IO.MemoryStream();
 
759
                        System.IO.BinaryWriter bw = new System.IO.BinaryWriter(mem, System.Text.UTF8Encoding.UTF8);
 
760
                        bw.Write((short)1);
 
761
                        bw.Write(type.FullName);
 
762
                        bw.Write((short)0);
 
763
                        return mem.ToArray();
 
764
                }
 
765
 
 
766
                internal static void SetInnerClass(TypeBuilder typeBuilder, string innerClass, Modifiers modifiers)
 
767
                {
 
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);
 
773
                }
 
774
 
 
775
                internal static void SetSourceFile(TypeBuilder typeBuilder, string filename)
 
776
                {
 
777
                        if(sourceFileAttribute == null)
 
778
                        {
 
779
                                sourceFileAttribute = typeofSourceFileAttribute.GetConstructor(new Type[] { Types.String });
 
780
                        }
 
781
                        typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename }));
 
782
                }
 
783
 
 
784
                internal static void SetSourceFile(ModuleBuilder moduleBuilder, string filename)
 
785
                {
 
786
                        if(sourceFileAttribute == null)
 
787
                        {
 
788
                                sourceFileAttribute = typeofSourceFileAttribute.GetConstructor(new Type[] { Types.String });
 
789
                        }
 
790
                        moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename }));
 
791
                }
 
792
 
 
793
                internal static void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer)
 
794
                {
 
795
                        object arg;
 
796
                        ConstructorInfo con;
 
797
                        if(writer.Count == 1)
 
798
                        {
 
799
                                if(lineNumberTableAttribute2 == null)
 
800
                                {
 
801
                                        lineNumberTableAttribute2 = typeofLineNumberTableAttribute.GetConstructor(new Type[] { Types.UInt16 });
 
802
                                }
 
803
                                con = lineNumberTableAttribute2;
 
804
                                arg = (ushort)writer.LineNo;
 
805
                        }
 
806
                        else
 
807
                        {
 
808
                                if(lineNumberTableAttribute1 == null)
 
809
                                {
 
810
                                        lineNumberTableAttribute1 = typeofLineNumberTableAttribute.GetConstructor(new Type[] { JVM.Import(typeof(byte[])) });
 
811
                                }
 
812
                                con = lineNumberTableAttribute1;
 
813
                                arg = writer.ToArray();
 
814
                        }
 
815
                        mb.SetCustomAttribute(new CustomAttributeBuilder(con, new object[] { arg }));
 
816
                }
 
817
 
 
818
                internal static void SetEnclosingMethodAttribute(TypeBuilder tb, string className, string methodName, string methodSig)
 
819
                {
 
820
                        if(enclosingMethodAttribute == null)
 
821
                        {
 
822
                                enclosingMethodAttribute = typeofEnclosingMethodAttribute.GetConstructor(new Type[] { Types.String, Types.String, Types.String });
 
823
                        }
 
824
                        tb.SetCustomAttribute(new CustomAttributeBuilder(enclosingMethodAttribute, new object[] { className, methodName, methodSig }));
 
825
                }
 
826
 
 
827
                internal static void SetSignatureAttribute(TypeBuilder tb, string signature)
 
828
                {
 
829
                        if(signatureAttribute == null)
 
830
                        {
 
831
                                signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
 
832
                        }
 
833
                        tb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
 
834
                }
 
835
 
 
836
                internal static void SetSignatureAttribute(FieldBuilder fb, string signature)
 
837
                {
 
838
                        if(signatureAttribute == null)
 
839
                        {
 
840
                                signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
 
841
                        }
 
842
                        fb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
 
843
                }
 
844
 
 
845
                internal static void SetSignatureAttribute(MethodBuilder mb, string signature)
 
846
                {
 
847
                        if(signatureAttribute == null)
 
848
                        {
 
849
                                signatureAttribute = typeofSignatureAttribute.GetConstructor(new Type[] { Types.String });
 
850
                        }
 
851
                        mb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { signature }));
 
852
                }
 
853
 
 
854
                internal static void SetParamArrayAttribute(ParameterBuilder pb)
 
855
                {
 
856
                        if(paramArrayAttribute == null)
 
857
                        {
 
858
                                paramArrayAttribute = new CustomAttributeBuilder(JVM.Import(typeof(ParamArrayAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
859
                        }
 
860
                        pb.SetCustomAttribute(paramArrayAttribute);
 
861
                }
 
862
#endif  // STATIC_COMPILER
 
863
 
 
864
                internal static NameSigAttribute GetNameSig(MemberInfo member)
 
865
                {
 
866
#if !STATIC_COMPILER && !STUB_GENERATOR
 
867
                        object[] attr = member.GetCustomAttributes(typeof(NameSigAttribute), false);
 
868
                        return attr.Length == 1 ? (NameSigAttribute)attr[0] : null;
 
869
#else
 
870
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, typeofNameSigAttribute, false))
 
871
                        {
 
872
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
873
                                return new NameSigAttribute((string)args[0].Value, (string)args[1].Value);
 
874
                        }
 
875
                        return null;
 
876
#endif
 
877
                }
 
878
 
 
879
                internal static T[] DecodeArray<T>(CustomAttributeTypedArgument arg)
 
880
                {
 
881
                        IList<CustomAttributeTypedArgument> elems = (IList<CustomAttributeTypedArgument>)arg.Value;
 
882
                        T[] arr = new T[elems.Count];
 
883
                        for(int i = 0; i < arr.Length; i++)
 
884
                        {
 
885
                                arr[i] = (T)elems[i].Value;
 
886
                        }
 
887
                        return arr;
 
888
                }
 
889
 
 
890
                internal static ImplementsAttribute GetImplements(Type type)
 
891
                {
 
892
#if !STATIC_COMPILER && !STUB_GENERATOR
 
893
                        object[] attribs = type.GetCustomAttributes(typeof(ImplementsAttribute), false);
 
894
                        return attribs.Length == 1 ? (ImplementsAttribute)attribs[0] : null;
 
895
#else
 
896
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofImplementsAttribute, false))
 
897
                        {
 
898
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
899
                                return new ImplementsAttribute(DecodeArray<string>(args[0]));
 
900
                        }
 
901
                        return null;
 
902
#endif
 
903
                }
 
904
 
 
905
                internal static ThrowsAttribute GetThrows(MethodBase mb)
 
906
                {
 
907
#if !STATIC_COMPILER && !STUB_GENERATOR
 
908
                        object[] attribs = mb.GetCustomAttributes(typeof(ThrowsAttribute), false);
 
909
                        return attribs.Length == 1 ? (ThrowsAttribute)attribs[0] : null;
 
910
#else
 
911
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(mb, typeofThrowsAttribute, false))
 
912
                        {
 
913
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
914
                                if (args[0].ArgumentType == Types.String.MakeArrayType())
 
915
                                {
 
916
                                        return new ThrowsAttribute(DecodeArray<string>(args[0]));
 
917
                                }
 
918
                                else if (args[0].ArgumentType == Types.Type.MakeArrayType())
 
919
                                {
 
920
                                        return new ThrowsAttribute(DecodeArray<Type>(args[0]));
 
921
                                }
 
922
                                else
 
923
                                {
 
924
                                        return new ThrowsAttribute((Type)args[0].Value);
 
925
                                }
 
926
                        }
 
927
                        return null;
 
928
#endif
 
929
                }
 
930
 
 
931
                internal static string[] GetNonNestedInnerClasses(Type t)
 
932
                {
 
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++)
 
937
                        {
 
938
                                classes[i] = ((NonNestedInnerClassAttribute)attribs[i]).InnerClassName;
 
939
                        }
 
940
                        return classes;
 
941
#else
 
942
                        List<string> list = new List<string>();
 
943
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(t, typeofNonNestedInnerClassAttribute, false))
 
944
                        {
 
945
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
946
                                list.Add((string)args[0].Value);
 
947
                        }
 
948
                        return list.ToArray();
 
949
#endif
 
950
                }
 
951
 
 
952
                internal static string GetNonNestedOuterClasses(Type t)
 
953
                {
 
954
#if !STATIC_COMPILER && !STUB_GENERATOR
 
955
                        object[] attribs = t.GetCustomAttributes(typeof(NonNestedOuterClassAttribute), false);
 
956
                        return attribs.Length == 1 ? ((NonNestedOuterClassAttribute)attribs[0]).OuterClassName : null;
 
957
#else
 
958
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(t, typeofNonNestedOuterClassAttribute, false))
 
959
                        {
 
960
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
961
                                return (string)args[0].Value;
 
962
                        }
 
963
                        return null;
 
964
#endif
 
965
                }
 
966
 
 
967
                internal static SignatureAttribute GetSignature(MemberInfo member)
 
968
                {
 
969
#if !STATIC_COMPILER && !STUB_GENERATOR
 
970
                        object[] attribs = member.GetCustomAttributes(typeof(SignatureAttribute), false);
 
971
                        return attribs.Length == 1 ? (SignatureAttribute)attribs[0] : null;
 
972
#else
 
973
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, typeofSignatureAttribute, false))
 
974
                        {
 
975
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
976
                                return new SignatureAttribute((string)args[0].Value);
 
977
                        }
 
978
                        return null;
 
979
#endif
 
980
                }
 
981
 
 
982
                internal static InnerClassAttribute GetInnerClass(Type type)
 
983
                {
 
984
#if !STATIC_COMPILER && !STUB_GENERATOR
 
985
                        object[] attribs = type.GetCustomAttributes(typeof(InnerClassAttribute), false);
 
986
                        return attribs.Length == 1 ? (InnerClassAttribute)attribs[0] : null;
 
987
#else
 
988
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofInnerClassAttribute, false))
 
989
                        {
 
990
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
991
                                return new InnerClassAttribute((string)args[0].Value, (Modifiers)args[1].Value);
 
992
                        }
 
993
                        return null;
 
994
#endif
 
995
                }
 
996
 
 
997
                internal static RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(Type type)
 
998
                {
 
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);
 
1003
                        return attr1;
 
1004
#else
 
1005
                        List<RemappedInterfaceMethodAttribute> attrs = new List<RemappedInterfaceMethodAttribute>();
 
1006
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofRemappedInterfaceMethodAttribute, false))
 
1007
                        {
 
1008
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
1009
                                attrs.Add(new RemappedInterfaceMethodAttribute((string)args[0].Value, (string)args[1].Value, DecodeArray<string>(args[2])));
 
1010
                        }
 
1011
                        return attrs.ToArray();
 
1012
#endif
 
1013
                }
 
1014
 
 
1015
                internal static RemappedTypeAttribute GetRemappedType(Type type)
 
1016
                {
 
1017
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1018
                        object[] attribs = type.GetCustomAttributes(typeof(RemappedTypeAttribute), false);
 
1019
                        return attribs.Length == 1 ? (RemappedTypeAttribute)attribs[0] : null;
 
1020
#else
 
1021
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofRemappedTypeAttribute, false))
 
1022
                        {
 
1023
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
1024
                                return new RemappedTypeAttribute((Type)args[0].Value);
 
1025
                        }
 
1026
                        return null;
 
1027
#endif
 
1028
                }
 
1029
 
 
1030
                internal static RemappedClassAttribute[] GetRemappedClasses(Assembly coreAssembly)
 
1031
                {
 
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);
 
1036
                        return attr1;
 
1037
#else
 
1038
                        List<RemappedClassAttribute> attrs = new List<RemappedClassAttribute>();
 
1039
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(coreAssembly, typeofRemappedClassAttribute, false))
 
1040
                        {
 
1041
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
1042
                                attrs.Add(new RemappedClassAttribute((string)args[0].Value, (Type)args[1].Value));
 
1043
                        }
 
1044
                        return attrs.ToArray();
 
1045
#endif
 
1046
                }
 
1047
 
 
1048
                internal static string GetAnnotationAttributeType(Type type)
 
1049
                {
 
1050
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1051
                        object[] attr = type.GetCustomAttributes(typeof(AnnotationAttributeAttribute), false);
 
1052
                        if(attr.Length == 1)
 
1053
                        {
 
1054
                                return ((AnnotationAttributeAttribute)attr[0]).AttributeType;
 
1055
                        }
 
1056
                        return null;
 
1057
#else
 
1058
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofAnnotationAttributeAttribute, false))
 
1059
                        {
 
1060
                                return (string)cad.ConstructorArguments[0].Value;
 
1061
                        }
 
1062
                        return null;
 
1063
#endif
 
1064
                }
 
1065
 
 
1066
                internal static AssemblyName[] GetInternalsVisibleToAttributes(Assembly assembly)
 
1067
                {
 
1068
                        List<AssemblyName> list = new List<AssemblyName>();
 
1069
                        foreach(CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(assembly))
 
1070
                        {
 
1071
                                if(cad.Constructor.DeclaringType == JVM.Import(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute)))
 
1072
                                {
 
1073
                                        try
 
1074
                                        {
 
1075
                                                list.Add(new AssemblyName((string)cad.ConstructorArguments[0].Value));
 
1076
                                        }
 
1077
                                        catch
 
1078
                                        {
 
1079
                                                // HACK since there is no list of exception that the AssemblyName constructor can throw, we simply catch all
 
1080
                                        }
 
1081
                                }
 
1082
                        }
 
1083
                        return list.ToArray();
 
1084
                }
 
1085
 
 
1086
                internal static bool IsJavaModule(Module mod)
 
1087
                {
 
1088
                        return mod.IsDefined(typeofJavaModuleAttribute, false);
 
1089
                }
 
1090
 
 
1091
                internal static object[] GetJavaModuleAttributes(Module mod)
 
1092
                {
 
1093
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1094
                        return mod.GetCustomAttributes(typeofJavaModuleAttribute, false);
 
1095
#else
 
1096
                        List<JavaModuleAttribute> attrs = new List<JavaModuleAttribute>();
 
1097
                        foreach(CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(mod, typeofJavaModuleAttribute, false))
 
1098
                        {
 
1099
                                IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
1100
                                if(args.Count == 0)
 
1101
                                {
 
1102
                                        attrs.Add(new JavaModuleAttribute());
 
1103
                                }
 
1104
                                else
 
1105
                                {
 
1106
                                        attrs.Add(new JavaModuleAttribute(DecodeArray<string>(args[0])));
 
1107
                                }
 
1108
                        }
 
1109
                        return attrs.ToArray();
 
1110
#endif
 
1111
                }
 
1112
 
 
1113
                internal static bool IsNoPackagePrefix(Type type)
 
1114
                {
 
1115
                        return type.IsDefined(typeofNoPackagePrefixAttribute, false) || type.Assembly.IsDefined(typeofNoPackagePrefixAttribute, false);
 
1116
                }
 
1117
 
 
1118
                internal static EnclosingMethodAttribute GetEnclosingMethodAttribute(Type type)
 
1119
                {
 
1120
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1121
                        object[] attr = type.GetCustomAttributes(typeof(EnclosingMethodAttribute), false);
 
1122
                        if (attr.Length == 1)
 
1123
                        {
 
1124
                                return (EnclosingMethodAttribute)attr[0];
 
1125
                        }
 
1126
                        return null;
 
1127
#else
 
1128
                        foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, typeofEnclosingMethodAttribute, false))
 
1129
                        {
 
1130
                                return new EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value);
 
1131
                        }
 
1132
                        return null;
 
1133
#endif
 
1134
                }
 
1135
 
 
1136
#if STATIC_COMPILER
 
1137
                internal static void SetRemappedClass(AssemblyBuilder assemblyBuilder, string name, Type shadowType)
 
1138
                {
 
1139
                        ConstructorInfo remappedClassAttribute = typeofRemappedClassAttribute.GetConstructor(new Type[] { Types.String, Types.Type });
 
1140
                        assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedClassAttribute, new object[] { name, shadowType }));
 
1141
                }
 
1142
 
 
1143
                internal static void SetRemappedType(TypeBuilder typeBuilder, Type shadowType)
 
1144
                {
 
1145
                        ConstructorInfo remappedTypeAttribute = typeofRemappedTypeAttribute.GetConstructor(new Type[] { Types.Type });
 
1146
                        typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedTypeAttribute, new object[] { shadowType }));
 
1147
                }
 
1148
 
 
1149
                internal static void SetRemappedInterfaceMethod(TypeBuilder typeBuilder, string name, string mappedTo, string[] throws)
 
1150
                {
 
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);
 
1153
                }
 
1154
 
 
1155
                internal static void SetExceptionIsUnsafeForMapping(TypeBuilder typeBuilder)
 
1156
                {
 
1157
                        CustomAttributeBuilder cab = new CustomAttributeBuilder(typeofExceptionIsUnsafeForMappingAttribute.GetConstructor(Type.EmptyTypes), new object[0]);
 
1158
                        typeBuilder.SetCustomAttribute(cab);
 
1159
                }
 
1160
#endif // STATIC_COMPILER
 
1161
 
 
1162
                internal static void SetRuntimeCompatibilityAttribute(AssemblyBuilder assemblyBuilder)
 
1163
                {
 
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]));
 
1169
                }
 
1170
        }
 
1171
 
 
1172
        static class EnumHelper
 
1173
        {
 
1174
                internal static Type GetUnderlyingType(Type enumType)
 
1175
                {
 
1176
#if STATIC_COMPILER || STUB_GENERATOR
 
1177
                        return enumType.GetEnumUnderlyingType();
 
1178
#else
 
1179
                        return Enum.GetUnderlyingType(enumType);
 
1180
#endif
 
1181
                }
 
1182
 
 
1183
#if STATIC_COMPILER
 
1184
                internal static object Parse(Type type, string value)
 
1185
                {
 
1186
                        object retval = null;
 
1187
                        foreach (string str in value.Split(','))
 
1188
                        {
 
1189
                                FieldInfo field = type.GetField(str.Trim(), BindingFlags.Public | BindingFlags.Static);
 
1190
                                if (field == null)
 
1191
                                {
 
1192
                                        throw new InvalidOperationException("Enum value '" + str + "' not found in " + type.FullName);
 
1193
                                }
 
1194
                                if (retval == null)
 
1195
                                {
 
1196
                                        retval = field.GetRawConstantValue();
 
1197
                                }
 
1198
                                else
 
1199
                                {
 
1200
                                        retval = OrBoxedIntegrals(retval, field.GetRawConstantValue());
 
1201
                                }
 
1202
                        }
 
1203
                        return retval;
 
1204
                }
 
1205
#endif
 
1206
 
 
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)
 
1210
                {
 
1211
                        Debug.Assert(v1.GetType() == v2.GetType());
 
1212
                        if (v1 is ulong)
 
1213
                        {
 
1214
                                ulong l1 = (ulong)v1;
 
1215
                                ulong l2 = (ulong)v2;
 
1216
                                return l1 | l2;
 
1217
                        }
 
1218
                        else
 
1219
                        {
 
1220
                                long v = ((IConvertible)v1).ToInt64(null) | ((IConvertible)v2).ToInt64(null);
 
1221
                                switch (Type.GetTypeCode(JVM.Import(v1.GetType())))
 
1222
                                {
 
1223
                                        case TypeCode.SByte:
 
1224
                                                return (sbyte)v;
 
1225
                                        case TypeCode.Byte:
 
1226
                                                return (byte)v;
 
1227
                                        case TypeCode.Int16:
 
1228
                                                return (short)v;
 
1229
                                        case TypeCode.UInt16:
 
1230
                                                return (ushort)v;
 
1231
                                        case TypeCode.Int32:
 
1232
                                                return (int)v;
 
1233
                                        case TypeCode.UInt32:
 
1234
                                                return (uint)v;
 
1235
                                        case TypeCode.Int64:
 
1236
                                                return (long)v;
 
1237
                                        default:
 
1238
                                                throw new InvalidOperationException();
 
1239
                                }
 
1240
                        }
 
1241
                }
 
1242
 
 
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)
 
1245
                {
 
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).
 
1249
                        long value;
 
1250
                        if (obj is ulong || (obj is Enum && underlyingType == Types.UInt64))
 
1251
                        {
 
1252
                                value = unchecked((long)((IConvertible)obj).ToUInt64(null));
 
1253
                        }
 
1254
                        else
 
1255
                        {
 
1256
                                value = ((IConvertible)obj).ToInt64(null);
 
1257
                        }
 
1258
                        if (underlyingType == Types.SByte || underlyingType == Types.Byte)
 
1259
                        {
 
1260
                                return unchecked((byte)value);
 
1261
                        }
 
1262
                        else if (underlyingType == Types.Int16 || underlyingType == Types.UInt16)
 
1263
                        {
 
1264
                                return unchecked((short)value);
 
1265
                        }
 
1266
                        else if (underlyingType == Types.Int32 || underlyingType == Types.UInt32)
 
1267
                        {
 
1268
                                return unchecked((int)value);
 
1269
                        }
 
1270
                        else if (underlyingType == Types.Int64 || underlyingType == Types.UInt64)
 
1271
                        {
 
1272
                                return value;
 
1273
                        }
 
1274
                        else
 
1275
                        {
 
1276
                                throw new InvalidOperationException();
 
1277
                        }
 
1278
                }
 
1279
        }
 
1280
 
 
1281
        static class TypeNameUtil
 
1282
        {
 
1283
                // note that MangleNestedTypeName() assumes that there are less than 16 special characters
 
1284
                private const string specialCharactersString = "\\+,[]*&\u0000";
 
1285
 
 
1286
                internal static string ReplaceIllegalCharacters(string name)
 
1287
                {
 
1288
                        // only the NUL character is illegal in CLR type names, so we replace it with a space
 
1289
                        return name.Replace('\u0000', ' ');
 
1290
                }
 
1291
 
 
1292
                internal static string Unescape(string name)
 
1293
                {
 
1294
                        int pos = name.IndexOf('\\');
 
1295
                        if (pos == -1)
 
1296
                        {
 
1297
                                return name;
 
1298
                        }
 
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++)
 
1302
                        {
 
1303
                                char c = name[i];
 
1304
                                if (c == '\\')
 
1305
                                {
 
1306
                                        c = name[++i];
 
1307
                                }
 
1308
                                sb.Append(c);
 
1309
                        }
 
1310
                        return sb.ToString();
 
1311
                }
 
1312
 
 
1313
                internal static string MangleNestedTypeName(string name)
 
1314
                {
 
1315
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
 
1316
                        foreach (char c in name)
 
1317
                        {
 
1318
                                int index = specialCharactersString.IndexOf(c);
 
1319
                                if (c == '.')
 
1320
                                {
 
1321
                                        sb.Append("_");
 
1322
                                }
 
1323
                                else if (c == '_')
 
1324
                                {
 
1325
                                        sb.Append("^-");
 
1326
                                }
 
1327
                                else if (index == -1)
 
1328
                                {
 
1329
                                        sb.Append(c);
 
1330
                                        if (c == '^')
 
1331
                                        {
 
1332
                                                sb.Append(c);
 
1333
                                        }
 
1334
                                }
 
1335
                                else
 
1336
                                {
 
1337
                                        sb.Append('^').AppendFormat("{0:X1}", index);
 
1338
                                }
 
1339
                        }
 
1340
                        return sb.ToString();
 
1341
                }
 
1342
 
 
1343
                internal static string UnmangleNestedTypeName(string name)
 
1344
                {
 
1345
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
 
1346
                        for (int i = 0; i < name.Length; i++)
 
1347
                        {
 
1348
                                char c = name[i];
 
1349
                                int index = specialCharactersString.IndexOf(c);
 
1350
                                if (c == '_')
 
1351
                                {
 
1352
                                        sb.Append('.');
 
1353
                                }
 
1354
                                else if (c == '^')
 
1355
                                {
 
1356
                                        c = name[++i];
 
1357
                                        if (c == '-')
 
1358
                                        {
 
1359
                                                sb.Append('_');
 
1360
                                        }
 
1361
                                        else if (c == '^')
 
1362
                                        {
 
1363
                                                sb.Append('^');
 
1364
                                        }
 
1365
                                        else
 
1366
                                        {
 
1367
                                                sb.Append(specialCharactersString[c - '0']);
 
1368
                                        }
 
1369
                                }
 
1370
                                else
 
1371
                                {
 
1372
                                        sb.Append(c);
 
1373
                                }
 
1374
                        }
 
1375
                        return sb.ToString();
 
1376
                }
 
1377
        }
 
1378
 
 
1379
        abstract class Annotation
 
1380
        {
 
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)
 
1384
                {
 
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;"))
 
1391
                        {
 
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)
 
1394
                                return null;
 
1395
                        }
 
1396
#endif
 
1397
                        try
 
1398
                        {
 
1399
                                TypeWrapper annot = loader.RetTypeWrapperFromSig(annotationClass.Replace('/', '.'));
 
1400
                                return annot.Annotation;
 
1401
                        }
 
1402
#if STATIC_COMPILER
 
1403
                        catch(ClassNotFoundException x)
 
1404
                        {
 
1405
                                loader.IssueMessage(Message.ClassNotFound, x.Message);
 
1406
                                return null;
 
1407
                        }
 
1408
#endif
 
1409
                        catch (RetargetableJavaException)
 
1410
                        {
 
1411
                                Tracer.Warning(Tracer.Compiler, "Unable to load annotation class {0}", annotationClass);
 
1412
                                return null;
 
1413
                        }
 
1414
                }
 
1415
 
 
1416
                private static object LookupEnumValue(Type enumType, string value)
 
1417
                {
 
1418
                        FieldInfo field = enumType.GetField(value, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
 
1419
                        if(field != null)
 
1420
                        {
 
1421
                                return field.GetRawConstantValue();
 
1422
                        }
 
1423
                        // both __unspecified and missing values end up here
 
1424
                        return EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(enumType), 0);
 
1425
                }
 
1426
 
 
1427
                protected static object ConvertValue(ClassLoaderWrapper loader, Type targetType, object obj)
 
1428
                {
 
1429
                        if(targetType.IsEnum)
 
1430
                        {
 
1431
                                // TODO check the obj descriptor matches the type we expect
 
1432
                                if(((object[])obj)[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY))
 
1433
                                {
 
1434
                                        object[] arr = (object[])obj;
 
1435
                                        object value = null;
 
1436
                                        for(int i = 1; i < arr.Length; i++)
 
1437
                                        {
 
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);
 
1441
                                                if (value == null)
 
1442
                                                {
 
1443
                                                        value = newval;
 
1444
                                                }
 
1445
                                                else
 
1446
                                                {
 
1447
                                                        value = EnumHelper.OrBoxedIntegrals(value, newval);
 
1448
                                                }
 
1449
                                        }
 
1450
                                        return value;
 
1451
                                }
 
1452
                                else
 
1453
                                {
 
1454
                                        string s = ((object[])obj)[2].ToString();
 
1455
                                        if(s == "__unspecified")
 
1456
                                        {
 
1457
                                                // TODO we should probably return null and handle that
 
1458
                                        }
 
1459
                                        return LookupEnumValue(targetType, s);
 
1460
                                }
 
1461
                        }
 
1462
                        else if(targetType == Types.Type)
 
1463
                        {
 
1464
                                // TODO check the obj descriptor matches the type we expect
 
1465
                                return loader.FieldTypeWrapperFromSig(((string)((object[])obj)[1]).Replace('/', '.')).TypeAsTBD;
 
1466
                        }
 
1467
                        else if(targetType.IsArray)
 
1468
                        {
 
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++)
 
1474
                                {
 
1475
                                        targetArray[i - 1] = ConvertValue(loader, elementType, arr[i]);
 
1476
                                }
 
1477
                                return targetArray;
 
1478
                        }
 
1479
                        else
 
1480
                        {
 
1481
                                return obj;
 
1482
                        }
 
1483
                }
 
1484
 
 
1485
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1486
                internal static bool MakeDeclSecurity(Type type, object annotation, out SecurityAction action, out PermissionSet permSet)
 
1487
                {
 
1488
                        ConstructorInfo ci = type.GetConstructor(new Type[] { typeof(SecurityAction) });
 
1489
                        if (ci == null)
 
1490
                        {
 
1491
                                // TODO should we support HostProtectionAttribute? (which has a no-arg constructor)
 
1492
                                // TODO issue message?
 
1493
                                action = 0;
 
1494
                                permSet = null;
 
1495
                                return false;
 
1496
                        }
 
1497
                        SecurityAttribute attr = null;
 
1498
                        object[] arr = (object[])annotation;
 
1499
                        for (int i = 2; i < arr.Length; i += 2)
 
1500
                        {
 
1501
                                string name = (string)arr[i];
 
1502
                                if (name == "value")
 
1503
                                {
 
1504
                                        attr = (SecurityAttribute)ci.Invoke(new object[] { ConvertValue(null, typeof(SecurityAction), arr[i + 1]) });
 
1505
                                }
 
1506
                        }
 
1507
                        if (attr == null)
 
1508
                        {
 
1509
                                // TODO issue message?
 
1510
                                action = 0;
 
1511
                                permSet = null;
 
1512
                                return false;
 
1513
                        }
 
1514
                        for (int i = 2; i < arr.Length; i += 2)
 
1515
                        {
 
1516
                                string name = (string)arr[i];
 
1517
                                if (name != "value")
 
1518
                                {
 
1519
                                        PropertyInfo pi = type.GetProperty(name);
 
1520
                                        pi.SetValue(attr, ConvertValue(null, pi.PropertyType, arr[i + 1]), null);
 
1521
                                }
 
1522
                        }
 
1523
                        action = attr.Action;
 
1524
                        permSet = new PermissionSet(PermissionState.None);
 
1525
                        permSet.AddPermission(attr.CreatePermission());
 
1526
                        return true;
 
1527
                }
 
1528
#endif // !STATIC_COMPILER && !STUB_GENERATOR
 
1529
 
 
1530
                internal static bool HasRetentionPolicyRuntime(object[] annotations)
 
1531
                {
 
1532
                        if(annotations != null)
 
1533
                        {
 
1534
                                foreach(object[] def in annotations)
 
1535
                                {
 
1536
                                        if(def[1].Equals("Ljava/lang/annotation/Retention;"))
 
1537
                                        {
 
1538
                                                for(int i = 2; i < def.Length; i += 2)
 
1539
                                                {
 
1540
                                                        if(def[i].Equals("value"))
 
1541
                                                        {
 
1542
                                                                object[] val = def[i + 1] as object[];
 
1543
                                                                if(val != null
 
1544
                                                                        && val.Length == 3
 
1545
                                                                        && val[0].Equals(AnnotationDefaultAttribute.TAG_ENUM)
 
1546
                                                                        && val[1].Equals("Ljava/lang/annotation/RetentionPolicy;")
 
1547
                                                                        && val[2].Equals("RUNTIME"))
 
1548
                                                                {
 
1549
                                                                        return true;
 
1550
                                                                }
 
1551
                                                        }
 
1552
                                                }
 
1553
                                        }
 
1554
                                }
 
1555
                        }
 
1556
                        return false;
 
1557
                }
 
1558
 
 
1559
                protected static object QualifyClassNames(ClassLoaderWrapper loader, object annotation)
 
1560
                {
 
1561
                        bool copy = false;
 
1562
                        object[] def = (object[])annotation;
 
1563
                        for(int i = 3; i < def.Length; i += 2)
 
1564
                        {
 
1565
                                object[] val = def[i] as object[];
 
1566
                                if(val != null)
 
1567
                                {
 
1568
                                        object[] newval = ValueQualifyClassNames(loader, val);
 
1569
                                        if(newval != val)
 
1570
                                        {
 
1571
                                                if(!copy)
 
1572
                                                {
 
1573
                                                        copy = true;
 
1574
                                                        object[] newdef = new object[def.Length];
 
1575
                                                        Array.Copy(def, newdef, def.Length);
 
1576
                                                        def = newdef;
 
1577
                                                }
 
1578
                                                def[i] = newval;
 
1579
                                        }
 
1580
                                }
 
1581
                        }
 
1582
                        return def;
 
1583
                }
 
1584
 
 
1585
                private static object[] ValueQualifyClassNames(ClassLoaderWrapper loader, object[] val)
 
1586
                {
 
1587
                        if(val[0].Equals(AnnotationDefaultAttribute.TAG_ANNOTATION))
 
1588
                        {
 
1589
                                return (object[])QualifyClassNames(loader, val);
 
1590
                        }
 
1591
                        else if(val[0].Equals(AnnotationDefaultAttribute.TAG_CLASS))
 
1592
                        {
 
1593
                                string sig = (string)val[1];
 
1594
                                if(sig.StartsWith("L"))
 
1595
                                {
 
1596
                                        TypeWrapper tw = loader.LoadClassByDottedNameFast(sig.Substring(1, sig.Length - 2).Replace('/', '.'));
 
1597
                                        if(tw != null)
 
1598
                                        {
 
1599
                                                return new object[] { AnnotationDefaultAttribute.TAG_CLASS, "L" + tw.TypeAsBaseType.AssemblyQualifiedName.Replace('.', '/') + ";" };
 
1600
                                        }
 
1601
                                }
 
1602
                                return val;
 
1603
                        }
 
1604
                        else if(val[0].Equals(AnnotationDefaultAttribute.TAG_ENUM))
 
1605
                        {
 
1606
                                string sig = (string)val[1];
 
1607
                                TypeWrapper tw = loader.LoadClassByDottedNameFast(sig.Substring(1, sig.Length - 2).Replace('/', '.'));
 
1608
                                if(tw != null)
 
1609
                                {
 
1610
                                        return new object[] { AnnotationDefaultAttribute.TAG_ENUM, "L" + tw.TypeAsBaseType.AssemblyQualifiedName.Replace('.', '/') + ";", val[2] };
 
1611
                                }
 
1612
                                return val;
 
1613
                        }
 
1614
                        else if(val[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY))
 
1615
                        {
 
1616
                                bool copy = false;
 
1617
                                for(int i = 1; i < val.Length; i++)
 
1618
                                {
 
1619
                                        object[] nval = val[i] as object[];
 
1620
                                        if(nval != null)
 
1621
                                        {
 
1622
                                                object newnval = ValueQualifyClassNames(loader, nval);
 
1623
                                                if(newnval != nval)
 
1624
                                                {
 
1625
                                                        if(!copy)
 
1626
                                                        {
 
1627
                                                                copy = true;
 
1628
                                                                object[] newval = new object[val.Length];
 
1629
                                                                Array.Copy(val, newval, val.Length);
 
1630
                                                                val = newval;
 
1631
                                                        }
 
1632
                                                        val[i] = newnval;
 
1633
                                                }
 
1634
                                        }
 
1635
                                }
 
1636
                                return val;
 
1637
                        }
 
1638
                        else
 
1639
                        {
 
1640
                                throw new InvalidOperationException();
 
1641
                        }
 
1642
                }
 
1643
 
 
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);
 
1650
 
 
1651
                internal virtual void ApplyReturnValue(ClassLoaderWrapper loader, MethodBuilder mb, ref ParameterBuilder pb, object annotation)
 
1652
                {
 
1653
                }
 
1654
 
 
1655
                internal abstract bool IsCustomAttribute { get; }
 
1656
        }
 
1657
 
 
1658
        [Flags]
 
1659
        enum TypeFlags : ushort
 
1660
        {
 
1661
                HasIncompleteInterfaceImplementation = 1,
 
1662
                InternalAccess = 2,
 
1663
                HasStaticInitializer = 4,
 
1664
                VerifyError = 8,
 
1665
                ClassFormatError = 16,
 
1666
                HasUnsupportedAbstractMethods = 32,
 
1667
        }
 
1668
 
 
1669
        static class NamePrefix
 
1670
        {
 
1671
                internal const string Type2AccessStubBackingField = "__<>";
 
1672
                internal const string AccessStub = "<accessstub>";
 
1673
                internal const string NonVirtual = "<nonvirtual>";
 
1674
                internal const string Bridge = "<bridge>";
 
1675
        }
 
1676
 
 
1677
        internal abstract class TypeWrapper
 
1678
        {
 
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;
 
1686
#endif
 
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;
 
1690
 
 
1691
                internal TypeWrapper(Modifiers modifiers, string name)
 
1692
                {
 
1693
                        Profiler.Count("TypeWrapper");
 
1694
                        // class name should be dotted or null for primitives
 
1695
                        Debug.Assert(name == null || name.IndexOf('/') < 0);
 
1696
 
 
1697
                        this.modifiers = modifiers;
 
1698
                        this.name = name == null ? null : String.Intern(name);
 
1699
                }
 
1700
 
 
1701
#if !STUB_GENERATOR
 
1702
                internal void EmitClassLiteral(CodeEmitter ilgen)
 
1703
                {
 
1704
                        Debug.Assert(!this.IsPrimitive);
 
1705
 
 
1706
                        Type type = GetClassLiteralType();
 
1707
 
 
1708
                        // note that this has to be the same check as in LazyInitClass
 
1709
                        if (!this.IsFastClassLiteralSafe || IsForbiddenTypeParameterType(type))
 
1710
                        {
 
1711
                                int rank = 0;
 
1712
                                while (ReflectUtil.IsVector(type))
 
1713
                                {
 
1714
                                        rank++;
 
1715
                                        type = type.GetElementType();
 
1716
                                }
 
1717
                                if (rank == 0)
 
1718
                                {
 
1719
                                        ilgen.Emit(OpCodes.Ldtoken, type);
 
1720
                                        Compiler.getClassFromTypeHandle.EmitCall(ilgen);
 
1721
                                }
 
1722
                                else
 
1723
                                {
 
1724
                                        ilgen.Emit(OpCodes.Ldtoken, type);
 
1725
                                        ilgen.EmitLdc_I4(rank);
 
1726
                                        Compiler.getClassFromTypeHandle2.EmitCall(ilgen);
 
1727
                                }
 
1728
                        }
 
1729
                        else
 
1730
                        {
 
1731
                                ilgen.Emit(OpCodes.Ldsfld, RuntimeHelperTypes.GetClassLiteralField(type));
 
1732
                        }
 
1733
                }
 
1734
#endif // !STUB_GENERATOR
 
1735
 
 
1736
                private Type GetClassLiteralType()
 
1737
                {
 
1738
                        Debug.Assert(!this.IsPrimitive);
 
1739
 
 
1740
                        TypeWrapper tw = this;
 
1741
                        if (tw.IsGhostArray)
 
1742
                        {
 
1743
                                int rank = tw.ArrayRank;
 
1744
                                while (tw.IsArray)
 
1745
                                {
 
1746
                                        tw = tw.ElementTypeWrapper;
 
1747
                                }
 
1748
                                return ArrayTypeWrapper.MakeArrayType(tw.TypeAsTBD, rank);
 
1749
                        }
 
1750
                        else
 
1751
                        {
 
1752
                                return tw.IsRemapped ? tw.TypeAsBaseType : tw.TypeAsTBD;
 
1753
                        }
 
1754
                }
 
1755
 
 
1756
                private static bool IsForbiddenTypeParameterType(Type type)
 
1757
                {
 
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
 
1764
                                || type.IsByRef;
 
1765
                }
 
1766
 
 
1767
                internal virtual bool IsFastClassLiteralSafe
 
1768
                {
 
1769
                        get { return false; }
 
1770
                }
 
1771
 
 
1772
#if !STATIC_COMPILER && !STUB_GENERATOR
 
1773
                internal void SetClassObject(java.lang.Class classObject)
 
1774
                {
 
1775
                        this.classObject = classObject;
 
1776
                }
 
1777
 
 
1778
                internal java.lang.Class ClassObject
 
1779
                {
 
1780
                        get
 
1781
                        {
 
1782
                                Debug.Assert(!IsUnloadable && !IsVerifierType);
 
1783
                                if (classObject == null)
 
1784
                                {
 
1785
                                        LazyInitClass();
 
1786
                                }
 
1787
                                return classObject;
 
1788
                        }
 
1789
                }
 
1790
 
 
1791
#if !FIRST_PASS
 
1792
                private java.lang.Class GetPrimitiveClass()
 
1793
                {
 
1794
                        if (this == PrimitiveTypeWrapper.BYTE)
 
1795
                        {
 
1796
                                return java.lang.Byte.TYPE;
 
1797
                        }
 
1798
                        else if (this == PrimitiveTypeWrapper.CHAR)
 
1799
                        {
 
1800
                                return java.lang.Character.TYPE;
 
1801
                        }
 
1802
                        else if (this == PrimitiveTypeWrapper.DOUBLE)
 
1803
                        {
 
1804
                                return java.lang.Double.TYPE;
 
1805
                        }
 
1806
                        else if (this == PrimitiveTypeWrapper.FLOAT)
 
1807
                        {
 
1808
                                return java.lang.Float.TYPE;
 
1809
                        }
 
1810
                        else if (this == PrimitiveTypeWrapper.INT)
 
1811
                        {
 
1812
                                return java.lang.Integer.TYPE;
 
1813
                        }
 
1814
                        else if (this == PrimitiveTypeWrapper.LONG)
 
1815
                        {
 
1816
                                return java.lang.Long.TYPE;
 
1817
                        }
 
1818
                        else if (this == PrimitiveTypeWrapper.SHORT)
 
1819
                        {
 
1820
                                return java.lang.Short.TYPE;
 
1821
                        }
 
1822
                        else if (this == PrimitiveTypeWrapper.BOOLEAN)
 
1823
                        {
 
1824
                                return java.lang.Boolean.TYPE;
 
1825
                        }
 
1826
                        else if (this == PrimitiveTypeWrapper.VOID)
 
1827
                        {
 
1828
                                return java.lang.Void.TYPE;
 
1829
                        }
 
1830
                        else
 
1831
                        {
 
1832
                                throw new InvalidOperationException();
 
1833
                        }
 
1834
                }
 
1835
#endif
 
1836
 
 
1837
                private void LazyInitClass()
 
1838
                {
 
1839
                        lock (this)
 
1840
                        {
 
1841
                                if (classObject == null)
 
1842
                                {
 
1843
                                        // DynamicTypeWrapper should haved already had SetClassObject explicitly
 
1844
                                        Debug.Assert(!(this is DynamicTypeWrapper));
 
1845
#if !FIRST_PASS
 
1846
                                        java.lang.Class clazz;
 
1847
                                        // note that this has to be the same check as in EmitClassLiteral
 
1848
                                        if (!this.IsFastClassLiteralSafe)
 
1849
                                        {
 
1850
                                                if (this.IsPrimitive)
 
1851
                                                {
 
1852
                                                        clazz = GetPrimitiveClass();
 
1853
                                                }
 
1854
                                                else
 
1855
                                                {
 
1856
                                                        clazz = new java.lang.Class(null);
 
1857
                                                }
 
1858
                                        }
 
1859
                                        else
 
1860
                                        {
 
1861
                                                Type type = GetClassLiteralType();
 
1862
                                                if (IsForbiddenTypeParameterType(type))
 
1863
                                                {
 
1864
                                                        clazz = new java.lang.Class(type);
 
1865
                                                }
 
1866
                                                else
 
1867
                                                {
 
1868
                                                        clazz = (java.lang.Class)typeof(ikvm.@internal.ClassLiteral<>).MakeGenericType(type).GetField("Value").GetValue(null);
 
1869
                                                }
 
1870
                                        }
 
1871
#if __MonoCS__
 
1872
                                        SetTypeWrapperHack(clazz, this);
 
1873
#else
 
1874
                                        clazz.typeWrapper = this;
 
1875
#endif
 
1876
                                        // MONOBUG Interlocked.Exchange is broken on Mono, so we use CompareExchange
 
1877
                                        System.Threading.Interlocked.CompareExchange(ref classObject, clazz, null);
 
1878
#endif
 
1879
                                }
 
1880
                        }
 
1881
                }
 
1882
 
 
1883
#if __MonoCS__
 
1884
                // MONOBUG this method is to work around an mcs bug
 
1885
                internal static void SetTypeWrapperHack(object clazz, TypeWrapper type)
 
1886
                {
 
1887
#if !FIRST_PASS
 
1888
                        typeof(java.lang.Class).GetField("typeWrapper", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(clazz, type);
 
1889
#endif
 
1890
                }
 
1891
#endif
 
1892
 
 
1893
#if !FIRST_PASS
 
1894
                private static void ResolvePrimitiveTypeWrapperClasses()
 
1895
                {
 
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)
 
1907
                        {
 
1908
                                throw new InvalidOperationException();
 
1909
                        }
 
1910
                }
 
1911
#endif
 
1912
 
 
1913
                internal static TypeWrapper FromClass(java.lang.Class clazz)
 
1914
                {
 
1915
#if FIRST_PASS
 
1916
                        return null;
 
1917
#else
 
1918
                        // MONOBUG redundant cast to workaround mcs bug
 
1919
                        TypeWrapper tw = (TypeWrapper)(object)clazz.typeWrapper;
 
1920
                        if(tw == null)
 
1921
                        {
 
1922
                                Type type = clazz.type;
 
1923
                                if (type == null)
 
1924
                                {
 
1925
                                        ResolvePrimitiveTypeWrapperClasses();
 
1926
                                        return FromClass(clazz);
 
1927
                                }
 
1928
                                if (type == typeof(void) || type.IsPrimitive || ClassLoaderWrapper.IsRemappedType(type))
 
1929
                                {
 
1930
                                        tw = DotNetTypeWrapper.GetWrapperFromDotNetType(type);
 
1931
                                }
 
1932
                                else
 
1933
                                {
 
1934
                                        tw = ClassLoaderWrapper.GetWrapperFromType(type);
 
1935
                                }
 
1936
#if __MonoCS__
 
1937
                                SetTypeWrapperHack(clazz, tw);
 
1938
#else
 
1939
                                clazz.typeWrapper = tw;
 
1940
#endif
 
1941
                        }
 
1942
                        return tw;
 
1943
#endif
 
1944
                }
 
1945
#endif // !STATIC_COMPILER && !STUB_GENERATOR
 
1946
 
 
1947
                public override string ToString()
 
1948
                {
 
1949
                        return GetType().Name + "[" + name + "]";
 
1950
                }
 
1951
 
 
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)
 
1956
                {
 
1957
                        return this;
 
1958
                }
 
1959
 
 
1960
                internal bool HasIncompleteInterfaceImplementation
 
1961
                {
 
1962
                        get
 
1963
                        {
 
1964
                                TypeWrapper baseWrapper = this.BaseTypeWrapper;
 
1965
                                return (flags & TypeFlags.HasIncompleteInterfaceImplementation) != 0 || (baseWrapper != null && baseWrapper.HasIncompleteInterfaceImplementation);
 
1966
                        }
 
1967
                        set
 
1968
                        {
 
1969
                                // TODO do we need locking here?
 
1970
                                if(value)
 
1971
                                {
 
1972
                                        flags |= TypeFlags.HasIncompleteInterfaceImplementation;
 
1973
                                }
 
1974
                                else
 
1975
                                {
 
1976
                                        flags &= ~TypeFlags.HasIncompleteInterfaceImplementation;
 
1977
                                }
 
1978
                        }
 
1979
                }
 
1980
 
 
1981
                internal bool HasUnsupportedAbstractMethods
 
1982
                {
 
1983
                        get
 
1984
                        {
 
1985
                                foreach(TypeWrapper iface in this.Interfaces)
 
1986
                                {
 
1987
                                        if(iface.HasUnsupportedAbstractMethods)
 
1988
                                        {
 
1989
                                                return true;
 
1990
                                        }
 
1991
                                }
 
1992
                                TypeWrapper baseWrapper = this.BaseTypeWrapper;
 
1993
                                return (flags & TypeFlags.HasUnsupportedAbstractMethods) != 0 || (baseWrapper != null && baseWrapper.HasUnsupportedAbstractMethods);
 
1994
                        }
 
1995
                        set
 
1996
                        {
 
1997
                                // TODO do we need locking here?
 
1998
                                if(value)
 
1999
                                {
 
2000
                                        flags |= TypeFlags.HasUnsupportedAbstractMethods;
 
2001
                                }
 
2002
                                else
 
2003
                                {
 
2004
                                        flags &= ~TypeFlags.HasUnsupportedAbstractMethods;
 
2005
                                }
 
2006
                        }
 
2007
                }
 
2008
 
 
2009
                internal virtual bool HasStaticInitializer
 
2010
                {
 
2011
                        get
 
2012
                        {
 
2013
                                return (flags & TypeFlags.HasStaticInitializer) != 0;
 
2014
                        }
 
2015
                        set
 
2016
                        {
 
2017
                                // TODO do we need locking here?
 
2018
                                if(value)
 
2019
                                {
 
2020
                                        flags |= TypeFlags.HasStaticInitializer;
 
2021
                                }
 
2022
                                else
 
2023
                                {
 
2024
                                        flags &= ~TypeFlags.HasStaticInitializer;
 
2025
                                }
 
2026
                        }
 
2027
                }
 
2028
 
 
2029
                internal bool HasVerifyError
 
2030
                {
 
2031
                        get
 
2032
                        {
 
2033
                                return (flags & TypeFlags.VerifyError) != 0;
 
2034
                        }
 
2035
                        set
 
2036
                        {
 
2037
                                // TODO do we need locking here?
 
2038
                                if(value)
 
2039
                                {
 
2040
                                        flags |= TypeFlags.VerifyError;
 
2041
                                }
 
2042
                                else
 
2043
                                {
 
2044
                                        flags &= ~TypeFlags.VerifyError;
 
2045
                                }
 
2046
                        }
 
2047
                }
 
2048
 
 
2049
                internal bool HasClassFormatError
 
2050
                {
 
2051
                        get
 
2052
                        {
 
2053
                                return (flags & TypeFlags.ClassFormatError) != 0;
 
2054
                        }
 
2055
                        set
 
2056
                        {
 
2057
                                // TODO do we need locking here?
 
2058
                                if(value)
 
2059
                                {
 
2060
                                        flags |= TypeFlags.ClassFormatError;
 
2061
                                }
 
2062
                                else
 
2063
                                {
 
2064
                                        flags &= ~TypeFlags.ClassFormatError;
 
2065
                                }
 
2066
                        }
 
2067
                }
 
2068
 
 
2069
                internal virtual bool IsFakeTypeContainer
 
2070
                {
 
2071
                        get
 
2072
                        {
 
2073
                                return false;
 
2074
                        }
 
2075
                }
 
2076
 
 
2077
                internal virtual bool IsFakeNestedType
 
2078
                {
 
2079
                        get
 
2080
                        {
 
2081
                                return false;
 
2082
                        }
 
2083
                }
 
2084
 
 
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
 
2089
                {
 
2090
                        get
 
2091
                        {
 
2092
                                return false;
 
2093
                        }
 
2094
                }
 
2095
 
 
2096
                // is this an array type of which the ultimate element type is a ghost?
 
2097
                internal bool IsGhostArray
 
2098
                {
 
2099
                        get
 
2100
                        {
 
2101
                                return !IsUnloadable && IsArray && (ElementTypeWrapper.IsGhost || ElementTypeWrapper.IsGhostArray);
 
2102
                        }
 
2103
                }
 
2104
 
 
2105
                internal virtual FieldInfo GhostRefField
 
2106
                {
 
2107
                        get
 
2108
                        {
 
2109
                                throw new InvalidOperationException();
 
2110
                        }
 
2111
                }
 
2112
 
 
2113
                internal virtual bool IsRemapped
 
2114
                {
 
2115
                        get
 
2116
                        {
 
2117
                                return false;
 
2118
                        }
 
2119
                }
 
2120
 
 
2121
                internal bool IsArray
 
2122
                {
 
2123
                        get
 
2124
                        {
 
2125
                                return name != null && name[0] == '[';
 
2126
                        }
 
2127
                }
 
2128
 
 
2129
                // NOTE for non-array types this returns 0
 
2130
                internal int ArrayRank
 
2131
                {
 
2132
                        get
 
2133
                        {
 
2134
                                int i = 0;
 
2135
                                if(name != null)
 
2136
                                {
 
2137
                                        while(name[i] == '[')
 
2138
                                        {
 
2139
                                                i++;
 
2140
                                        }
 
2141
                                }
 
2142
                                return i;
 
2143
                        }
 
2144
                }
 
2145
 
 
2146
                internal virtual TypeWrapper GetUltimateElementTypeWrapper()
 
2147
                {
 
2148
                        throw new InvalidOperationException();
 
2149
                }
 
2150
 
 
2151
                internal bool IsNonPrimitiveValueType
 
2152
                {
 
2153
                        get
 
2154
                        {
 
2155
                                return this != VerifierTypeWrapper.Null && !IsPrimitive && !IsGhost && TypeAsTBD.IsValueType;
 
2156
                        }
 
2157
                }
 
2158
 
 
2159
                internal bool IsPrimitive
 
2160
                {
 
2161
                        get
 
2162
                        {
 
2163
                                return name == null;
 
2164
                        }
 
2165
                }
 
2166
 
 
2167
                internal bool IsWidePrimitive
 
2168
                {
 
2169
                        get
 
2170
                        {
 
2171
                                return this == PrimitiveTypeWrapper.LONG || this == PrimitiveTypeWrapper.DOUBLE;
 
2172
                        }
 
2173
                }
 
2174
 
 
2175
                internal bool IsIntOnStackPrimitive
 
2176
                {
 
2177
                        get
 
2178
                        {
 
2179
                                return name == null &&
 
2180
                                        (this == PrimitiveTypeWrapper.BOOLEAN ||
 
2181
                                        this == PrimitiveTypeWrapper.BYTE ||
 
2182
                                        this == PrimitiveTypeWrapper.CHAR ||
 
2183
                                        this == PrimitiveTypeWrapper.SHORT ||
 
2184
                                        this == PrimitiveTypeWrapper.INT);
 
2185
                        }
 
2186
                }
 
2187
 
 
2188
                private static bool IsJavaPrimitive(Type type)
 
2189
                {
 
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;
 
2199
                }
 
2200
 
 
2201
                internal bool IsBoxedPrimitive
 
2202
                {
 
2203
                        get
 
2204
                        {
 
2205
                                return !IsPrimitive && IsJavaPrimitive(TypeAsSignatureType);
 
2206
                        }
 
2207
                }
 
2208
 
 
2209
                internal bool IsErasedOrBoxedPrimitiveOrRemapped
 
2210
                {
 
2211
                        get
 
2212
                        {
 
2213
                                bool erased = IsUnloadable || IsGhostArray;
 
2214
                                return erased || IsBoxedPrimitive || (IsRemapped && this is DotNetTypeWrapper);
 
2215
                        }
 
2216
                }
 
2217
 
 
2218
                internal bool IsUnloadable
 
2219
                {
 
2220
                        get
 
2221
                        {
 
2222
                                // NOTE we abuse modifiers to note unloadable classes
 
2223
                                return modifiers == UnloadableModifiersHack;
 
2224
                        }
 
2225
                }
 
2226
 
 
2227
                internal bool IsVerifierType
 
2228
                {
 
2229
                        get
 
2230
                        {
 
2231
                                // NOTE we abuse modifiers to note verifier types
 
2232
                                return modifiers == VerifierTypeModifiersHack;
 
2233
                        }
 
2234
                }
 
2235
 
 
2236
                internal virtual bool IsMapUnsafeException
 
2237
                {
 
2238
                        get
 
2239
                        {
 
2240
                                return false;
 
2241
                        }
 
2242
                }
 
2243
 
 
2244
                internal Modifiers Modifiers
 
2245
                {
 
2246
                        get
 
2247
                        {
 
2248
                                return modifiers;
 
2249
                        }
 
2250
                }
 
2251
 
 
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
 
2255
                {
 
2256
                        get
 
2257
                        {
 
2258
                                return modifiers;
 
2259
                        }
 
2260
                }
 
2261
 
 
2262
                internal bool IsInternal
 
2263
                {
 
2264
                        get
 
2265
                        {
 
2266
                                return (flags & TypeFlags.InternalAccess) != 0;
 
2267
                        }
 
2268
                        set
 
2269
                        {
 
2270
                                // TODO do we need locking here?
 
2271
                                if(value)
 
2272
                                {
 
2273
                                        flags |= TypeFlags.InternalAccess;
 
2274
                                }
 
2275
                                else
 
2276
                                {
 
2277
                                        flags &= ~TypeFlags.InternalAccess;
 
2278
                                }
 
2279
                        }
 
2280
                }
 
2281
 
 
2282
                internal bool IsPublic
 
2283
                {
 
2284
                        get
 
2285
                        {
 
2286
                                return (modifiers & Modifiers.Public) != 0;
 
2287
                        }
 
2288
                }
 
2289
 
 
2290
                internal bool IsAbstract
 
2291
                {
 
2292
                        get
 
2293
                        {
 
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;
 
2296
                        }
 
2297
                }
 
2298
 
 
2299
                internal bool IsFinal
 
2300
                {
 
2301
                        get
 
2302
                        {
 
2303
                                return (modifiers & Modifiers.Final) != 0;
 
2304
                        }
 
2305
                }
 
2306
 
 
2307
                internal bool IsInterface
 
2308
                {
 
2309
                        get
 
2310
                        {
 
2311
                                Debug.Assert(!IsUnloadable && !IsVerifierType);
 
2312
                                return (modifiers & Modifiers.Interface) != 0;
 
2313
                        }
 
2314
                }
 
2315
 
 
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
 
2321
                {
 
2322
                        get
 
2323
                        {
 
2324
                                TypeWrapper tw = this;
 
2325
                                while(tw.IsArray)
 
2326
                                {
 
2327
                                        tw = tw.ElementTypeWrapper;
 
2328
                                }
 
2329
                                return tw.IsInterface;
 
2330
                        }
 
2331
                }
 
2332
 
 
2333
                internal abstract ClassLoaderWrapper GetClassLoader();
 
2334
 
 
2335
                internal FieldWrapper GetFieldWrapper(string fieldName, string fieldSig)
 
2336
                {
 
2337
                        foreach(FieldWrapper fw in GetFields())
 
2338
                        {
 
2339
                                if(fw.Name == fieldName && fw.Signature == fieldSig)
 
2340
                                {
 
2341
                                        return fw;
 
2342
                                }       
 
2343
                        }
 
2344
                        foreach(TypeWrapper iface in this.Interfaces)
 
2345
                        {
 
2346
                                FieldWrapper fw = iface.GetFieldWrapper(fieldName, fieldSig);
 
2347
                                if(fw != null)
 
2348
                                {
 
2349
                                        return fw;
 
2350
                                }
 
2351
                        }
 
2352
                        TypeWrapper baseWrapper = this.BaseTypeWrapper;
 
2353
                        if(baseWrapper != null)
 
2354
                        {
 
2355
                                return baseWrapper.GetFieldWrapper(fieldName, fieldSig);
 
2356
                        }
 
2357
                        return null;
 
2358
                }
 
2359
 
 
2360
                protected virtual void LazyPublishMembers()
 
2361
                {
 
2362
                        if(methods == null)
 
2363
                        {
 
2364
                                methods = MethodWrapper.EmptyArray;
 
2365
                        }
 
2366
                        if(fields == null)
 
2367
                        {
 
2368
                                fields = FieldWrapper.EmptyArray;
 
2369
                        }
 
2370
                }
 
2371
 
 
2372
                protected virtual void LazyPublishMethods()
 
2373
                {
 
2374
                        LazyPublishMembers();
 
2375
                }
 
2376
 
 
2377
                protected virtual void LazyPublishFields()
 
2378
                {
 
2379
                        LazyPublishMembers();
 
2380
                }
 
2381
 
 
2382
                internal MethodWrapper[] GetMethods()
 
2383
                {
 
2384
                        if(methods == null)
 
2385
                        {
 
2386
                                lock(this)
 
2387
                                {
 
2388
                                        if(methods == null)
 
2389
                                        {
 
2390
                                                LazyPublishMethods();
 
2391
                                        }
 
2392
                                }
 
2393
                        }
 
2394
                        return methods;
 
2395
                }
 
2396
 
 
2397
                internal FieldWrapper[] GetFields()
 
2398
                {
 
2399
                        if(fields == null)
 
2400
                        {
 
2401
                                lock(this)
 
2402
                                {
 
2403
                                        if(fields == null)
 
2404
                                        {
 
2405
                                                LazyPublishFields();
 
2406
                                        }
 
2407
                                }
 
2408
                        }
 
2409
                        return fields;
 
2410
                }
 
2411
 
 
2412
                internal MethodWrapper GetMethodWrapper(string name, string sig, bool inherit)
 
2413
                {
 
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)
 
2421
                        {
 
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))
 
2425
                                {
 
2426
                                        return mw;
 
2427
                                }
 
2428
                        }
 
2429
                        TypeWrapper baseWrapper = this.BaseTypeWrapper;
 
2430
                        if(inherit && baseWrapper != null)
 
2431
                        {
 
2432
                                return baseWrapper.GetMethodWrapper(name, sig, inherit);
 
2433
                        }
 
2434
                        return null;
 
2435
                }
 
2436
 
 
2437
                internal void SetMethods(MethodWrapper[] methods)
 
2438
                {
 
2439
                        Debug.Assert(methods != null);
 
2440
                        this.methods = methods;
 
2441
                }
 
2442
 
 
2443
                internal void SetFields(FieldWrapper[] fields)
 
2444
                {
 
2445
                        Debug.Assert(fields != null);
 
2446
                        this.fields = fields;
 
2447
                }
 
2448
 
 
2449
                internal string Name
 
2450
                {
 
2451
                        get
 
2452
                        {
 
2453
                                return name;
 
2454
                        }
 
2455
                }
 
2456
 
 
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
 
2459
                {
 
2460
                        get
 
2461
                        {
 
2462
                                return "L" + this.Name + ";";
 
2463
                        }
 
2464
                }
 
2465
 
 
2466
                // returns true iff wrapper is allowed to access us
 
2467
                internal bool IsAccessibleFrom(TypeWrapper wrapper)
 
2468
                {
 
2469
                        return IsPublic
 
2470
                                || (IsInternal && InternalsVisibleTo(wrapper))
 
2471
                                || IsPackageAccessibleFrom(wrapper);
 
2472
                }
 
2473
 
 
2474
                internal bool InternalsVisibleTo(TypeWrapper wrapper)
 
2475
                {
 
2476
                        return GetClassLoader().InternalsVisibleToImpl(this, wrapper);
 
2477
                }
 
2478
 
 
2479
                internal bool IsPackageAccessibleFrom(TypeWrapper wrapper)
 
2480
                {
 
2481
                        if (MatchingPackageNames(name, wrapper.name))
 
2482
                        {
 
2483
#if STATIC_COMPILER
 
2484
                                CompilerClassLoader ccl = GetClassLoader() as CompilerClassLoader;
 
2485
                                if (ccl != null)
 
2486
                                {
 
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());
 
2490
                                }
 
2491
#endif
 
2492
                                return GetClassLoader() == wrapper.GetClassLoader();
 
2493
                        }
 
2494
                        else
 
2495
                        {
 
2496
                                return false;
 
2497
                        }
 
2498
                }
 
2499
 
 
2500
                private static bool MatchingPackageNames(string name1, string name2)
 
2501
                {
 
2502
                        int index1 = name1.LastIndexOf('.');
 
2503
                        int index2 = name2.LastIndexOf('.');
 
2504
                        if (index1 == -1 && index2 == -1)
 
2505
                        {
 
2506
                                return true;
 
2507
                        }
 
2508
                        // for array types we need to skip the brackets
 
2509
                        int skip1 = 0;
 
2510
                        int skip2 = 0;
 
2511
                        while (name1[skip1] == '[')
 
2512
                        {
 
2513
                                skip1++;
 
2514
                        }
 
2515
                        while (name2[skip2] == '[')
 
2516
                        {
 
2517
                                skip2++;
 
2518
                        }
 
2519
                        if (skip1 > 0)
 
2520
                        {
 
2521
                                // skip over the L that follows the brackets
 
2522
                                skip1++;
 
2523
                        }
 
2524
                        if (skip2 > 0)
 
2525
                        {
 
2526
                                // skip over the L that follows the brackets
 
2527
                                skip2++;
 
2528
                        }
 
2529
                        if ((index1 - skip1) != (index2 - skip2))
 
2530
                        {
 
2531
                                return false;
 
2532
                        }
 
2533
                        return String.CompareOrdinal(name1, skip1, name2, skip2, index1 - skip1) == 0;
 
2534
                }
 
2535
 
 
2536
                internal abstract Type TypeAsTBD
 
2537
                {
 
2538
                        get;
 
2539
                }
 
2540
 
 
2541
                internal Type TypeAsSignatureType
 
2542
                {
 
2543
                        get
 
2544
                        {
 
2545
                                if(IsUnloadable)
 
2546
                                {
 
2547
                                        return Types.Object;
 
2548
                                }
 
2549
                                if(IsGhostArray)
 
2550
                                {
 
2551
                                        return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
 
2552
                                }
 
2553
                                return TypeAsTBD;
 
2554
                        }
 
2555
                }
 
2556
 
 
2557
                internal virtual Type TypeAsBaseType
 
2558
                {
 
2559
                        get
 
2560
                        {
 
2561
                                return TypeAsTBD;
 
2562
                        }
 
2563
                }
 
2564
 
 
2565
                internal Type TypeAsLocalOrStackType
 
2566
                {
 
2567
                        get
 
2568
                        {
 
2569
                                if(IsUnloadable || IsGhost)
 
2570
                                {
 
2571
                                        return Types.Object;
 
2572
                                }
 
2573
                                if(IsNonPrimitiveValueType)
 
2574
                                {
 
2575
                                        // return either System.ValueType or System.Enum
 
2576
                                        return TypeAsTBD.BaseType;
 
2577
                                }
 
2578
                                if(IsGhostArray)
 
2579
                                {
 
2580
                                        return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
 
2581
                                }
 
2582
                                return TypeAsTBD;
 
2583
                        }
 
2584
                }
 
2585
 
 
2586
                /** <summary>Use this if the type is used as an array or array element</summary> */
 
2587
                internal Type TypeAsArrayType
 
2588
                {
 
2589
                        get
 
2590
                        {
 
2591
                                if(IsUnloadable || IsGhost)
 
2592
                                {
 
2593
                                        return Types.Object;
 
2594
                                }
 
2595
                                if(IsGhostArray)
 
2596
                                {
 
2597
                                        return ArrayTypeWrapper.MakeArrayType(Types.Object, ArrayRank);
 
2598
                                }
 
2599
                                return TypeAsTBD;
 
2600
                        }
 
2601
                }
 
2602
 
 
2603
                internal Type TypeAsExceptionType
 
2604
                {
 
2605
                        get
 
2606
                        {
 
2607
                                if(IsUnloadable)
 
2608
                                {
 
2609
                                        return Types.Exception;
 
2610
                                }
 
2611
                                return TypeAsTBD;
 
2612
                        }
 
2613
                }
 
2614
 
 
2615
                internal abstract TypeWrapper BaseTypeWrapper
 
2616
                {
 
2617
                        get;
 
2618
                }
 
2619
 
 
2620
                internal TypeWrapper ElementTypeWrapper
 
2621
                {
 
2622
                        get
 
2623
                        {
 
2624
                                Debug.Assert(!this.IsUnloadable);
 
2625
                                Debug.Assert(this == VerifierTypeWrapper.Null || this.IsArray);
 
2626
 
 
2627
                                if(this == VerifierTypeWrapper.Null)
 
2628
                                {
 
2629
                                        return VerifierTypeWrapper.Null;
 
2630
                                }
 
2631
 
 
2632
                                // TODO consider caching the element type
 
2633
                                switch(name[1])
 
2634
                                {
 
2635
                                        case '[':
 
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));
 
2639
                                        case 'L':
 
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));
 
2643
                                        case 'Z':
 
2644
                                                return PrimitiveTypeWrapper.BOOLEAN;
 
2645
                                        case 'B':
 
2646
                                                return PrimitiveTypeWrapper.BYTE;
 
2647
                                        case 'S':
 
2648
                                                return PrimitiveTypeWrapper.SHORT;
 
2649
                                        case 'C':
 
2650
                                                return PrimitiveTypeWrapper.CHAR;
 
2651
                                        case 'I':
 
2652
                                                return PrimitiveTypeWrapper.INT;
 
2653
                                        case 'J':
 
2654
                                                return PrimitiveTypeWrapper.LONG;
 
2655
                                        case 'F':
 
2656
                                                return PrimitiveTypeWrapper.FLOAT;
 
2657
                                        case 'D':
 
2658
                                                return PrimitiveTypeWrapper.DOUBLE;
 
2659
                                        default:
 
2660
                                                throw new InvalidOperationException(name);
 
2661
                                }
 
2662
                        }
 
2663
                }
 
2664
 
 
2665
                internal TypeWrapper MakeArrayType(int rank)
 
2666
                {
 
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);
 
2670
                }
 
2671
 
 
2672
                internal bool ImplementsInterface(TypeWrapper interfaceWrapper)
 
2673
                {
 
2674
                        TypeWrapper typeWrapper = this;
 
2675
                        while(typeWrapper != null)
 
2676
                        {
 
2677
                                TypeWrapper[] interfaces = typeWrapper.Interfaces;
 
2678
                                for(int i = 0; i < interfaces.Length; i++)
 
2679
                                {
 
2680
                                        if(interfaces[i] == interfaceWrapper)
 
2681
                                        {
 
2682
                                                return true;
 
2683
                                        }
 
2684
                                        if(interfaces[i].ImplementsInterface(interfaceWrapper))
 
2685
                                        {
 
2686
                                                return true;
 
2687
                                        }
 
2688
                                }
 
2689
                                typeWrapper = typeWrapper.BaseTypeWrapper;
 
2690
                        }
 
2691
                        return false;
 
2692
                }
 
2693
 
 
2694
                internal bool IsSubTypeOf(TypeWrapper baseType)
 
2695
                {
 
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);
 
2702
 
 
2703
                        if(baseType.IsInterface)
 
2704
                        {
 
2705
                                if(baseType == this)
 
2706
                                {
 
2707
                                        return true;
 
2708
                                }
 
2709
                                return ImplementsInterface(baseType);
 
2710
                        }
 
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)
 
2713
                        {
 
2714
                                return true;
 
2715
                        }
 
2716
                        TypeWrapper subType = this;
 
2717
                        while(subType != baseType)
 
2718
                        {
 
2719
                                subType = subType.BaseTypeWrapper;
 
2720
                                if(subType == null)
 
2721
                                {
 
2722
                                        return false;
 
2723
                                }
 
2724
                        }
 
2725
                        return true;
 
2726
                }
 
2727
 
 
2728
                internal bool IsAssignableTo(TypeWrapper wrapper)
 
2729
                {
 
2730
                        if(this == wrapper)
 
2731
                        {
 
2732
                                return true;
 
2733
                        }
 
2734
                        if(this.IsPrimitive || wrapper.IsPrimitive)
 
2735
                        {
 
2736
                                return false;
 
2737
                        }
 
2738
                        if(this == VerifierTypeWrapper.Null)
 
2739
                        {
 
2740
                                return true;
 
2741
                        }
 
2742
                        if(wrapper.IsInterface)
 
2743
                        {
 
2744
                                return ImplementsInterface(wrapper);
 
2745
                        }
 
2746
                        int rank1 = this.ArrayRank;
 
2747
                        int rank2 = wrapper.ArrayRank;
 
2748
                        if(rank1 > 0 && rank2 > 0)
 
2749
                        {
 
2750
                                rank1--;
 
2751
                                rank2--;
 
2752
                                TypeWrapper elem1 = this.ElementTypeWrapper;
 
2753
                                TypeWrapper elem2 = wrapper.ElementTypeWrapper;
 
2754
                                while(rank1 != 0 && rank2 != 0)
 
2755
                                {
 
2756
                                        elem1 = elem1.ElementTypeWrapper;
 
2757
                                        elem2 = elem2.ElementTypeWrapper;
 
2758
                                        rank1--;
 
2759
                                        rank2--;
 
2760
                                }
 
2761
                                if(elem1.IsPrimitive || elem2.IsPrimitive)
 
2762
                                {
 
2763
                                        return false;
 
2764
                                }
 
2765
                                return (!elem1.IsNonPrimitiveValueType && elem1.IsSubTypeOf(elem2)) || (rank1 == rank2 && elem2.IsGhost && elem1 == CoreClasses.java.lang.Object.Wrapper);
 
2766
                        }
 
2767
                        return this.IsSubTypeOf(wrapper);
 
2768
                }
 
2769
 
 
2770
#if !STATIC_COMPILER && !STUB_GENERATOR
 
2771
                internal bool IsInstance(object obj)
 
2772
                {
 
2773
                        if(obj != null)
 
2774
                        {
 
2775
                                TypeWrapper thisWrapper = this;
 
2776
                                TypeWrapper objWrapper = IKVM.NativeCode.ikvm.runtime.Util.GetTypeWrapperFromObject(obj);
 
2777
                                return objWrapper.IsAssignableTo(thisWrapper);
 
2778
                        }
 
2779
                        return false;
 
2780
                }
 
2781
#endif
 
2782
 
 
2783
                internal abstract TypeWrapper[] Interfaces
 
2784
                {
 
2785
                        get;
 
2786
                }
 
2787
 
 
2788
                // NOTE this property can only be called for finished types!
 
2789
                internal abstract TypeWrapper[] InnerClasses
 
2790
                {
 
2791
                        get;
 
2792
                }
 
2793
 
 
2794
                // NOTE this property can only be called for finished types!
 
2795
                internal abstract TypeWrapper DeclaringTypeWrapper
 
2796
                {
 
2797
                        get;
 
2798
                }
 
2799
 
 
2800
                internal abstract void Finish();
 
2801
 
 
2802
#if !STATIC_COMPILER
 
2803
                [Conditional("DEBUG")]
 
2804
                internal static void AssertFinished(Type type)
 
2805
                {
 
2806
                        if(type != null)
 
2807
                        {
 
2808
                                while(type.HasElementType)
 
2809
                                {
 
2810
                                        type = type.GetElementType();
 
2811
                                }
 
2812
                                Debug.Assert(!(type is TypeBuilder));
 
2813
                        }
 
2814
                }
 
2815
#endif
 
2816
 
 
2817
#if !STATIC_COMPILER && !STUB_GENERATOR
 
2818
                internal void RunClassInit()
 
2819
                {
 
2820
                        Type t = IsRemapped ? TypeAsBaseType : TypeAsTBD;
 
2821
                        if(t != null)
 
2822
                        {
 
2823
                                System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);
 
2824
                        }
 
2825
                }
 
2826
#endif
 
2827
 
 
2828
#if !STUB_GENERATOR
 
2829
                internal void EmitUnbox(CodeEmitter ilgen)
 
2830
                {
 
2831
                        Debug.Assert(this.IsNonPrimitiveValueType);
 
2832
 
 
2833
                        ilgen.EmitUnboxSpecial(this.TypeAsTBD);
 
2834
                }
 
2835
 
 
2836
                internal void EmitBox(CodeEmitter ilgen)
 
2837
                {
 
2838
                        Debug.Assert(this.IsNonPrimitiveValueType);
 
2839
 
 
2840
                        ilgen.Emit(OpCodes.Box, this.TypeAsTBD);
 
2841
                }
 
2842
 
 
2843
                internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen)
 
2844
                {
 
2845
                        if(IsUnloadable)
 
2846
                        {
 
2847
                        }
 
2848
                        else if(this == PrimitiveTypeWrapper.BYTE)
 
2849
                        {
 
2850
                                ilgen.Emit(OpCodes.Conv_I1);
 
2851
                        }
 
2852
                        else if(IsNonPrimitiveValueType)
 
2853
                        {
 
2854
                                EmitBox(ilgen);
 
2855
                        }
 
2856
                        else if(IsGhost)
 
2857
                        {
 
2858
                                CodeEmitterLocal local = ilgen.DeclareLocal(TypeAsSignatureType);
 
2859
                                ilgen.Emit(OpCodes.Stloc, local);
 
2860
                                ilgen.Emit(OpCodes.Ldloca, local);
 
2861
                                ilgen.Emit(OpCodes.Ldfld, GhostRefField);
 
2862
                        }
 
2863
                }
 
2864
 
 
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)
 
2868
                {
 
2869
                        if(!IsUnloadable)
 
2870
                        {
 
2871
                                if(IsGhost)
 
2872
                                {
 
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);
 
2881
                                }
 
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)))
 
2885
                                {
 
2886
                                        ilgen.EmitAssertType(TypeAsTBD);
 
2887
                                        Profiler.Count("InterfaceDownCast");
 
2888
                                }
 
2889
                                else if(IsNonPrimitiveValueType)
 
2890
                                {
 
2891
                                        EmitUnbox(ilgen);
 
2892
                                }
 
2893
                                else if(sourceType != null && sourceType.IsUnloadable)
 
2894
                                {
 
2895
                                        ilgen.Emit(OpCodes.Castclass, TypeAsSignatureType);
 
2896
                                }
 
2897
                        }
 
2898
                }
 
2899
 
 
2900
                internal virtual void EmitCheckcast(TypeWrapper context, CodeEmitter ilgen)
 
2901
                {
 
2902
                        if(IsGhost)
 
2903
                        {
 
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);
 
2910
                        }
 
2911
                        else if(IsGhostArray)
 
2912
                        {
 
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;
 
2918
                                int rank = 0;
 
2919
                                while(tw.IsArray)
 
2920
                                {
 
2921
                                        rank++;
 
2922
                                        tw = tw.ElementTypeWrapper;
 
2923
                                }
 
2924
                                ilgen.EmitLdc_I4(rank);
 
2925
                                ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray"));
 
2926
                                ilgen.Emit(OpCodes.Castclass, ArrayTypeWrapper.MakeArrayType(Types.Object, rank));
 
2927
                        }
 
2928
                        else
 
2929
                        {
 
2930
                                ilgen.EmitCastclass(TypeAsTBD);
 
2931
                        }
 
2932
                }
 
2933
 
 
2934
                internal virtual void EmitInstanceOf(TypeWrapper context, CodeEmitter ilgen)
 
2935
                {
 
2936
                        if(IsGhost)
 
2937
                        {
 
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"));
 
2942
                        }
 
2943
                        else if(IsGhostArray)
 
2944
                        {
 
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;
 
2949
                                int rank = 0;
 
2950
                                while(tw.IsArray)
 
2951
                                {
 
2952
                                        rank++;
 
2953
                                        tw = tw.ElementTypeWrapper;
 
2954
                                }
 
2955
                                ilgen.EmitLdc_I4(rank);
 
2956
                                ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("IsInstanceArray"));
 
2957
                        }
 
2958
                        else
 
2959
                        {
 
2960
                                ilgen.Emit_instanceof(TypeAsTBD);
 
2961
                        }
 
2962
                }
 
2963
#endif // !STUB_GENERATOR
 
2964
 
 
2965
                // NOTE don't call this method, call MethodWrapper.Link instead
 
2966
                internal virtual MethodBase LinkMethod(MethodWrapper mw)
 
2967
                {
 
2968
                        return mw.GetMethod();
 
2969
                }
 
2970
 
 
2971
                // NOTE don't call this method, call FieldWrapper.Link instead
 
2972
                internal virtual FieldInfo LinkField(FieldWrapper fw)
 
2973
                {
 
2974
                        return fw.GetField();
 
2975
                }
 
2976
 
 
2977
#if !STUB_GENERATOR
 
2978
                internal virtual void EmitRunClassConstructor(CodeEmitter ilgen)
 
2979
                {
 
2980
                }
 
2981
#endif // !STUB_GENERATOR
 
2982
 
 
2983
                internal virtual string GetGenericSignature()
 
2984
                {
 
2985
                        return null;
 
2986
                }
 
2987
 
 
2988
                internal virtual string GetGenericMethodSignature(MethodWrapper mw)
 
2989
                {
 
2990
                        return null;
 
2991
                }
 
2992
 
 
2993
                internal virtual string GetGenericFieldSignature(FieldWrapper fw)
 
2994
                {
 
2995
                        return null;
 
2996
                }
 
2997
 
 
2998
#if !STATIC_COMPILER && !STUB_GENERATOR
 
2999
                internal virtual string[] GetEnclosingMethod()
 
3000
                {
 
3001
                        return null;
 
3002
                }
 
3003
 
 
3004
                internal virtual object[] GetDeclaredAnnotations()
 
3005
                {
 
3006
                        return null;
 
3007
                }
 
3008
 
 
3009
                internal virtual object[] GetMethodAnnotations(MethodWrapper mw)
 
3010
                {
 
3011
                        return null;
 
3012
                }
 
3013
 
 
3014
                internal virtual object[][] GetParameterAnnotations(MethodWrapper mw)
 
3015
                {
 
3016
                        return null;
 
3017
                }
 
3018
 
 
3019
                internal virtual object[] GetFieldAnnotations(FieldWrapper fw)
 
3020
                {
 
3021
                        return null;
 
3022
                }
 
3023
 
 
3024
                internal virtual string GetSourceFileName()
 
3025
                {
 
3026
                        return null;
 
3027
                }
 
3028
 
 
3029
                internal virtual int GetSourceLineNumber(MethodBase mb, int ilOffset)
 
3030
                {
 
3031
                        return -1;
 
3032
                }
 
3033
 
 
3034
                internal virtual object GetAnnotationDefault(MethodWrapper mw)
 
3035
                {
 
3036
                        MethodBase mb = mw.GetMethod();
 
3037
                        if(mb != null)
 
3038
                        {
 
3039
                                object[] attr = mb.GetCustomAttributes(typeof(AnnotationDefaultAttribute), false);
 
3040
                                if(attr.Length == 1)
 
3041
                                {
 
3042
                                        return JVM.NewAnnotationElementValue(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), mw.ReturnType.ClassObject, ((AnnotationDefaultAttribute)attr[0]).Value);
 
3043
                                }
 
3044
                        }
 
3045
                        return null;
 
3046
                }
 
3047
#endif // !STATIC_COMPILER && !STUB_GENERATOR
 
3048
 
 
3049
                internal virtual Annotation Annotation
 
3050
                {
 
3051
                        get
 
3052
                        {
 
3053
                                return null;
 
3054
                        }
 
3055
                }
 
3056
 
 
3057
                internal virtual Type EnumType
 
3058
                {
 
3059
                        get
 
3060
                        {
 
3061
                                return null;
 
3062
                        }
 
3063
                }
 
3064
 
 
3065
                protected static TypeWrapper[] GetImplementedInterfacesAsTypeWrappers(Type type)
 
3066
                {
 
3067
                        Type[] interfaceTypes = type.GetInterfaces();
 
3068
                        TypeWrapper[] interfaces = new TypeWrapper[interfaceTypes.Length];
 
3069
                        for (int i = 0; i < interfaceTypes.Length; i++)
 
3070
                        {
 
3071
                                Type decl = interfaceTypes[i].DeclaringType;
 
3072
                                if (decl != null && AttributeHelper.IsGhostInterface(decl))
 
3073
                                {
 
3074
                                        // we have to return the declaring type for ghost interfaces
 
3075
                                        interfaces[i] = ClassLoaderWrapper.GetWrapperFromType(decl);
 
3076
                                }
 
3077
                                else
 
3078
                                {
 
3079
                                        interfaces[i] = ClassLoaderWrapper.GetWrapperFromType(interfaceTypes[i]);
 
3080
                                }
 
3081
                        }
 
3082
                        for (int i = 0; i < interfaceTypes.Length; i++)
 
3083
                        {
 
3084
                                if (interfaces[i].IsRemapped)
 
3085
                                {
 
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]);
 
3089
                                        interfaces[i] = tw;
 
3090
                                        if (Array.IndexOf(interfaces, twRemapped) == -1)
 
3091
                                        {
 
3092
                                                Array.Resize(ref interfaces, interfaces.Length + 1);
 
3093
                                                interfaces[interfaces.Length - 1] = twRemapped;
 
3094
                                        }
 
3095
                                }
 
3096
                        }
 
3097
                        return interfaces;
 
3098
                }
 
3099
 
 
3100
                internal TypeWrapper GetPublicBaseTypeWrapper()
 
3101
                {
 
3102
                        Debug.Assert(!this.IsPublic);
 
3103
                        if (this.IsUnloadable || this.IsInterface)
 
3104
                        {
 
3105
                                return CoreClasses.java.lang.Object.Wrapper;
 
3106
                        }
 
3107
                        for (TypeWrapper tw = this; ; tw = tw.BaseTypeWrapper)
 
3108
                        {
 
3109
                                if (tw.IsPublic)
 
3110
                                {
 
3111
                                        return tw;
 
3112
                                }
 
3113
                        }
 
3114
                }
 
3115
 
 
3116
#if !STUB_GENERATOR
 
3117
                // return the constructor used for automagic .NET serialization
 
3118
                internal virtual MethodBase GetSerializationConstructor()
 
3119
                {
 
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);
 
3123
                }
 
3124
 
 
3125
                internal virtual MethodBase GetBaseSerializationConstructor()
 
3126
                {
 
3127
                        return BaseTypeWrapper.GetSerializationConstructor();
 
3128
                }
 
3129
#endif
 
3130
        }
 
3131
 
 
3132
        sealed class UnloadableTypeWrapper : TypeWrapper
 
3133
        {
 
3134
                private Type customModifier;
 
3135
 
 
3136
                internal UnloadableTypeWrapper(string name)
 
3137
                        : base(TypeWrapper.UnloadableModifiersHack, name)
 
3138
                {
 
3139
                }
 
3140
 
 
3141
                internal UnloadableTypeWrapper(string name, Type customModifier)
 
3142
                        : this(name)
 
3143
                {
 
3144
                        this.customModifier = customModifier;
 
3145
                }
 
3146
 
 
3147
                internal override TypeWrapper BaseTypeWrapper
 
3148
                {
 
3149
                        get { return null; }
 
3150
                }
 
3151
 
 
3152
                internal override ClassLoaderWrapper GetClassLoader()
 
3153
                {
 
3154
                        return null;
 
3155
                }
 
3156
 
 
3157
                internal override TypeWrapper EnsureLoadable(ClassLoaderWrapper loader)
 
3158
                {
 
3159
                        TypeWrapper tw = loader.LoadClassByDottedNameFast(this.Name);
 
3160
                        if(tw == null)
 
3161
                        {
 
3162
                                throw new NoClassDefFoundError(this.Name);
 
3163
                        }
 
3164
                        return tw;
 
3165
                }
 
3166
 
 
3167
                internal override string SigName
 
3168
                {
 
3169
                        get
 
3170
                        {
 
3171
                                string name = Name;
 
3172
                                if(name.StartsWith("["))
 
3173
                                {
 
3174
                                        return name;
 
3175
                                }
 
3176
                                return "L" + name + ";";
 
3177
                        }
 
3178
                }
 
3179
 
 
3180
                protected override void LazyPublishMembers()
 
3181
                {
 
3182
                        throw new InvalidOperationException("LazyPublishMembers called on UnloadableTypeWrapper: " + Name);
 
3183
                }
 
3184
 
 
3185
                internal override Type TypeAsTBD
 
3186
                {
 
3187
                        get
 
3188
                        {
 
3189
                                throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
 
3190
                        }
 
3191
                }
 
3192
 
 
3193
                internal override TypeWrapper[] Interfaces
 
3194
                {
 
3195
                        get
 
3196
                        {
 
3197
                                throw new InvalidOperationException("get_Interfaces called on UnloadableTypeWrapper: " + Name);
 
3198
                        }
 
3199
                }
 
3200
 
 
3201
                internal override TypeWrapper[] InnerClasses
 
3202
                {
 
3203
                        get
 
3204
                        {
 
3205
                                throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper: " + Name);
 
3206
                        }
 
3207
                }
 
3208
 
 
3209
                internal override TypeWrapper DeclaringTypeWrapper
 
3210
                {
 
3211
                        get
 
3212
                        {
 
3213
                                throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
 
3214
                        }
 
3215
                }
 
3216
 
 
3217
                internal override void Finish()
 
3218
                {
 
3219
                        throw new InvalidOperationException("Finish called on UnloadableTypeWrapper: " + Name);
 
3220
                }
 
3221
 
 
3222
                internal Type CustomModifier
 
3223
                {
 
3224
                        get { return customModifier; }
 
3225
                }
 
3226
 
 
3227
                internal void SetCustomModifier(Type type)
 
3228
                {
 
3229
                        this.customModifier = type;
 
3230
                }
 
3231
 
 
3232
#if !STUB_GENERATOR
 
3233
                internal Type GetCustomModifier(TypeWrapperFactory context)
 
3234
                {
 
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));
 
3237
                }
 
3238
 
 
3239
                internal override void EmitCheckcast(TypeWrapper context, CodeEmitter ilgen)
 
3240
                {
 
3241
                        ilgen.Emit(OpCodes.Ldtoken, context.TypeAsTBD);
 
3242
                        ilgen.Emit(OpCodes.Ldstr, Name);
 
3243
                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCast);
 
3244
                }
 
3245
 
 
3246
                internal override void EmitInstanceOf(TypeWrapper context, CodeEmitter ilgen)
 
3247
                {
 
3248
                        ilgen.Emit(OpCodes.Ldtoken, context.TypeAsTBD);
 
3249
                        ilgen.Emit(OpCodes.Ldstr, Name);
 
3250
                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicInstanceOf);
 
3251
                }
 
3252
#endif // !STUB_GENERATOR
 
3253
        }
 
3254
 
 
3255
        sealed class PrimitiveTypeWrapper : TypeWrapper
 
3256
        {
 
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");
 
3266
 
 
3267
                private readonly Type type;
 
3268
                private readonly string sigName;
 
3269
 
 
3270
                private PrimitiveTypeWrapper(Type type, string sigName)
 
3271
                        : base(Modifiers.Public | Modifiers.Abstract | Modifiers.Final, null)
 
3272
                {
 
3273
                        this.type = type;
 
3274
                        this.sigName = sigName;
 
3275
                }
 
3276
 
 
3277
                internal override TypeWrapper BaseTypeWrapper
 
3278
                {
 
3279
                        get { return null; }
 
3280
                }
 
3281
 
 
3282
                internal static bool IsPrimitiveType(Type type)
 
3283
                {
 
3284
                        return type == BYTE.type
 
3285
                                || type == CHAR.type
 
3286
                                || type == DOUBLE.type
 
3287
                                || type == FLOAT.type
 
3288
                                || type == INT.type
 
3289
                                || type == LONG.type
 
3290
                                || type == SHORT.type
 
3291
                                || type == BOOLEAN.type
 
3292
                                || type == VOID.type;
 
3293
                }
 
3294
 
 
3295
                internal override string SigName
 
3296
                {
 
3297
                        get
 
3298
                        {
 
3299
                                return sigName;
 
3300
                        }
 
3301
                }
 
3302
 
 
3303
                internal override ClassLoaderWrapper GetClassLoader()
 
3304
                {
 
3305
                        return ClassLoaderWrapper.GetBootstrapClassLoader();
 
3306
                }
 
3307
 
 
3308
                internal override Type TypeAsTBD
 
3309
                {
 
3310
                        get
 
3311
                        {
 
3312
                                return type;
 
3313
                        }
 
3314
                }
 
3315
 
 
3316
                internal override TypeWrapper[] Interfaces
 
3317
                {
 
3318
                        get
 
3319
                        {
 
3320
                                return TypeWrapper.EmptyArray;
 
3321
                        }
 
3322
                }
 
3323
 
 
3324
                internal override TypeWrapper[] InnerClasses
 
3325
                {
 
3326
                        get
 
3327
                        {
 
3328
                                return TypeWrapper.EmptyArray;
 
3329
                        }
 
3330
                }
 
3331
 
 
3332
                internal override TypeWrapper DeclaringTypeWrapper
 
3333
                {
 
3334
                        get
 
3335
                        {
 
3336
                                return null;
 
3337
                        }
 
3338
                }
 
3339
 
 
3340
                internal override void Finish()
 
3341
                {
 
3342
                }
 
3343
 
 
3344
                public override string ToString()
 
3345
                {
 
3346
                        return "PrimitiveTypeWrapper[" + sigName + "]";
 
3347
                }
 
3348
        }
 
3349
 
 
3350
        class CompiledTypeWrapper : TypeWrapper
 
3351
        {
 
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;
 
3358
 
 
3359
                internal static CompiledTypeWrapper newInstance(string name, Type type)
 
3360
                {
 
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))
 
3364
                        {
 
3365
                                return new CompiledGhostTypeWrapper(name, type);
 
3366
                        }
 
3367
                        else if(AttributeHelper.IsRemappedType(type))
 
3368
                        {
 
3369
                                return new CompiledRemappedTypeWrapper(name, type);
 
3370
                        }
 
3371
                        else
 
3372
                        {
 
3373
                                return new CompiledTypeWrapper(name, type);
 
3374
                        }
 
3375
                }
 
3376
 
 
3377
                private sealed class CompiledRemappedTypeWrapper : CompiledTypeWrapper
 
3378
                {
 
3379
                        private readonly Type remappedType;
 
3380
 
 
3381
                        internal CompiledRemappedTypeWrapper(string name, Type type)
 
3382
                                : base(name, type)
 
3383
                        {
 
3384
                                RemappedTypeAttribute attr = AttributeHelper.GetRemappedType(type);
 
3385
                                if(attr == null)
 
3386
                                {
 
3387
                                        throw new InvalidOperationException();
 
3388
                                }
 
3389
                                remappedType = attr.Type;
 
3390
                        }
 
3391
 
 
3392
                        internal override Type TypeAsTBD
 
3393
                        {
 
3394
                                get
 
3395
                                {
 
3396
                                        return remappedType;
 
3397
                                }
 
3398
                        }
 
3399
 
 
3400
                        internal override bool IsRemapped
 
3401
                        {
 
3402
                                get
 
3403
                                {
 
3404
                                        return true;
 
3405
                                }
 
3406
                        }
 
3407
 
 
3408
                        protected override void LazyPublishMethods()
 
3409
                        {
 
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))
 
3413
                                {
 
3414
                                        AddMethod(list, ctor);
 
3415
                                }
 
3416
                                foreach(MethodInfo method in type.GetMethods(bindingFlags))
 
3417
                                {
 
3418
                                        AddMethod(list, method);
 
3419
                                }
 
3420
                                // if we're a remapped interface, we need to get the methods from the real interface
 
3421
                                if(remappedType.IsInterface)
 
3422
                                {
 
3423
                                        Type nestedHelper = type.GetNestedType("__Helper", BindingFlags.Public | BindingFlags.Static);
 
3424
                                        foreach(RemappedInterfaceMethodAttribute m in AttributeHelper.GetRemappedInterfaceMethods(type))
 
3425
                                        {
 
3426
                                                MethodInfo method = remappedType.GetMethod(m.MappedTo);
 
3427
                                                MethodInfo mbHelper = method;
 
3428
                                                ExModifiers modifiers = AttributeHelper.GetModifiers(method, false);
 
3429
                                                string name;
 
3430
                                                string sig;
 
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)
 
3436
                                                {
 
3437
                                                        mbHelper = nestedHelper.GetMethod(m.Name);
 
3438
                                                        if(mbHelper == null)
 
3439
                                                        {
 
3440
                                                                mbHelper = method;
 
3441
                                                        }
 
3442
                                                }
 
3443
                                                MethodWrapper mw = new CompiledRemappedMethodWrapper(this, m.Name, sig, method, retType, paramTypes, modifiers, false, mbHelper, null);
 
3444
                                                mw.SetDeclaredExceptions(m.Throws);
 
3445
                                                list.Add(mw);
 
3446
                                        }
 
3447
                                }
 
3448
                                SetMethods(list.ToArray());
 
3449
                        }
 
3450
 
 
3451
                        private void AddMethod(List<MethodWrapper> list, MethodBase method)
 
3452
                        {
 
3453
                                if(!AttributeHelper.IsHideFromJava(method)
 
3454
                                        && (remappedType.IsSealed || !method.Name.StartsWith("instancehelper_"))
 
3455
                                        && (!remappedType.IsSealed || method.IsStatic))
 
3456
                                {
 
3457
                                        list.Add(CreateRemappedMethodWrapper(method));
 
3458
                                }
 
3459
                        }
 
3460
 
 
3461
                        protected override void LazyPublishFields()
 
3462
                        {
 
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)
 
3466
                                {
 
3467
                                        if(!AttributeHelper.IsHideFromJava(field))
 
3468
                                        {
 
3469
                                                list.Add(CreateFieldWrapper(field));
 
3470
                                        }
 
3471
                                }
 
3472
                                SetFields(list.ToArray());
 
3473
                        }
 
3474
 
 
3475
                        private MethodWrapper CreateRemappedMethodWrapper(MethodBase mb)
 
3476
                        {
 
3477
                                ExModifiers modifiers = AttributeHelper.GetModifiers(mb, false);
 
3478
                                string name;
 
3479
                                string sig;
 
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)
 
3488
                                {
 
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++)
 
3493
                                        {
 
3494
                                                argTypes[i + 1] = parameters[i].ParameterType;
 
3495
                                        }
 
3496
                                        MethodInfo helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null);
 
3497
                                        if(helper != null)
 
3498
                                        {
 
3499
                                                mbHelper = helper;
 
3500
                                        }
 
3501
                                        mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null);
 
3502
                                }
 
3503
                                return new CompiledRemappedMethodWrapper(this, name, sig, mb, retType, paramTypes, modifiers, hideFromReflection, mbHelper, mbNonvirtualHelper);
 
3504
                        }
 
3505
                }
 
3506
 
 
3507
                private sealed class CompiledGhostTypeWrapper : CompiledTypeWrapper
 
3508
                {
 
3509
                        private FieldInfo ghostRefField;
 
3510
                        private Type typeAsBaseType;
 
3511
 
 
3512
                        internal CompiledGhostTypeWrapper(string name, Type type)
 
3513
                                : base(name, type)
 
3514
                        {
 
3515
                        }
 
3516
 
 
3517
                        internal override Type TypeAsBaseType
 
3518
                        {
 
3519
                                get
 
3520
                                {
 
3521
                                        if(typeAsBaseType == null)
 
3522
                                        {
 
3523
                                                typeAsBaseType = type.GetNestedType("__Interface");
 
3524
                                        }
 
3525
                                        return typeAsBaseType;
 
3526
                                }
 
3527
                        }
 
3528
 
 
3529
                        internal override FieldInfo GhostRefField
 
3530
                        {
 
3531
                                get
 
3532
                                {
 
3533
                                        if(ghostRefField == null)
 
3534
                                        {
 
3535
                                                ghostRefField = type.GetField("__<ref>");
 
3536
                                        }
 
3537
                                        return ghostRefField;
 
3538
                                }
 
3539
                        }
 
3540
 
 
3541
                        internal override bool IsGhost
 
3542
                        {
 
3543
                                get
 
3544
                                {
 
3545
                                        return true;
 
3546
                                }
 
3547
                        }
 
3548
                }
 
3549
 
 
3550
                internal static string GetName(Type type)
 
3551
                {
 
3552
                        Debug.Assert(!type.HasElementType);
 
3553
                        Debug.Assert(!type.IsGenericType);
 
3554
                        Debug.Assert(AttributeHelper.IsJavaModule(type.Module));
 
3555
 
 
3556
                        // look for our custom attribute, that contains the real name of the type (for inner classes)
 
3557
                        InnerClassAttribute attr = AttributeHelper.GetInnerClass(type);
 
3558
                        if(attr != null)
 
3559
                        {
 
3560
                                string name = attr.InnerClassName;
 
3561
                                if(name != null)
 
3562
                                {
 
3563
                                        return name;
 
3564
                                }
 
3565
                                if(type.DeclaringType != null)
 
3566
                                {
 
3567
                                        return GetName(type.DeclaringType) + "$" + TypeNameUtil.Unescape(type.Name);
 
3568
                                }
 
3569
                        }
 
3570
                        return TypeNameUtil.Unescape(type.FullName);
 
3571
                }
 
3572
 
 
3573
                private static TypeWrapper GetBaseTypeWrapper(Type type)
 
3574
                {
 
3575
                        if(type.IsInterface || AttributeHelper.IsGhostInterface(type))
 
3576
                        {
 
3577
                                return null;
 
3578
                        }
 
3579
                        else if(type.BaseType == null)
 
3580
                        {
 
3581
                                // System.Object must appear to be derived from java.lang.Object
 
3582
                                return CoreClasses.java.lang.Object.Wrapper;
 
3583
                        }
 
3584
                        else
 
3585
                        {
 
3586
                                RemappedTypeAttribute attr = AttributeHelper.GetRemappedType(type);
 
3587
                                if(attr != null)
 
3588
                                {
 
3589
                                        if(attr.Type == Types.Object)
 
3590
                                        {
 
3591
                                                return null;
 
3592
                                        }
 
3593
                                        else
 
3594
                                        {
 
3595
                                                return CoreClasses.java.lang.Object.Wrapper;
 
3596
                                        }
 
3597
                                }
 
3598
                                else if(ClassLoaderWrapper.IsRemappedType(type.BaseType))
 
3599
                                {
 
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);
 
3602
                                }
 
3603
                                TypeWrapper tw = null;
 
3604
                                while(tw == null)
 
3605
                                {
 
3606
                                        type = type.BaseType;
 
3607
                                        tw = ClassLoaderWrapper.GetWrapperFromType(type);
 
3608
                                }
 
3609
                                return tw;
 
3610
                        }
 
3611
                }
 
3612
 
 
3613
                private CompiledTypeWrapper(ExModifiers exmod, string name)
 
3614
                        : base(exmod.Modifiers, name)
 
3615
                {
 
3616
                        this.IsInternal = exmod.IsInternal;
 
3617
                }
 
3618
 
 
3619
                private CompiledTypeWrapper(string name, Type type)
 
3620
                        : this(GetModifiers(type), name)
 
3621
                {
 
3622
                        Debug.Assert(!(type is TypeBuilder));
 
3623
                        Debug.Assert(!type.Name.EndsWith("[]"));
 
3624
 
 
3625
                        this.type = type;
 
3626
                }
 
3627
 
 
3628
                internal override TypeWrapper BaseTypeWrapper
 
3629
                {
 
3630
                        get { return baseTypeWrapper ?? (baseTypeWrapper = GetBaseTypeWrapper(type)); }
 
3631
                }
 
3632
 
 
3633
                internal override ClassLoaderWrapper GetClassLoader()
 
3634
                {
 
3635
                        return AssemblyClassLoader.FromAssembly(type.Assembly);
 
3636
                }
 
3637
 
 
3638
                private static ExModifiers GetModifiers(Type type)
 
3639
                {
 
3640
                        ModifiersAttribute attr = AttributeHelper.GetModifiersAttribute(type);
 
3641
                        if(attr != null)
 
3642
                        {
 
3643
                                return new ExModifiers(attr.Modifiers, attr.IsInternal);
 
3644
                        }
 
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)
 
3649
                        {
 
3650
                                modifiers |= Modifiers.Public;
 
3651
                        }
 
3652
                        if(type.IsSealed)
 
3653
                        {
 
3654
                                modifiers |= Modifiers.Final;
 
3655
                        }
 
3656
                        if(type.IsAbstract)
 
3657
                        {
 
3658
                                modifiers |= Modifiers.Abstract;
 
3659
                        }
 
3660
                        if(type.IsInterface)
 
3661
                        {
 
3662
                                modifiers |= Modifiers.Interface;
 
3663
                        }
 
3664
                        else
 
3665
                        {
 
3666
                                modifiers |= Modifiers.Super;
 
3667
                        }
 
3668
                        return new ExModifiers(modifiers, false);
 
3669
                }
 
3670
 
 
3671
                internal override bool HasStaticInitializer
 
3672
                {
 
3673
                        get
 
3674
                        {
 
3675
                                if(!clinitMethodSet)
 
3676
                                {
 
3677
                                        clinitMethod = type.GetMethod("__<clinit>", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
 
3678
                                        clinitMethodSet = true;
 
3679
                                }
 
3680
                                return clinitMethod != null;
 
3681
                        }
 
3682
                }
 
3683
 
 
3684
                internal override TypeWrapper[] Interfaces
 
3685
                {
 
3686
                        get
 
3687
                        {
 
3688
                                if(interfaces == null)
 
3689
                                {
 
3690
                                        interfaces = GetInterfaces();
 
3691
                                }
 
3692
                                return interfaces;
 
3693
                        }
 
3694
                }
 
3695
 
 
3696
                private TypeWrapper[] GetInterfaces()
 
3697
                {
 
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);
 
3703
                        if (attr == null)
 
3704
                        {
 
3705
                                return TypeWrapper.EmptyArray;
 
3706
                        }
 
3707
                        string[] interfaceNames = attr.Interfaces;
 
3708
                        TypeWrapper[] interfaceWrappers = new TypeWrapper[interfaceNames.Length];
 
3709
                        if (this.IsRemapped)
 
3710
                        {
 
3711
                                for (int i = 0; i < interfaceWrappers.Length; i++)
 
3712
                                {
 
3713
                                        interfaceWrappers[i] = ClassLoaderWrapper.LoadClassCritical(interfaceNames[i]);
 
3714
                                }
 
3715
                        }
 
3716
                        else
 
3717
                        {
 
3718
                                TypeWrapper[] typeWrappers = GetImplementedInterfacesAsTypeWrappers(type);
 
3719
                                for (int i = 0; i < interfaceWrappers.Length; i++)
 
3720
                                {
 
3721
                                        for (int j = 0; j < typeWrappers.Length; j++)
 
3722
                                        {
 
3723
                                                if (typeWrappers[j].Name == interfaceNames[i])
 
3724
                                                {
 
3725
                                                        interfaceWrappers[i] = typeWrappers[j];
 
3726
                                                        break;
 
3727
                                                }
 
3728
                                        }
 
3729
                                        if (interfaceWrappers[i] == null)
 
3730
                                        {
 
3731
#if STATIC_COMPILER
 
3732
                                                throw new FatalCompilerErrorException(Message.UnableToResolveInterface, interfaceNames[i], this);
 
3733
#else
 
3734
                                                JVM.CriticalFailure("Unable to resolve interface " + interfaceNames[i] + " on type " + this, null);
 
3735
#endif
 
3736
                                        }
 
3737
                                }
 
3738
                        }
 
3739
                        return interfaceWrappers;
 
3740
                }
 
3741
 
 
3742
                internal override TypeWrapper[] InnerClasses
 
3743
                {
 
3744
                        get
 
3745
                        {
 
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++)
 
3749
                                {
 
3750
                                        if(nestedTypes[i].Name.EndsWith("Attribute", StringComparison.Ordinal)
 
3751
                                                && nestedTypes[i].IsClass
 
3752
                                                && nestedTypes[i].BaseType.FullName == "ikvm.internal.AnnotationAttributeBase")
 
3753
                                        {
 
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)
 
3756
                                                continue;
 
3757
                                        }
 
3758
                                        if(!AttributeHelper.IsHideFromJava(nestedTypes[i]))
 
3759
                                        {
 
3760
                                                wrappers.Add(ClassLoaderWrapper.GetWrapperFromType(nestedTypes[i]));
 
3761
                                        }
 
3762
                                }
 
3763
                                foreach(string s in AttributeHelper.GetNonNestedInnerClasses(type))
 
3764
                                {
 
3765
                                        wrappers.Add(GetClassLoader().LoadClassByDottedName(s));
 
3766
                                }
 
3767
                                return wrappers.ToArray();
 
3768
                        }
 
3769
                }
 
3770
 
 
3771
                internal override TypeWrapper DeclaringTypeWrapper
 
3772
                {
 
3773
                        get
 
3774
                        {
 
3775
                                Type declaringType = type.DeclaringType;
 
3776
                                if(declaringType != null)
 
3777
                                {
 
3778
                                        return ClassLoaderWrapper.GetWrapperFromType(declaringType);
 
3779
                                }
 
3780
                                string decl = AttributeHelper.GetNonNestedOuterClasses(type);
 
3781
                                if(decl != null)
 
3782
                                {
 
3783
                                        return GetClassLoader().LoadClassByDottedName(decl);
 
3784
                                }
 
3785
                                return null;
 
3786
                        }
 
3787
                }
 
3788
 
 
3789
                internal override Modifiers ReflectiveModifiers
 
3790
                {
 
3791
                        get
 
3792
                        {
 
3793
                                if (reflectiveModifiers == 0)
 
3794
                                {
 
3795
                                        Modifiers mods;
 
3796
                                        InnerClassAttribute attr = AttributeHelper.GetInnerClass(type);
 
3797
                                        if (attr != null)
 
3798
                                        {
 
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;
 
3802
                                        }
 
3803
                                        else
 
3804
                                        {
 
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;
 
3808
                                        }
 
3809
                                        if (IsInterface)
 
3810
                                        {
 
3811
                                                mods |= Modifiers.Abstract;
 
3812
                                        }
 
3813
                                        reflectiveModifiers = mods;
 
3814
                                }
 
3815
                                return reflectiveModifiers;
 
3816
                        }
 
3817
                }
 
3818
 
 
3819
                internal override Type TypeAsBaseType
 
3820
                {
 
3821
                        get
 
3822
                        {
 
3823
                                return type;
 
3824
                        }
 
3825
                }
 
3826
 
 
3827
                private void SigTypePatchUp(string sigtype, ref TypeWrapper type)
 
3828
                {
 
3829
                        if(sigtype != type.SigName)
 
3830
                        {
 
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)
 
3833
                                if(type.IsArray)
 
3834
                                {
 
3835
                                        type = GetClassLoader().FieldTypeWrapperFromSig(sigtype);
 
3836
                                }
 
3837
                                else if(type.IsPrimitive)
 
3838
                                {
 
3839
                                        type = DotNetTypeWrapper.GetWrapperFromDotNetType(type.TypeAsTBD);
 
3840
                                        if(sigtype != type.SigName)
 
3841
                                        {
 
3842
                                                throw new InvalidOperationException();
 
3843
                                        }
 
3844
                                }
 
3845
                                else if(type.IsNonPrimitiveValueType)
 
3846
                                {
 
3847
                                        // this can't happen and even if it does happen we cannot return
 
3848
                                        // UnloadableTypeWrapper because that would result in incorrect code
 
3849
                                        // being generated
 
3850
                                        throw new InvalidOperationException();
 
3851
                                }
 
3852
                                else
 
3853
                                {
 
3854
                                        if(sigtype[0] == 'L')
 
3855
                                        {
 
3856
                                                sigtype = sigtype.Substring(1, sigtype.Length - 2);
 
3857
                                        }
 
3858
                                        try
 
3859
                                        {
 
3860
                                                TypeWrapper tw = GetClassLoader().LoadClassByDottedNameFast(sigtype);
 
3861
                                                if(tw != null && tw.IsRemapped)
 
3862
                                                {
 
3863
                                                        type = tw;
 
3864
                                                        return;
 
3865
                                                }
 
3866
                                        }
 
3867
                                        catch(RetargetableJavaException)
 
3868
                                        {
 
3869
                                        }
 
3870
                                        type = new UnloadableTypeWrapper(sigtype);
 
3871
                                }
 
3872
                        }
 
3873
                }
 
3874
 
 
3875
                private static void ParseSig(string sig, out string[] sigparam, out string sigret)
 
3876
                {
 
3877
                        List<string> list = new List<string>();
 
3878
                        int pos = 1;
 
3879
                        for(;;)
 
3880
                        {
 
3881
                                switch(sig[pos])
 
3882
                                {
 
3883
                                        case 'L':
 
3884
                                        {
 
3885
                                                int end = sig.IndexOf(';', pos) + 1;
 
3886
                                                list.Add(sig.Substring(pos, end - pos));
 
3887
                                                pos = end;
 
3888
                                                break;
 
3889
                                        }
 
3890
                                        case '[':
 
3891
                                        {
 
3892
                                                int skip = 1;
 
3893
                                                while(sig[pos + skip] == '[') skip++;
 
3894
                                                if(sig[pos + skip] == 'L')
 
3895
                                                {
 
3896
                                                        int end = sig.IndexOf(';', pos) + 1;
 
3897
                                                        list.Add(sig.Substring(pos, end - pos));
 
3898
                                                        pos = end;
 
3899
                                                }
 
3900
                                                else
 
3901
                                                {
 
3902
                                                        skip++;
 
3903
                                                        list.Add(sig.Substring(pos, skip));
 
3904
                                                        pos += skip;
 
3905
                                                }
 
3906
                                                break;
 
3907
                                        }
 
3908
                                        case ')':
 
3909
                                                sigparam = list.ToArray();
 
3910
                                                sigret = sig.Substring(pos + 1);
 
3911
                                                return;
 
3912
                                        default:
 
3913
                                                list.Add(sig.Substring(pos, 1));
 
3914
                                                pos++;
 
3915
                                                break;
 
3916
                                }
 
3917
                        }
 
3918
                }
 
3919
 
 
3920
                private bool IsCallerID(Type type)
 
3921
                {
 
3922
#if STUB_GENERATOR
 
3923
                        return type.FullName == "ikvm.internal.CallerID";
 
3924
#else
 
3925
                        return type == CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType
 
3926
                                && GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader();
 
3927
#endif
 
3928
                }
 
3929
 
 
3930
                private void GetNameSigFromMethodBase(MethodBase method, out string name, out string sig, out TypeWrapper retType, out TypeWrapper[] paramTypes, ref MemberFlags flags)
 
3931
                {
 
3932
                        retType = method is ConstructorInfo ? PrimitiveTypeWrapper.VOID : GetParameterTypeWrapper(((MethodInfo)method).ReturnParameter);
 
3933
                        ParameterInfo[] parameters = method.GetParameters();
 
3934
                        int len = parameters.Length;
 
3935
                        if(len > 0
 
3936
                                && IsCallerID(parameters[len - 1].ParameterType)
 
3937
                                && !method.DeclaringType.IsInterface)
 
3938
                        {
 
3939
                                len--;
 
3940
                                flags |= MemberFlags.CallerID;
 
3941
                        }
 
3942
                        paramTypes = new TypeWrapper[len];
 
3943
                        for(int i = 0; i < len; i++)
 
3944
                        {
 
3945
                                paramTypes[i] = GetParameterTypeWrapper(parameters[i]);
 
3946
                        }
 
3947
                        NameSigAttribute attr = AttributeHelper.GetNameSig(method);
 
3948
                        if(attr != null)
 
3949
                        {
 
3950
                                name = attr.Name;
 
3951
                                sig = attr.Sig;
 
3952
                                string[] sigparams;
 
3953
                                string sigret;
 
3954
                                ParseSig(sig, out sigparams, out sigret);
 
3955
                                // HACK newhelper methods have a return type, but it should be void
 
3956
                                if(name == "<init>")
 
3957
                                {
 
3958
                                        retType = PrimitiveTypeWrapper.VOID;
 
3959
                                }
 
3960
                                SigTypePatchUp(sigret, ref retType);
 
3961
                                // if we have a remapped method, the paramTypes array contains an additional entry for "this" so we have
 
3962
                                // to remove that
 
3963
                                if(paramTypes.Length == sigparams.Length + 1)
 
3964
                                {
 
3965
                                        TypeWrapper[] temp = paramTypes;
 
3966
                                        paramTypes = new TypeWrapper[sigparams.Length];
 
3967
                                        Array.Copy(temp, 1, paramTypes, 0, paramTypes.Length);
 
3968
                                }
 
3969
                                Debug.Assert(sigparams.Length == paramTypes.Length);
 
3970
                                for(int i = 0; i < sigparams.Length; i++)
 
3971
                                {
 
3972
                                        SigTypePatchUp(sigparams[i], ref paramTypes[i]);
 
3973
                                }
 
3974
                        }
 
3975
                        else
 
3976
                        {
 
3977
                                if(method is ConstructorInfo)
 
3978
                                {
 
3979
                                        name = method.IsStatic ? "<clinit>" : "<init>";
 
3980
                                }
 
3981
                                else
 
3982
                                {
 
3983
                                        name = method.Name;
 
3984
                                        if(name.StartsWith(NamePrefix.Bridge, StringComparison.Ordinal))
 
3985
                                        {
 
3986
                                                name = name.Substring(NamePrefix.Bridge.Length);
 
3987
                                        }
 
3988
                                }
 
3989
                                System.Text.StringBuilder sb = new System.Text.StringBuilder("(");
 
3990
                                foreach(TypeWrapper tw in paramTypes)
 
3991
                                {
 
3992
                                        sb.Append(tw.SigName);
 
3993
                                }
 
3994
                                sb.Append(")");
 
3995
                                sb.Append(retType.SigName);
 
3996
                                sig = sb.ToString();
 
3997
                        }
 
3998
                }
 
3999
 
 
4000
                private sealed class DelegateConstructorMethodWrapper : MethodWrapper
 
4001
                {
 
4002
                        private readonly ConstructorInfo constructor;
 
4003
                        private MethodInfo invoke;
 
4004
 
 
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)
 
4007
                        {
 
4008
                        }
 
4009
 
 
4010
                        internal DelegateConstructorMethodWrapper(TypeWrapper tw, MethodBase method)
 
4011
                                : this(tw, tw.GetClassLoader().LoadClassByDottedName(tw.Name + DotNetTypeWrapper.DelegateInterfaceSuffix), AttributeHelper.GetModifiers(method, false))
 
4012
                        {
 
4013
                                constructor = (ConstructorInfo)method;
 
4014
                        }
 
4015
 
 
4016
                        protected override void DoLinkMethod()
 
4017
                        {
 
4018
                                MethodWrapper mw = GetParameters()[0].GetMethods()[0];
 
4019
                                mw.Link();
 
4020
                                invoke = (MethodInfo)mw.GetMethod();
 
4021
                        }
 
4022
 
 
4023
#if !STUB_GENERATOR
 
4024
                        internal override void EmitNewobj(CodeEmitter ilgen)
 
4025
                        {
 
4026
                                ilgen.Emit(OpCodes.Dup);
 
4027
                                ilgen.Emit(OpCodes.Ldvirtftn, invoke);
 
4028
                                ilgen.Emit(OpCodes.Newobj, constructor);
 
4029
                        }
 
4030
#endif // !STUB_GENERATOR
 
4031
                }
 
4032
 
 
4033
                protected override void LazyPublishMethods()
 
4034
                {
 
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))
 
4039
                        {
 
4040
                                if(isDelegate && !ctor.IsStatic && !AttributeHelper.IsHideFromJava(ctor))
 
4041
                                {
 
4042
                                        methods.Add(new DelegateConstructorMethodWrapper(this, ctor));
 
4043
                                }
 
4044
                                else
 
4045
                                {
 
4046
                                        AddMethodOrConstructor(ctor, methods);
 
4047
                                }
 
4048
                        }
 
4049
                        foreach(MethodInfo method in type.GetMethods(flags))
 
4050
                        {
 
4051
                                AddMethodOrConstructor(method, methods);
 
4052
                        }
 
4053
                        SetMethods(methods.ToArray());
 
4054
                }
 
4055
 
 
4056
                private void AddMethodOrConstructor(MethodBase method, List<MethodWrapper> methods)
 
4057
                {
 
4058
                        if(!AttributeHelper.IsHideFromJava(method))
 
4059
                        {
 
4060
                                if(method.IsSpecialName && method.Name.StartsWith("__<"))
 
4061
                                {
 
4062
                                        // skip
 
4063
                                }
 
4064
                                else
 
4065
                                {
 
4066
                                        string name;
 
4067
                                        string sig;
 
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);
 
4075
                                        if(mods.IsInternal)
 
4076
                                        {
 
4077
                                                flags |= MemberFlags.InternalAccess;
 
4078
                                        }
 
4079
                                        if(hideFromReflection && name.StartsWith(NamePrefix.AccessStub, StringComparison.Ordinal))
 
4080
                                        {
 
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));
 
4086
                                                return;
 
4087
                                        }
 
4088
                                        MethodWrapper mw;
 
4089
                                        if (IsGhost)
 
4090
                                        {
 
4091
                                                Type[] types = new Type[paramTypes.Length];
 
4092
                                                for (int i = 0; i < types.Length; i++)
 
4093
                                                {
 
4094
                                                        types[i] = paramTypes[i].TypeAsSignatureType;
 
4095
                                                }
 
4096
                                                MethodInfo ifmethod = TypeAsBaseType.GetMethod(method.Name, types);
 
4097
                                                mw = new GhostMethodWrapper(this, name, sig, ifmethod, (MethodInfo)method, retType, paramTypes, mods.Modifiers, flags);
 
4098
                                        }
 
4099
                                        else
 
4100
                                        {
 
4101
                                                mw = new TypicalMethodWrapper(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags);
 
4102
                                        }
 
4103
                                        if (mw.HasNonPublicTypeInSignature)
 
4104
                                        {
 
4105
                                                if (mi != null)
 
4106
                                                {
 
4107
                                                        MethodInfo stubVirt;
 
4108
                                                        MethodInfo stubNonVirt;
 
4109
                                                        if (GetType2AccessStubs(name, sig, out stubVirt, out stubNonVirt))
 
4110
                                                        {
 
4111
                                                                mw = new AccessStubMethodWrapper(this, name, sig, mi, stubVirt, stubNonVirt ?? stubVirt, retType, paramTypes, mw.Modifiers, flags);
 
4112
                                                        }
 
4113
                                                }
 
4114
                                                else
 
4115
                                                {
 
4116
                                                        ConstructorInfo stub;
 
4117
                                                        if (GetType2AccessStub(sig, out stub))
 
4118
                                                        {
 
4119
                                                                mw = new AccessStubConstructorMethodWrapper(this, sig, (ConstructorInfo)method, stub, paramTypes, mw.Modifiers, flags);
 
4120
                                                        }
 
4121
                                                }
 
4122
                                        }
 
4123
                                        methods.Add(mw);
 
4124
                                }
 
4125
                        }
 
4126
                }
 
4127
 
 
4128
                private bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out MethodInfo stubNonVirt)
 
4129
                {
 
4130
                        stubVirt = null;
 
4131
                        stubNonVirt = null;
 
4132
                        const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
 
4133
                        foreach (MethodInfo method in type.GetMethods(flags))
 
4134
                        {
 
4135
                                if (AttributeHelper.IsHideFromJava(method))
 
4136
                                {
 
4137
                                        NameSigAttribute attr = AttributeHelper.GetNameSig(method);
 
4138
                                        if (attr != null && attr.Name == name && attr.Sig == sig)
 
4139
                                        {
 
4140
                                                if (method.Name.StartsWith(NamePrefix.NonVirtual, StringComparison.Ordinal))
 
4141
                                                {
 
4142
                                                        stubNonVirt = method;
 
4143
                                                }
 
4144
                                                else
 
4145
                                                {
 
4146
                                                        stubVirt = method;
 
4147
                                                }
 
4148
                                        }
 
4149
                                }
 
4150
                        }
 
4151
                        return stubVirt != null;
 
4152
                }
 
4153
 
 
4154
                private bool GetType2AccessStub(string sig, out ConstructorInfo stub)
 
4155
                {
 
4156
                        stub = null;
 
4157
                        const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
 
4158
                        foreach (ConstructorInfo ctor in type.GetConstructors(flags))
 
4159
                        {
 
4160
                                if (AttributeHelper.IsHideFromJava(ctor))
 
4161
                                {
 
4162
                                        NameSigAttribute attr = AttributeHelper.GetNameSig(ctor);
 
4163
                                        if (attr != null && attr.Sig == sig)
 
4164
                                        {
 
4165
                                                stub = ctor;
 
4166
                                        }
 
4167
                                }
 
4168
                        }
 
4169
                        return stub != null;
 
4170
                }
 
4171
 
 
4172
                private static int SortFieldByToken(FieldInfo field1, FieldInfo field2)
 
4173
                {
 
4174
                        return field1.MetadataToken.CompareTo(field2.MetadataToken);
 
4175
                }
 
4176
 
 
4177
                protected override void LazyPublishFields()
 
4178
                {
 
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)
 
4187
                        {
 
4188
                                if(AttributeHelper.IsHideFromJava(field))
 
4189
                                {
 
4190
                                        if(field.Name.StartsWith(NamePrefix.Type2AccessStubBackingField, StringComparison.Ordinal))
 
4191
                                        {
 
4192
                                                TypeWrapper tw = GetFieldTypeWrapper(field);
 
4193
                                                string name = field.Name.Substring(NamePrefix.Type2AccessStubBackingField.Length);
 
4194
                                                for(int i = 0; i < properties.Length; i++)
 
4195
                                                {
 
4196
                                                        if(properties[i] != null
 
4197
                                                                && name == properties[i].Name
 
4198
                                                                && MatchTypes(tw, GetPropertyTypeWrapper(properties[i])))
 
4199
                                                        {
 
4200
                                                                fields.Add(new CompiledAccessStubFieldWrapper(this, properties[i], field, tw));
 
4201
                                                                properties[i] = null;
 
4202
                                                                break;
 
4203
                                                        }
 
4204
                                                }
 
4205
                                        }
 
4206
                                }
 
4207
                                else
 
4208
                                {
 
4209
                                        if(field.IsSpecialName && field.Name.StartsWith("__<", StringComparison.Ordinal))
 
4210
                                        {
 
4211
                                                // skip
 
4212
                                        }
 
4213
                                        else
 
4214
                                        {
 
4215
                                                fields.Add(CreateFieldWrapper(field));
 
4216
                                        }
 
4217
                                }
 
4218
                        }
 
4219
                        foreach(PropertyInfo property in properties)
 
4220
                        {
 
4221
                                if(property != null)
 
4222
                                {
 
4223
                                        AddPropertyFieldWrapper(fields, property, null);
 
4224
                                }
 
4225
                        }
 
4226
                        SetFields(fields.ToArray());
 
4227
                }
 
4228
 
 
4229
                private static bool MatchTypes(TypeWrapper tw1, TypeWrapper tw2)
 
4230
                {
 
4231
                        return tw1 == tw2 || (tw1.IsUnloadable && tw2.IsUnloadable && tw1.Name == tw2.Name);
 
4232
                }
 
4233
 
 
4234
                private void AddPropertyFieldWrapper(List<FieldWrapper> fields, PropertyInfo property, FieldInfo field)
 
4235
                {
 
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))
 
4239
                        {
 
4240
                                // is it a type 1 access stub?
 
4241
                                if(AttributeHelper.IsHideFromReflection(property))
 
4242
                                {
 
4243
                                        fields.Add(new CompiledAccessStubFieldWrapper(this, property, GetPropertyTypeWrapper(property)));
 
4244
                                }
 
4245
                                else
 
4246
                                {
 
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)));
 
4251
                                }
 
4252
                        }
 
4253
                }
 
4254
 
 
4255
                private sealed class CompiledRemappedMethodWrapper : SmartMethodWrapper
 
4256
                {
 
4257
                        private MethodInfo mbHelper;
 
4258
#if !STATIC_COMPILER
 
4259
                        private MethodInfo mbNonvirtualHelper;
 
4260
#endif
 
4261
 
 
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))
 
4265
                        {
 
4266
                                this.mbHelper = mbHelper;
 
4267
#if !STATIC_COMPILER
 
4268
                                this.mbNonvirtualHelper = mbNonvirtualHelper;
 
4269
#endif
 
4270
                        }
 
4271
 
 
4272
#if !STUB_GENERATOR
 
4273
                        protected override void CallImpl(CodeEmitter ilgen)
 
4274
                        {
 
4275
                                MethodBase mb = GetMethod();
 
4276
                                MethodInfo mi = mb as MethodInfo;
 
4277
                                if(mi != null)
 
4278
                                {
 
4279
                                        if(!IsStatic && IsFinal)
 
4280
                                        {
 
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);
 
4285
                                        }
 
4286
                                        else
 
4287
                                        {
 
4288
                                                ilgen.Emit(OpCodes.Call, mi);
 
4289
                                        }
 
4290
                                }
 
4291
                                else
 
4292
                                {
 
4293
                                        ilgen.Emit(OpCodes.Call, mb);
 
4294
                                }
 
4295
                        }
 
4296
 
 
4297
                        protected override void CallvirtImpl(CodeEmitter ilgen)
 
4298
                        {
 
4299
                                Debug.Assert(!mbHelper.IsStatic || mbHelper.Name.StartsWith("instancehelper_") || mbHelper.DeclaringType.Name == "__Helper");
 
4300
                                if(mbHelper.IsPublic)
 
4301
                                {
 
4302
                                        ilgen.Emit(mbHelper.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mbHelper);
 
4303
                                }
 
4304
                                else
 
4305
                                {
 
4306
                                        // HACK the helper is not public, this means that we're dealing with finalize or clone
 
4307
                                        ilgen.Emit(OpCodes.Callvirt, GetMethod());
 
4308
                                }
 
4309
                        }
 
4310
 
 
4311
                        protected override void NewobjImpl(CodeEmitter ilgen)
 
4312
                        {
 
4313
                                MethodBase mb = GetMethod();
 
4314
                                MethodInfo mi = mb as MethodInfo;
 
4315
                                if(mi != null)
 
4316
                                {
 
4317
                                        Debug.Assert(mi.Name == "newhelper");
 
4318
                                        ilgen.Emit(OpCodes.Call, mi);
 
4319
                                }
 
4320
                                else
 
4321
                                {
 
4322
                                        ilgen.Emit(OpCodes.Newobj, mb);
 
4323
                                }
 
4324
                        }
 
4325
#endif // !STUB_GENERATOR
 
4326
 
 
4327
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
 
4328
                        [HideFromJava]
 
4329
                        protected override object InvokeNonvirtualRemapped(object obj, object[] args)
 
4330
                        {
 
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;
 
4336
                                if (mi == null)
 
4337
                                {
 
4338
                                        mi = mbHelper;
 
4339
                                }
 
4340
                                object[] args1 = new object[args.Length + 1];
 
4341
                                args1[0] = obj;
 
4342
                                args.CopyTo(args1, 1);
 
4343
                                return mi.Invoke(null, args1);
 
4344
                        }
 
4345
 
 
4346
                        internal override void EmitCallvirtReflect(CodeEmitter ilgen)
 
4347
                        {
 
4348
                                MethodBase mb = mbHelper != null ? mbHelper : GetMethod();
 
4349
                                ilgen.Emit(mb.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mb);
 
4350
                        }
 
4351
#endif // !STATIC_COMPILER
 
4352
 
 
4353
                        internal string GetGenericSignature()
 
4354
                        {
 
4355
                                SignatureAttribute attr = AttributeHelper.GetSignature(mbHelper != null ? mbHelper : GetMethod());
 
4356
                                if(attr != null)
 
4357
                                {
 
4358
                                        return attr.Signature;
 
4359
                                }
 
4360
                                return null;
 
4361
                        }
 
4362
                }
 
4363
 
 
4364
                private static TypeWrapper TypeWrapperFromModOpt(Type[] modopt)
 
4365
                {
 
4366
                        int rank = 0;
 
4367
                        TypeWrapper tw = null;
 
4368
                        foreach (Type type in modopt)
 
4369
                        {
 
4370
                                if (type == JVM.LoadType(typeof(IKVM.Attributes.AccessStub)))
 
4371
                                {
 
4372
                                        // ignore
 
4373
                                }
 
4374
                                else if (type == Types.Array)
 
4375
                                {
 
4376
                                        rank++;
 
4377
                                }
 
4378
                                else if (type == Types.Void || type.IsPrimitive || ClassLoaderWrapper.IsRemappedType(type))
 
4379
                                {
 
4380
                                        tw = DotNetTypeWrapper.GetWrapperFromDotNetType(type);
 
4381
                                }
 
4382
                                else
 
4383
                                {
 
4384
                                        tw = ClassLoaderWrapper.GetWrapperFromType(type)
 
4385
                                                ?? new UnloadableTypeWrapper(TypeNameUtil.UnmangleNestedTypeName(type.Name), type);
 
4386
                                }
 
4387
                        }
 
4388
                        if (rank != 0)
 
4389
                        {
 
4390
                                tw = tw.MakeArrayType(rank);
 
4391
                        }
 
4392
                        return tw;
 
4393
                }
 
4394
 
 
4395
                private static TypeWrapper GetPropertyTypeWrapper(PropertyInfo property)
 
4396
                {
 
4397
                        return TypeWrapperFromModOpt(property.GetOptionalCustomModifiers())
 
4398
                                ?? ClassLoaderWrapper.GetWrapperFromType(property.PropertyType);
 
4399
                }
 
4400
 
 
4401
                private static TypeWrapper GetFieldTypeWrapper(FieldInfo field)
 
4402
                {
 
4403
                        return TypeWrapperFromModOpt(field.GetOptionalCustomModifiers())
 
4404
                                ?? ClassLoaderWrapper.GetWrapperFromType(field.FieldType);
 
4405
                }
 
4406
 
 
4407
                private static TypeWrapper GetParameterTypeWrapper(ParameterInfo param)
 
4408
                {
 
4409
                        TypeWrapper tw = TypeWrapperFromModOpt(param.GetOptionalCustomModifiers());
 
4410
                        if (tw != null)
 
4411
                        {
 
4412
                                return tw;
 
4413
                        }
 
4414
                        Type parameterType = param.ParameterType;
 
4415
                        if (parameterType.IsByRef)
 
4416
                        {
 
4417
                                // we only support ByRef parameters for automatically generated delegate invoke stubs
 
4418
                                parameterType = parameterType.GetElementType().MakeArrayType();
 
4419
                        }
 
4420
                        return ClassLoaderWrapper.GetWrapperFromType(parameterType);
 
4421
                }
 
4422
 
 
4423
                private FieldWrapper CreateFieldWrapper(FieldInfo field)
 
4424
                {
 
4425
                        ExModifiers modifiers = AttributeHelper.GetModifiers(field, false);
 
4426
                        TypeWrapper type = GetFieldTypeWrapper(field);
 
4427
 
 
4428
                        if(field.IsLiteral)
 
4429
                        {
 
4430
                                MemberFlags flags = MemberFlags.None;
 
4431
                                if(AttributeHelper.IsHideFromReflection(field))
 
4432
                                {
 
4433
                                        flags |= MemberFlags.HideFromReflection;
 
4434
                                }
 
4435
                                if(modifiers.IsInternal)
 
4436
                                {
 
4437
                                        flags |= MemberFlags.InternalAccess;
 
4438
                                }
 
4439
                                return new ConstantFieldWrapper(this, type, field.Name, type.SigName, modifiers.Modifiers, field, null, flags);
 
4440
                        }
 
4441
                        else
 
4442
                        {
 
4443
                                return FieldWrapper.Create(this, type, field, field.Name, type.SigName, modifiers);
 
4444
                        }
 
4445
                }
 
4446
 
 
4447
                internal override Type TypeAsTBD
 
4448
                {
 
4449
                        get
 
4450
                        {
 
4451
                                return type;
 
4452
                        }
 
4453
                }
 
4454
 
 
4455
                internal override bool IsMapUnsafeException
 
4456
                {
 
4457
                        get
 
4458
                        {
 
4459
                                return AttributeHelper.IsExceptionIsUnsafeForMapping(type);
 
4460
                        }
 
4461
                }
 
4462
 
 
4463
                internal override void Finish()
 
4464
                {
 
4465
                        if(BaseTypeWrapper != null)
 
4466
                        {
 
4467
                                BaseTypeWrapper.Finish();
 
4468
                        }
 
4469
                        foreach(TypeWrapper tw in this.Interfaces)
 
4470
                        {
 
4471
                                tw.Finish();
 
4472
                        }
 
4473
                }
 
4474
 
 
4475
#if !STUB_GENERATOR
 
4476
                internal override void EmitRunClassConstructor(CodeEmitter ilgen)
 
4477
                {
 
4478
                        if(HasStaticInitializer)
 
4479
                        {
 
4480
                                ilgen.Emit(OpCodes.Call, clinitMethod);
 
4481
                        }
 
4482
                }
 
4483
#endif // !STUB_GENERATOR
 
4484
 
 
4485
                internal override string GetGenericSignature()
 
4486
                {
 
4487
                        SignatureAttribute attr = AttributeHelper.GetSignature(type);
 
4488
                        if(attr != null)
 
4489
                        {
 
4490
                                return attr.Signature;
 
4491
                        }
 
4492
                        return null;
 
4493
                }
 
4494
 
 
4495
                internal override string GetGenericMethodSignature(MethodWrapper mw)
 
4496
                {
 
4497
                        if(mw is CompiledRemappedMethodWrapper)
 
4498
                        {
 
4499
                                return ((CompiledRemappedMethodWrapper)mw).GetGenericSignature();
 
4500
                        }
 
4501
                        MethodBase mb = mw.GetMethod();
 
4502
                        if(mb != null)
 
4503
                        {
 
4504
                                SignatureAttribute attr = AttributeHelper.GetSignature(mb);
 
4505
                                if(attr != null)
 
4506
                                {
 
4507
                                        return attr.Signature;
 
4508
                                }
 
4509
                        }
 
4510
                        return null;
 
4511
                }
 
4512
 
 
4513
                internal override string GetGenericFieldSignature(FieldWrapper fw)
 
4514
                {
 
4515
                        FieldInfo fi = fw.GetField();
 
4516
                        if(fi != null)
 
4517
                        {
 
4518
                                SignatureAttribute attr = AttributeHelper.GetSignature(fi);
 
4519
                                if(attr != null)
 
4520
                                {
 
4521
                                        return attr.Signature;
 
4522
                                }
 
4523
                        }
 
4524
                        return null;
 
4525
                }
 
4526
 
 
4527
#if !STATIC_COMPILER && !STUB_GENERATOR
 
4528
                internal override string[] GetEnclosingMethod()
 
4529
                {
 
4530
                        EnclosingMethodAttribute enc = AttributeHelper.GetEnclosingMethodAttribute(type);
 
4531
                        if (enc != null)
 
4532
                        {
 
4533
                                return new string[] { enc.ClassName, enc.MethodName, enc.MethodSignature };
 
4534
                        }
 
4535
                        return null;
 
4536
                }
 
4537
 
 
4538
                internal override object[] GetDeclaredAnnotations()
 
4539
                {
 
4540
                        return type.GetCustomAttributes(false);
 
4541
                }
 
4542
 
 
4543
                internal override object[] GetMethodAnnotations(MethodWrapper mw)
 
4544
                {
 
4545
                        MethodBase mb = mw.GetMethod();
 
4546
                        if(mb == null)
 
4547
                        {
 
4548
                                // delegate constructor
 
4549
                                return null;
 
4550
                        }
 
4551
                        return mb.GetCustomAttributes(false);
 
4552
                }
 
4553
 
 
4554
                internal override object[][] GetParameterAnnotations(MethodWrapper mw)
 
4555
                {
 
4556
                        MethodBase mb = mw.GetMethod();
 
4557
                        if(mb == null)
 
4558
                        {
 
4559
                                // delegate constructor
 
4560
                                return null;
 
4561
                        }
 
4562
                        ParameterInfo[] parameters = mb.GetParameters();
 
4563
                        int skip = 0;
 
4564
                        if(mb.IsStatic && !mw.IsStatic && mw.Name != "<init>")
 
4565
                        {
 
4566
                                skip = 1;
 
4567
                        }
 
4568
                        int skipEnd = 0;
 
4569
                        if(mw.HasCallerID)
 
4570
                        {
 
4571
                                skipEnd = 1;
 
4572
                        }
 
4573
                        object[][] attribs = new object[parameters.Length - skip - skipEnd][];
 
4574
                        for(int i = skip; i < parameters.Length - skipEnd; i++)
 
4575
                        {
 
4576
                                attribs[i - skip] = parameters[i].GetCustomAttributes(false);
 
4577
                        }
 
4578
                        return attribs;
 
4579
                }
 
4580
 
 
4581
                internal override object[] GetFieldAnnotations(FieldWrapper fw)
 
4582
                {
 
4583
                        FieldInfo field = fw.GetField();
 
4584
                        if(field != null)
 
4585
                        {
 
4586
                                return field.GetCustomAttributes(false);
 
4587
                        }
 
4588
                        CompiledPropertyFieldWrapper prop = fw as CompiledPropertyFieldWrapper;
 
4589
                        if(prop != null)
 
4590
                        {
 
4591
                                return prop.GetProperty().GetCustomAttributes(false);
 
4592
                        }
 
4593
                        return new object[0];
 
4594
                }
 
4595
#endif
 
4596
 
 
4597
                private sealed class CompiledAnnotation : Annotation
 
4598
                {
 
4599
                        private Type type;
 
4600
 
 
4601
                        internal CompiledAnnotation(Type type)
 
4602
                        {
 
4603
                                this.type = type;
 
4604
                        }
 
4605
 
 
4606
                        private CustomAttributeBuilder MakeCustomAttributeBuilder(object annotation)
 
4607
                        {
 
4608
                                return new CustomAttributeBuilder(type.GetConstructor(new Type[] { JVM.Import(typeof(object[])) }), new object[] { annotation });
 
4609
                        }
 
4610
 
 
4611
                        internal override void Apply(ClassLoaderWrapper loader, TypeBuilder tb, object annotation)
 
4612
                        {
 
4613
                                annotation = QualifyClassNames(loader, annotation);
 
4614
                                tb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4615
                        }
 
4616
 
 
4617
                        internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation)
 
4618
                        {
 
4619
                                annotation = QualifyClassNames(loader, annotation);
 
4620
                                mb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4621
                        }
 
4622
 
 
4623
                        internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation)
 
4624
                        {
 
4625
                                annotation = QualifyClassNames(loader, annotation);
 
4626
                                fb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4627
                        }
 
4628
 
 
4629
                        internal override void Apply(ClassLoaderWrapper loader, ParameterBuilder pb, object annotation)
 
4630
                        {
 
4631
                                annotation = QualifyClassNames(loader, annotation);
 
4632
                                pb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4633
                        }
 
4634
 
 
4635
                        internal override void Apply(ClassLoaderWrapper loader, AssemblyBuilder ab, object annotation)
 
4636
                        {
 
4637
                                annotation = QualifyClassNames(loader, annotation);
 
4638
                                ab.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4639
                        }
 
4640
 
 
4641
                        internal override void Apply(ClassLoaderWrapper loader, PropertyBuilder pb, object annotation)
 
4642
                        {
 
4643
                                annotation = QualifyClassNames(loader, annotation);
 
4644
                                pb.SetCustomAttribute(MakeCustomAttributeBuilder(annotation));
 
4645
                        }
 
4646
 
 
4647
                        internal override bool IsCustomAttribute
 
4648
                        {
 
4649
                                get { return false; }
 
4650
                        }
 
4651
                }
 
4652
 
 
4653
                internal override Annotation Annotation
 
4654
                {
 
4655
                        get
 
4656
                        {
 
4657
                                string annotationAttribute = AttributeHelper.GetAnnotationAttributeType(type);
 
4658
                                if(annotationAttribute != null)
 
4659
                                {
 
4660
                                        return new CompiledAnnotation(type.Assembly.GetType(annotationAttribute, true));
 
4661
                                }
 
4662
                                return null;
 
4663
                        }
 
4664
                }
 
4665
 
 
4666
                internal override Type EnumType
 
4667
                {
 
4668
                        get
 
4669
                        {
 
4670
                                if((this.Modifiers & Modifiers.Enum) != 0)
 
4671
                                {
 
4672
                                        return type.GetNestedType("__Enum");
 
4673
                                }
 
4674
                                return null;
 
4675
                        }
 
4676
                }
 
4677
 
 
4678
#if !STATIC_COMPILER && !STUB_GENERATOR
 
4679
                internal override string GetSourceFileName()
 
4680
                {
 
4681
                        object[] attr = type.GetCustomAttributes(typeof(SourceFileAttribute), false);
 
4682
                        if(attr.Length == 1)
 
4683
                        {
 
4684
                                return ((SourceFileAttribute)attr[0]).SourceFile;
 
4685
                        }
 
4686
                        if(type.Module.IsDefined(typeof(SourceFileAttribute), false))
 
4687
                        {
 
4688
                                return type.Name + ".java";
 
4689
                        }
 
4690
                        return null;
 
4691
                }
 
4692
 
 
4693
                internal override int GetSourceLineNumber(MethodBase mb, int ilOffset)
 
4694
                {
 
4695
                        object[] attr = mb.GetCustomAttributes(typeof(LineNumberTableAttribute), false);
 
4696
                        if(attr.Length == 1)
 
4697
                        {
 
4698
                                return ((LineNumberTableAttribute)attr[0]).GetLineNumber(ilOffset);
 
4699
                        }
 
4700
                        return -1;
 
4701
                }
 
4702
#endif
 
4703
 
 
4704
                internal override bool IsFastClassLiteralSafe
 
4705
                {
 
4706
                        get { return true; }
 
4707
                }
 
4708
        }
 
4709
 
 
4710
        sealed class ArrayTypeWrapper : TypeWrapper
 
4711
        {
 
4712
                private static TypeWrapper[] interfaces;
 
4713
                private static MethodInfo clone;
 
4714
                private readonly TypeWrapper ultimateElementTypeWrapper;
 
4715
                private Type arrayType;
 
4716
                private bool finished;
 
4717
 
 
4718
                internal ArrayTypeWrapper(TypeWrapper ultimateElementTypeWrapper, string name)
 
4719
                        : base(Modifiers.Final | Modifiers.Abstract | (ultimateElementTypeWrapper.Modifiers & Modifiers.Public), name)
 
4720
                {
 
4721
                        Debug.Assert(!ultimateElementTypeWrapper.IsArray);
 
4722
                        this.ultimateElementTypeWrapper = ultimateElementTypeWrapper;
 
4723
                        this.IsInternal = ultimateElementTypeWrapper.IsInternal;
 
4724
                }
 
4725
 
 
4726
                internal override TypeWrapper BaseTypeWrapper
 
4727
                {
 
4728
                        get { return CoreClasses.java.lang.Object.Wrapper; }
 
4729
                }
 
4730
 
 
4731
                internal override ClassLoaderWrapper GetClassLoader()
 
4732
                {
 
4733
                        return ultimateElementTypeWrapper.GetClassLoader();
 
4734
                }
 
4735
 
 
4736
                internal static MethodInfo CloneMethod
 
4737
                {
 
4738
                        get
 
4739
                        {
 
4740
                                if(clone == null)
 
4741
                                {
 
4742
                                        clone = Types.Array.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
 
4743
                                }
 
4744
                                return clone;
 
4745
                        }
 
4746
                }
 
4747
 
 
4748
                protected override void LazyPublishMembers()
 
4749
                {
 
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);
 
4751
                        mw.Link();
 
4752
                        SetMethods(new MethodWrapper[] { mw });
 
4753
                        SetFields(FieldWrapper.EmptyArray);
 
4754
                }
 
4755
 
 
4756
                internal override Modifiers ReflectiveModifiers
 
4757
                {
 
4758
                        get
 
4759
                        {
 
4760
                                return Modifiers.Final | Modifiers.Abstract | (ultimateElementTypeWrapper.ReflectiveModifiers & Modifiers.AccessMask);
 
4761
                        }
 
4762
                }
 
4763
 
 
4764
                internal override string SigName
 
4765
                {
 
4766
                        get
 
4767
                        {
 
4768
                                // for arrays the signature name is the same as the normal name
 
4769
                                return Name;
 
4770
                        }
 
4771
                }
 
4772
 
 
4773
                internal override TypeWrapper[] Interfaces
 
4774
                {
 
4775
                        get
 
4776
                        {
 
4777
                                if(interfaces == null)
 
4778
                                {
 
4779
                                        TypeWrapper[] tw = new TypeWrapper[2];
 
4780
                                        tw[0] = ClassLoaderWrapper.LoadClassCritical("java.lang.Cloneable");
 
4781
                                        tw[1] = ClassLoaderWrapper.LoadClassCritical("java.io.Serializable");
 
4782
                                        interfaces = tw;
 
4783
                                }
 
4784
                                return interfaces;
 
4785
                        }
 
4786
                }
 
4787
 
 
4788
                internal override TypeWrapper[] InnerClasses
 
4789
                {
 
4790
                        get
 
4791
                        {
 
4792
                                return TypeWrapper.EmptyArray;
 
4793
                        }
 
4794
                }
 
4795
 
 
4796
                internal override TypeWrapper DeclaringTypeWrapper
 
4797
                {
 
4798
                        get
 
4799
                        {
 
4800
                                return null;
 
4801
                        }
 
4802
                }
 
4803
 
 
4804
                internal override Type TypeAsTBD
 
4805
                {
 
4806
                        get
 
4807
                        {
 
4808
                                while (arrayType == null)
 
4809
                                {
 
4810
                                        bool prevFinished = finished;
 
4811
                                        Type type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank);
 
4812
                                        if (prevFinished)
 
4813
                                        {
 
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.
 
4818
                                                arrayType = type;
 
4819
                                        }
 
4820
                                        else
 
4821
                                        {
 
4822
                                                lock (this)
 
4823
                                                {
 
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.
 
4831
                                                        if (!finished)
 
4832
                                                        {
 
4833
                                                                arrayType = type;
 
4834
                                                        }
 
4835
                                                }
 
4836
                                        }
 
4837
                                }
 
4838
                                return arrayType;
 
4839
                        }
 
4840
                }
 
4841
 
 
4842
                internal override void Finish()
 
4843
                {
 
4844
                        if (!finished)
 
4845
                        {
 
4846
                                ultimateElementTypeWrapper.Finish();
 
4847
                                lock (this)
 
4848
                                {
 
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
 
4852
                                        // with TypeAsTBD.
 
4853
                                        finished = true;
 
4854
                                        arrayType = null;
 
4855
                                }
 
4856
                        }
 
4857
                }
 
4858
 
 
4859
                internal override bool IsFastClassLiteralSafe
 
4860
                {
 
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; }
 
4864
                }
 
4865
 
 
4866
                internal override TypeWrapper GetUltimateElementTypeWrapper()
 
4867
                {
 
4868
                        return ultimateElementTypeWrapper;
 
4869
                }
 
4870
 
 
4871
                internal static Type MakeArrayType(Type type, int dims)
 
4872
                {
 
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++)
 
4878
                        {
 
4879
                                type = type.MakeArrayType();
 
4880
                        }
 
4881
                        return type;
 
4882
                }
 
4883
        }
 
4884
 
 
4885
        // this is a container for the special verifier TypeWrappers
 
4886
        sealed class VerifierTypeWrapper : TypeWrapper
 
4887
        {
 
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);
 
4899
 
 
4900
                private int index;
 
4901
                private TypeWrapper underlyingType;
 
4902
                private MethodAnalyzer methodAnalyzer;
 
4903
 
 
4904
#if STUB_GENERATOR
 
4905
                internal class MethodAnalyzer
 
4906
                {
 
4907
                        internal void ClearFaultBlockException(int dummy) { }
 
4908
                }
 
4909
#endif
 
4910
 
 
4911
                public override string ToString()
 
4912
                {
 
4913
                        return GetType().Name + "[" + Name + "," + index + "," + underlyingType + "]";
 
4914
                }
 
4915
 
 
4916
                internal static TypeWrapper MakeNew(TypeWrapper type, int bytecodeIndex)
 
4917
                {
 
4918
                        return new VerifierTypeWrapper(New, bytecodeIndex, type, null);
 
4919
                }
 
4920
 
 
4921
                internal static TypeWrapper MakeFaultBlockException(MethodAnalyzer ma, int handlerIndex)
 
4922
                {
 
4923
                        return new VerifierTypeWrapper(Fault, handlerIndex, null, ma);
 
4924
                }
 
4925
 
 
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)
 
4932
                {
 
4933
                        return new VerifierTypeWrapper(This, 0, type, null);
 
4934
                }
 
4935
 
 
4936
                internal static bool IsNotPresentOnStack(TypeWrapper w)
 
4937
                {
 
4938
                        return IsNew(w) || IsFaultBlockException(w);
 
4939
                }
 
4940
 
 
4941
                internal static bool IsNew(TypeWrapper w)
 
4942
                {
 
4943
                        return w != null && w.IsVerifierType && ReferenceEquals(w.Name, New);
 
4944
                }
 
4945
 
 
4946
                internal static bool IsFaultBlockException(TypeWrapper w)
 
4947
                {
 
4948
                        return w != null && w.IsVerifierType && ReferenceEquals(w.Name, Fault);
 
4949
                }
 
4950
 
 
4951
                internal static bool IsNullOrUnloadable(TypeWrapper w)
 
4952
                {
 
4953
                        return w == Null || w.IsUnloadable;
 
4954
                }
 
4955
 
 
4956
                internal static bool IsThis(TypeWrapper w)
 
4957
                {
 
4958
                        return w != null && w.IsVerifierType && ReferenceEquals(w.Name, This);
 
4959
                }
 
4960
 
 
4961
                internal static void ClearFaultBlockException(TypeWrapper w)
 
4962
                {
 
4963
                        VerifierTypeWrapper vtw = (VerifierTypeWrapper)w;
 
4964
                        vtw.methodAnalyzer.ClearFaultBlockException(vtw.Index);
 
4965
                }
 
4966
 
 
4967
                internal int Index
 
4968
                {
 
4969
                        get
 
4970
                        {
 
4971
                                return index;
 
4972
                        }
 
4973
                }
 
4974
 
 
4975
                internal TypeWrapper UnderlyingType
 
4976
                {
 
4977
                        get
 
4978
                        {
 
4979
                                return underlyingType;
 
4980
                        }
 
4981
                }
 
4982
 
 
4983
                private VerifierTypeWrapper(string name, int index, TypeWrapper underlyingType, MethodAnalyzer methodAnalyzer)
 
4984
                        : base(TypeWrapper.VerifierTypeModifiersHack, name)
 
4985
                {
 
4986
                        this.index = index;
 
4987
                        this.underlyingType = underlyingType;
 
4988
                        this.methodAnalyzer = methodAnalyzer;
 
4989
                }
 
4990
 
 
4991
                internal override TypeWrapper BaseTypeWrapper
 
4992
                {
 
4993
                        get { return null; }
 
4994
                }
 
4995
 
 
4996
                internal override ClassLoaderWrapper GetClassLoader()
 
4997
                {
 
4998
                        return null;
 
4999
                }
 
5000
 
 
5001
                protected override void LazyPublishMembers()
 
5002
                {
 
5003
                        throw new InvalidOperationException("LazyPublishMembers called on " + this);
 
5004
                }
 
5005
 
 
5006
                internal override Type TypeAsTBD
 
5007
                {
 
5008
                        get
 
5009
                        {
 
5010
                                throw new InvalidOperationException("get_Type called on " + this);
 
5011
                        }
 
5012
                }
 
5013
 
 
5014
                internal override TypeWrapper[] Interfaces
 
5015
                {
 
5016
                        get
 
5017
                        {
 
5018
                                throw new InvalidOperationException("get_Interfaces called on " + this);
 
5019
                        }
 
5020
                }
 
5021
 
 
5022
                internal override TypeWrapper[] InnerClasses
 
5023
                {
 
5024
                        get
 
5025
                        {
 
5026
                                throw new InvalidOperationException("get_InnerClasses called on " + this);
 
5027
                        }
 
5028
                }
 
5029
 
 
5030
                internal override TypeWrapper DeclaringTypeWrapper
 
5031
                {
 
5032
                        get
 
5033
                        {
 
5034
                                throw new InvalidOperationException("get_DeclaringTypeWrapper called on " + this);
 
5035
                        }
 
5036
                }
 
5037
 
 
5038
                internal override void Finish()
 
5039
                {
 
5040
                        throw new InvalidOperationException("Finish called on " + this);
 
5041
                }
 
5042
        }
 
5043
}