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

« back to all changes in this revision

Viewing changes to external/ikvm/runtime/DynamicTypeWrapper.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
 
27
using IKVM.Reflection;
 
28
using IKVM.Reflection.Emit;
 
29
using Type = IKVM.Reflection.Type;
 
30
using DynamicOrAotTypeWrapper = IKVM.Internal.AotTypeWrapper;
 
31
#else
 
32
using System.Reflection;
 
33
using System.Reflection.Emit;
 
34
using DynamicOrAotTypeWrapper = IKVM.Internal.DynamicTypeWrapper;
 
35
#endif
 
36
using System.Diagnostics;
 
37
using System.Security;
 
38
using System.Security.Permissions;
 
39
using IKVM.Attributes;
 
40
 
 
41
namespace IKVM.Internal
 
42
{
 
43
#if STATIC_COMPILER
 
44
        abstract class DynamicTypeWrapper : TypeWrapper
 
45
#else
 
46
        class DynamicTypeWrapper : TypeWrapper
 
47
#endif
 
48
        {
 
49
#if STATIC_COMPILER
 
50
                protected readonly CompilerClassLoader classLoader;
 
51
#else
 
52
                protected readonly ClassLoaderWrapper classLoader;
 
53
#endif
 
54
                private volatile DynamicImpl impl;
 
55
                private readonly TypeWrapper baseTypeWrapper;
 
56
                private TypeWrapper[] interfaces;
 
57
                private readonly string sourceFileName;
 
58
#if !STATIC_COMPILER
 
59
                private byte[][] lineNumberTables;
 
60
#endif
 
61
                private MethodBase automagicSerializationCtor;
 
62
 
 
63
                private static TypeWrapper LoadTypeWrapper(ClassLoaderWrapper classLoader, string name)
 
64
                {
 
65
                        TypeWrapper tw = classLoader.LoadClassByDottedNameFast(name);
 
66
                        if (tw == null)
 
67
                        {
 
68
                                throw new NoClassDefFoundError(name);
 
69
                        }
 
70
                        return tw;
 
71
                }
 
72
 
 
73
#if STATIC_COMPILER
 
74
                internal DynamicTypeWrapper(ClassFile f, CompilerClassLoader classLoader)
 
75
#else
 
76
                internal DynamicTypeWrapper(ClassFile f, ClassLoaderWrapper classLoader)
 
77
#endif
 
78
                        : base(f.Modifiers, f.Name)
 
79
                {
 
80
                        Profiler.Count("DynamicTypeWrapper");
 
81
                        this.classLoader = classLoader;
 
82
                        this.IsInternal = f.IsInternal;
 
83
                        this.sourceFileName = f.SourceFileAttribute;
 
84
                        this.baseTypeWrapper = f.IsInterface ? null : LoadTypeWrapper(classLoader, f.SuperClass);
 
85
                        if (BaseTypeWrapper != null)
 
86
                        {
 
87
                                if (!BaseTypeWrapper.IsAccessibleFrom(this))
 
88
                                {
 
89
                                        throw new IllegalAccessError("Class " + f.Name + " cannot access its superclass " + BaseTypeWrapper.Name);
 
90
                                }
 
91
#if !STATIC_COMPILER
 
92
                                if (!BaseTypeWrapper.IsPublic && !ReflectUtil.IsFromAssembly(BaseTypeWrapper.TypeAsBaseType, classLoader.GetTypeWrapperFactory().ModuleBuilder.Assembly))
 
93
                                {
 
94
                                        // NOTE this can only happen if evil code calls ClassLoader.defineClass() on an assembly class loader (which we allow for compatibility with other slightly less evil code)
 
95
                                        throw new IllegalAccessError("Class " + f.Name + " cannot access its non-public superclass " + BaseTypeWrapper.Name + " from another assembly");
 
96
                                }
 
97
#endif
 
98
                                if (BaseTypeWrapper.IsFinal)
 
99
                                {
 
100
                                        throw new VerifyError("Class " + f.Name + " extends final class " + BaseTypeWrapper.Name);
 
101
                                }
 
102
                                if (BaseTypeWrapper.IsInterface)
 
103
                                {
 
104
                                        throw new IncompatibleClassChangeError("Class " + f.Name + " has interface " + BaseTypeWrapper.Name + " as superclass");
 
105
                                }
 
106
                                if (BaseTypeWrapper.TypeAsTBD == Types.Delegate)
 
107
                                {
 
108
                                        throw new VerifyError(BaseTypeWrapper.Name + " cannot be used as a base class");
 
109
                                }
 
110
                                // NOTE defining value types, enums is not supported in IKVM v1
 
111
                                if (BaseTypeWrapper.TypeAsTBD == Types.ValueType || BaseTypeWrapper.TypeAsTBD == Types.Enum)
 
112
                                {
 
113
                                        throw new VerifyError("Defining value types in Java is not implemented in IKVM v1");
 
114
                                }
 
115
                                if (IsDelegate)
 
116
                                {
 
117
                                        VerifyDelegate(f);
 
118
                                }
 
119
#if CLASSGC
 
120
                                if (JVM.classUnloading && BaseTypeWrapper.TypeAsBaseType == typeof(ContextBoundObject))
 
121
                                {
 
122
                                        throw new VerifyError("Extending ContextBoundObject is not supported in dynamic mode with class GC enabled.");
 
123
                                }
 
124
#endif
 
125
                        }
 
126
 
 
127
#if CLASSGC
 
128
                        if (JVM.classUnloading)
 
129
                        {
 
130
                                VerifyRunAndCollect(f);
 
131
                        }
 
132
#endif
 
133
 
 
134
                        ClassFile.ConstantPoolItemClass[] interfaces = f.Interfaces;
 
135
                        this.interfaces = new TypeWrapper[interfaces.Length];
 
136
                        for (int i = 0; i < interfaces.Length; i++)
 
137
                        {
 
138
                                TypeWrapper iface = LoadTypeWrapper(classLoader, interfaces[i].Name);
 
139
                                if (!iface.IsAccessibleFrom(this))
 
140
                                {
 
141
                                        throw new IllegalAccessError("Class " + f.Name + " cannot access its superinterface " + iface.Name);
 
142
                                }
 
143
#if !STATIC_COMPILER
 
144
                                if (!iface.IsPublic && !ReflectUtil.IsFromAssembly(iface.TypeAsBaseType, classLoader.GetTypeWrapperFactory().ModuleBuilder.Assembly))
 
145
                                {
 
146
                                        string proxyName = DynamicClassLoader.GetProxyHelperName(iface.TypeAsTBD);
 
147
                                        Type proxyType = ReflectUtil.GetAssembly(iface.TypeAsBaseType).GetType(proxyName);
 
148
                                        // FXBUG we need to check if the type returned is actually correct, because .NET 2.0 has a bug that
 
149
                                        // causes it to return typeof(IFoo) for GetType("__<Proxy>+IFoo")
 
150
                                        if (proxyType == null || proxyType.FullName != proxyName)
 
151
                                        {
 
152
                                                // NOTE this happens when you call Proxy.newProxyInstance() on a non-public .NET interface
 
153
                                                // (for ikvmc compiled Java types, ikvmc generates public proxy stubs).
 
154
                                                // NOTE we don't currently check interfaces inherited from other interfaces because mainstream .NET languages
 
155
                                                // don't allow public interfaces extending non-public interfaces.
 
156
                                                throw new IllegalAccessError("Class " + f.Name + " cannot access its non-public superinterface " + iface.Name + " from another assembly");
 
157
                                        }
 
158
                                }
 
159
#endif
 
160
                                if (!iface.IsInterface)
 
161
                                {
 
162
                                        throw new IncompatibleClassChangeError("Implementing class");
 
163
                                }
 
164
                                this.interfaces[i] = iface;
 
165
                        }
 
166
 
 
167
                        impl = new JavaTypeImpl(f, this);
 
168
                }
 
169
 
 
170
#if CLASSGC
 
171
                private static void VerifyRunAndCollect(ClassFile f)
 
172
                {
 
173
                        if (f.Annotations != null)
 
174
                        {
 
175
                                foreach (object[] ann in f.Annotations)
 
176
                                {
 
177
                                        if (ann[1].Equals("Lcli/System/Runtime/InteropServices/ComImportAttribute$Annotation;"))
 
178
                                        {
 
179
                                                throw new VerifyError("ComImportAttribute is not supported in dynamic mode with class GC enabled.");
 
180
                                        }
 
181
                                }
 
182
                        }
 
183
                        foreach (ClassFile.Field field in f.Fields)
 
184
                        {
 
185
                                if (field.Annotations != null)
 
186
                                {
 
187
                                        foreach (object[] ann in field.Annotations)
 
188
                                        {
 
189
                                                if (ann[1].Equals("Lcli/System/ThreadStaticAttribute$Annotation;"))
 
190
                                                {
 
191
                                                        throw new VerifyError("ThreadStaticAttribute is not supported in dynamic mode with class GC enabled.");
 
192
                                                }
 
193
                                                if (ann[1].Equals("Lcli/System/ContextStaticAttribute$Annotation;"))
 
194
                                                {
 
195
                                                        throw new VerifyError("ContextStaticAttribute is not supported in dynamic mode with class GC enabled.");
 
196
                                                }
 
197
                                        }
 
198
                                }
 
199
                        }
 
200
                        foreach (ClassFile.Method method in f.Methods)
 
201
                        {
 
202
                                if (method.Annotations != null)
 
203
                                {
 
204
                                        foreach (object[] ann in method.Annotations)
 
205
                                        {
 
206
                                                if (ann[1].Equals("Lcli/System/Runtime/InteropServices/DllImportAttribute$Annotation;"))
 
207
                                                {
 
208
                                                        throw new VerifyError("DllImportAttribute is not supported in dynamic mode with class GC enabled.");
 
209
                                                }
 
210
                                        }
 
211
                                }
 
212
                        }
 
213
                }
 
214
#endif
 
215
 
 
216
                private void VerifyDelegate(ClassFile f)
 
217
                {
 
218
                        if (!f.IsFinal)
 
219
                        {
 
220
                                throw new VerifyError("Delegate must be final");
 
221
                        }
 
222
                        ClassFile.Method invoke = null;
 
223
                        ClassFile.Method beginInvoke = null;
 
224
                        ClassFile.Method endInvoke = null;
 
225
                        ClassFile.Method constructor = null;
 
226
                        foreach (ClassFile.Method m in f.Methods)
 
227
                        {
 
228
                                if (m.Name == "Invoke")
 
229
                                {
 
230
                                        if (invoke != null)
 
231
                                        {
 
232
                                                throw new VerifyError("Delegate may only have a single Invoke method");
 
233
                                        }
 
234
                                        invoke = m;
 
235
                                }
 
236
                                else if (m.Name == "BeginInvoke")
 
237
                                {
 
238
                                        if (beginInvoke != null)
 
239
                                        {
 
240
                                                throw new VerifyError("Delegate may only have a single BeginInvoke method");
 
241
                                        }
 
242
                                        beginInvoke = m;
 
243
                                }
 
244
                                else if (m.Name == "EndInvoke")
 
245
                                {
 
246
                                        if (endInvoke != null)
 
247
                                        {
 
248
                                                throw new VerifyError("Delegate may only have a single EndInvoke method");
 
249
                                        }
 
250
                                        endInvoke = m;
 
251
                                }
 
252
                                else if (m.Name == "<init>")
 
253
                                {
 
254
                                        if (constructor != null)
 
255
                                        {
 
256
                                                throw new VerifyError("Delegate may only have a single constructor");
 
257
                                        }
 
258
                                        constructor = m;
 
259
                                }
 
260
                                else if (m.IsNative)
 
261
                                {
 
262
                                        throw new VerifyError("Delegate may not have any native methods besides Invoke, BeginInvoke and EndInvoke");
 
263
                                }
 
264
                        }
 
265
                        if (invoke == null || constructor == null)
 
266
                        {
 
267
                                throw new VerifyError("Delegate must have a constructor and an Invoke method");
 
268
                        }
 
269
                        if (!invoke.IsPublic || !invoke.IsNative || invoke.IsFinal || invoke.IsStatic)
 
270
                        {
 
271
                                throw new VerifyError("Delegate Invoke method must be a public native non-final instance method");
 
272
                        }
 
273
                        if ((beginInvoke != null && endInvoke == null) || (beginInvoke == null && endInvoke != null))
 
274
                        {
 
275
                                throw new VerifyError("Delegate must have both BeginInvoke and EndInvoke or neither");
 
276
                        }
 
277
                        if (!constructor.IsPublic)
 
278
                        {
 
279
                                throw new VerifyError("Delegate constructor must be public");
 
280
                        }
 
281
                        if (constructor.Instructions.Length < 3
 
282
                                || constructor.Instructions[0].NormalizedOpCode != NormalizedByteCode.__aload
 
283
                                || constructor.Instructions[0].NormalizedArg1 != 0
 
284
                                || constructor.Instructions[1].NormalizedOpCode != NormalizedByteCode.__invokespecial
 
285
                                || constructor.Instructions[2].NormalizedOpCode != NormalizedByteCode.__return)
 
286
                        {
 
287
                                throw new VerifyError("Delegate constructor must be empty");
 
288
                        }
 
289
                        if (f.Fields.Length != 0)
 
290
                        {
 
291
                                throw new VerifyError("Delegate may not declare any fields");
 
292
                        }
 
293
                        TypeWrapper iface = classLoader.LoadClassByDottedNameFast(f.Name + DotNetTypeWrapper.DelegateInterfaceSuffix);
 
294
                        DelegateInnerClassCheck(iface != null);
 
295
                        DelegateInnerClassCheck(iface.IsInterface);
 
296
                        DelegateInnerClassCheck(iface.IsPublic);
 
297
                        DelegateInnerClassCheck(iface.GetClassLoader() == classLoader);
 
298
                        MethodWrapper[] methods = iface.GetMethods();
 
299
                        DelegateInnerClassCheck(methods.Length == 1 && methods[0].Name == "Invoke");
 
300
                        if (methods[0].Signature != invoke.Signature)
 
301
                        {
 
302
                                throw new VerifyError("Delegate Invoke method signature must be identical to inner interface Invoke method signature");
 
303
                        }
 
304
                        if (iface.Interfaces.Length != 0)
 
305
                        {
 
306
                                throw new VerifyError("Delegate inner interface may not extend any interfaces");
 
307
                        }
 
308
                        if (constructor.Signature != "(" + iface.SigName + ")V")
 
309
                        {
 
310
                                throw new VerifyError("Delegate constructor must take a single argument of type inner Method interface");
 
311
                        }
 
312
                        if (beginInvoke != null && beginInvoke.Signature != invoke.Signature.Substring(0, invoke.Signature.IndexOf(')')) + "Lcli.System.AsyncCallback;Ljava.lang.Object;)Lcli.System.IAsyncResult;")
 
313
                        {
 
314
                                throw new VerifyError("Delegate BeginInvoke method has incorrect signature");
 
315
                        }
 
316
                        if (endInvoke != null && endInvoke.Signature != "(Lcli.System.IAsyncResult;)" + invoke.Signature.Substring(invoke.Signature.IndexOf(')') + 1))
 
317
                        {
 
318
                                throw new VerifyError("Delegate EndInvoke method has incorrect signature");
 
319
                        }
 
320
                }
 
321
 
 
322
                private static void DelegateInnerClassCheck(bool cond)
 
323
                {
 
324
                        if (!cond)
 
325
                        {
 
326
                                throw new VerifyError("Delegate must have a public inner interface named Method with a single method named Invoke");
 
327
                        }
 
328
                }
 
329
 
 
330
                private bool IsDelegate
 
331
                {
 
332
                        get
 
333
                        {
 
334
                                TypeWrapper baseTypeWrapper = BaseTypeWrapper;
 
335
                                return baseTypeWrapper != null && baseTypeWrapper.TypeAsTBD == Types.MulticastDelegate;
 
336
                        }
 
337
                }
 
338
 
 
339
                internal sealed override TypeWrapper BaseTypeWrapper
 
340
                {
 
341
                        get { return baseTypeWrapper; }
 
342
                }
 
343
 
 
344
                internal override ClassLoaderWrapper GetClassLoader()
 
345
                {
 
346
                        return classLoader;
 
347
                }
 
348
 
 
349
                internal override Modifiers ReflectiveModifiers
 
350
                {
 
351
                        get
 
352
                        {
 
353
                                return impl.ReflectiveModifiers;
 
354
                        }
 
355
                }
 
356
 
 
357
                internal override TypeWrapper[] Interfaces
 
358
                {
 
359
                        get
 
360
                        {
 
361
                                return interfaces;
 
362
                        }
 
363
                }
 
364
 
 
365
                internal override TypeWrapper[] InnerClasses
 
366
                {
 
367
                        get
 
368
                        {
 
369
                                return impl.InnerClasses;
 
370
                        }
 
371
                }
 
372
 
 
373
                internal override TypeWrapper DeclaringTypeWrapper
 
374
                {
 
375
                        get
 
376
                        {
 
377
                                return impl.DeclaringTypeWrapper;
 
378
                        }
 
379
                }
 
380
 
 
381
                internal override Type TypeAsTBD
 
382
                {
 
383
                        get
 
384
                        {
 
385
                                return impl.Type;
 
386
                        }
 
387
                }
 
388
 
 
389
                internal override void Finish()
 
390
                {
 
391
                        // we don't need locking, because Finish is Thread safe
 
392
                        impl = impl.Finish();
 
393
                }
 
394
 
 
395
                internal void CreateStep1()
 
396
                {
 
397
                        ((JavaTypeImpl)impl).CreateStep1();
 
398
                }
 
399
 
 
400
                internal void CreateStep2()
 
401
                {
 
402
                        ((JavaTypeImpl)impl).CreateStep2();
 
403
                }
 
404
 
 
405
                private bool IsSerializable
 
406
                {
 
407
                        get
 
408
                        {
 
409
                                return this.IsSubTypeOf(ClassLoaderWrapper.LoadClassCritical("java.io.Serializable"));
 
410
                        }
 
411
                }
 
412
 
 
413
                private abstract class DynamicImpl
 
414
                {
 
415
                        internal abstract Type Type { get; }
 
416
                        internal abstract TypeWrapper[] InnerClasses { get; }
 
417
                        internal abstract TypeWrapper DeclaringTypeWrapper { get; }
 
418
                        internal abstract Modifiers ReflectiveModifiers { get; }
 
419
                        internal abstract DynamicImpl Finish();
 
420
                        internal abstract MethodBase LinkMethod(MethodWrapper mw);
 
421
                        internal abstract FieldInfo LinkField(FieldWrapper fw);
 
422
                        internal abstract void EmitRunClassConstructor(CodeEmitter ilgen);
 
423
                        internal abstract string GetGenericSignature();
 
424
                        internal abstract string[] GetEnclosingMethod();
 
425
                        internal abstract string GetGenericMethodSignature(int index);
 
426
                        internal abstract string GetGenericFieldSignature(int index);
 
427
                        internal abstract object[] GetDeclaredAnnotations();
 
428
                        internal abstract object GetMethodDefaultValue(int index);
 
429
                        internal abstract object[] GetMethodAnnotations(int index);
 
430
                        internal abstract object[][] GetParameterAnnotations(int index);
 
431
                        internal abstract object[] GetFieldAnnotations(int index);
 
432
                        internal abstract MethodInfo GetFinalizeMethod();
 
433
                }
 
434
 
 
435
                private sealed class JavaTypeImpl : DynamicImpl
 
436
                {
 
437
                        private readonly ClassFile classFile;
 
438
                        private readonly DynamicOrAotTypeWrapper wrapper;
 
439
                        private TypeBuilder typeBuilder;
 
440
                        private MethodWrapper[] methods;
 
441
                        private MethodWrapper[][] baseMethods;
 
442
                        private FieldWrapper[] fields;
 
443
                        private FinishedTypeImpl finishedType;
 
444
                        private bool finishInProgress;
 
445
                        private MethodBuilder clinitMethod;
 
446
                        private MethodBuilder finalizeMethod;
 
447
#if STATIC_COMPILER
 
448
                        private DynamicTypeWrapper outerClassWrapper;
 
449
                        private AnnotationBuilder annotationBuilder;
 
450
                        private TypeBuilder enumBuilder;
 
451
                        private Dictionary<string, TypeWrapper> nestedTypeNames;        // only keys are used, values are always null
 
452
#endif
 
453
 
 
454
                        internal JavaTypeImpl(ClassFile f, DynamicTypeWrapper wrapper)
 
455
                        {
 
456
                                Tracer.Info(Tracer.Compiler, "constructing JavaTypeImpl for " + f.Name);
 
457
                                this.classFile = f;
 
458
                                this.wrapper = (DynamicOrAotTypeWrapper)wrapper;
 
459
                        }
 
460
 
 
461
                        internal void CreateStep1()
 
462
                        {
 
463
                                // process all methods
 
464
                                bool hasclinit = wrapper.BaseTypeWrapper == null ? false : wrapper.BaseTypeWrapper.HasStaticInitializer;
 
465
                                methods = new MethodWrapper[classFile.Methods.Length];
 
466
                                baseMethods = new MethodWrapper[classFile.Methods.Length][];
 
467
                                for (int i = 0; i < methods.Length; i++)
 
468
                                {
 
469
                                        ClassFile.Method m = classFile.Methods[i];
 
470
                                        if (m.IsClassInitializer)
 
471
                                        {
 
472
#if STATIC_COMPILER
 
473
                                                bool noop;
 
474
                                                if (IsSideEffectFreeStaticInitializerOrNoop(m, out noop))
 
475
                                                {
 
476
                                                        // because we cannot affect serialVersionUID computation (which is the only way the presence of a <clinit> can surface)
 
477
                                                        // we cannot do this optimization if the class is serializable but doesn't have a serialVersionUID
 
478
                                                        if (noop && (!wrapper.IsSerializable || classFile.HasSerialVersionUID))
 
479
                                                        {
 
480
                                                                methods[i] = new DummyMethodWrapper(wrapper);
 
481
                                                                continue;
 
482
                                                        }
 
483
                                                }
 
484
                                                else
 
485
                                                {
 
486
                                                        hasclinit = true;
 
487
                                                }
 
488
#else
 
489
                                                hasclinit = true;
 
490
#endif
 
491
                                        }
 
492
                                        MemberFlags flags = MemberFlags.None;
 
493
                                        if (m.IsInternal)
 
494
                                        {
 
495
                                                flags |= MemberFlags.InternalAccess;
 
496
                                        }
 
497
                                        // we only support HasCallerID instance methods on final types, because we don't support interface stubs with CallerID
 
498
                                        if (m.HasCallerIDAnnotation
 
499
                                                && (m.IsStatic || classFile.IsFinal)
 
500
                                                && CoreClasses.java.lang.Object.Wrapper.InternalsVisibleTo(wrapper))
 
501
                                        {
 
502
                                                flags |= MemberFlags.CallerID;
 
503
                                        }
 
504
                                        if (wrapper.IsGhost)
 
505
                                        {
 
506
                                                methods[i] = new GhostMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, null, m.Modifiers, flags);
 
507
                                        }
 
508
                                        else if (m.IsConstructor && wrapper.IsDelegate)
 
509
                                        {
 
510
                                                methods[i] = new DelegateConstructorMethodWrapper(wrapper, m);
 
511
                                        }
 
512
                                        else
 
513
                                        {
 
514
                                                if (!classFile.IsInterface && !m.IsStatic && !m.IsPrivate && !m.IsConstructor)
 
515
                                                {
 
516
                                                        bool explicitOverride = false;
 
517
                                                        baseMethods[i] = FindBaseMethods(m, out explicitOverride);
 
518
                                                        if (explicitOverride)
 
519
                                                        {
 
520
                                                                flags |= MemberFlags.ExplicitOverride;
 
521
                                                        }
 
522
                                                }
 
523
                                                methods[i] = new TypicalMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, m.Modifiers, flags);
 
524
                                        }
 
525
                                }
 
526
                                wrapper.HasStaticInitializer = hasclinit;
 
527
                                if (wrapper.IsAbstract && (!wrapper.IsInterface || wrapper.IsPublic))
 
528
                                {
 
529
                                        List<MethodWrapper> methodsArray = new List<MethodWrapper>(methods);
 
530
                                        List<MethodWrapper[]> baseMethodsArray = new List<MethodWrapper[]>(baseMethods);
 
531
                                        AddMirandaMethods(methodsArray, baseMethodsArray, wrapper);
 
532
                                        methods = methodsArray.ToArray();
 
533
                                        baseMethods = baseMethodsArray.ToArray();
 
534
                                }
 
535
                                if (!wrapper.IsInterface)
 
536
                                {
 
537
                                        AddDelegateInvokeStubs(wrapper, ref methods);
 
538
                                }
 
539
                                wrapper.SetMethods(methods);
 
540
 
 
541
                                fields = new FieldWrapper[classFile.Fields.Length];
 
542
                                for (int i = 0; i < fields.Length; i++)
 
543
                                {
 
544
                                        ClassFile.Field fld = classFile.Fields[i];
 
545
                                        if (fld.IsStaticFinalConstant)
 
546
                                        {
 
547
                                                TypeWrapper fieldType = null;
 
548
#if !STATIC_COMPILER
 
549
                                                fieldType = ClassLoaderWrapper.GetBootstrapClassLoader().FieldTypeWrapperFromSig(fld.Signature);
 
550
#endif
 
551
                                                fields[i] = new ConstantFieldWrapper(wrapper, fieldType, fld.Name, fld.Signature, fld.Modifiers, null, fld.ConstantValue, MemberFlags.None);
 
552
                                        }
 
553
                                        else if (fld.IsProperty)
 
554
                                        {
 
555
                                                fields[i] = new DynamicPropertyFieldWrapper(wrapper, fld);
 
556
                                        }
 
557
                                        else
 
558
                                        {
 
559
                                                fields[i] = FieldWrapper.Create(wrapper, null, null, fld.Name, fld.Signature, new ExModifiers(fld.Modifiers, fld.IsInternal));
 
560
                                        }
 
561
                                }
 
562
#if STATIC_COMPILER
 
563
                                wrapper.AddMapXmlFields(ref fields);
 
564
#endif
 
565
                                wrapper.SetFields(fields);
 
566
                        }
 
567
 
 
568
                        internal void CreateStep2()
 
569
                        {
 
570
#if STATIC_COMPILER
 
571
                                if (typeBuilder != null)
 
572
                                {
 
573
                                        // in the static compiler we need to create the TypeBuilder from outer to inner
 
574
                                        // and to avoid having to sort the classes this way, we instead call CreateStep2
 
575
                                        // on demand for outer wrappers and this necessitates us to keep track of
 
576
                                        // whether we've already been called
 
577
                                        return;
 
578
                                }
 
579
#endif
 
580
                                // this method is not allowed to throw exceptions (if it does, the runtime will abort)
 
581
                                bool hasclinit = wrapper.HasStaticInitializer;
 
582
                                string mangledTypeName = wrapper.classLoader.GetTypeWrapperFactory().AllocMangledName(wrapper);
 
583
                                ClassFile f = classFile;
 
584
                                try
 
585
                                {
 
586
                                        TypeAttributes typeAttribs = 0;
 
587
                                        if (f.IsAbstract)
 
588
                                        {
 
589
                                                typeAttribs |= TypeAttributes.Abstract;
 
590
                                        }
 
591
                                        if (f.IsFinal)
 
592
                                        {
 
593
                                                typeAttribs |= TypeAttributes.Sealed;
 
594
                                        }
 
595
                                        if (!hasclinit)
 
596
                                        {
 
597
                                                typeAttribs |= TypeAttributes.BeforeFieldInit;
 
598
                                        }
 
599
#if STATIC_COMPILER
 
600
                                        bool cantNest = false;
 
601
                                        bool setModifiers = false;
 
602
                                        TypeBuilder outer = null;
 
603
                                        // we only compile inner classes as nested types in the static compiler, because it has a higher cost
 
604
                                        // and doesn't buy us anything in dynamic mode (and if fact, due to an FXBUG it would make handling
 
605
                                        // the TypeResolve event very hard)
 
606
                                        ClassFile.InnerClass outerClass = getOuterClass();
 
607
                                        if (outerClass.outerClass != 0)
 
608
                                        {
 
609
                                                string outerClassName = classFile.GetConstantPoolClass(outerClass.outerClass);
 
610
                                                if (!CheckInnerOuterNames(f.Name, outerClassName))
 
611
                                                {
 
612
                                                        Tracer.Warning(Tracer.Compiler, "Incorrect InnerClasses attribute on {0}", f.Name);
 
613
                                                }
 
614
                                                else
 
615
                                                {
 
616
                                                        try
 
617
                                                        {
 
618
                                                                outerClassWrapper = wrapper.classLoader.LoadClassByDottedNameFast(outerClassName) as DynamicTypeWrapper;
 
619
                                                        }
 
620
                                                        catch (RetargetableJavaException x)
 
621
                                                        {
 
622
                                                                Tracer.Warning(Tracer.Compiler, "Unable to load outer class {0} for inner class {1} ({2}: {3})", outerClassName, f.Name, x.GetType().Name, x.Message);
 
623
                                                        }
 
624
                                                        if (outerClassWrapper != null)
 
625
                                                        {
 
626
                                                                // make sure the relationship is reciprocal (otherwise we run the risk of
 
627
                                                                // baking the outer type before the inner type) and that the inner and outer
 
628
                                                                // class live in the same class loader (when doing a multi target compilation,
 
629
                                                                // it is possible to split the two classes acros assemblies)
 
630
                                                                JavaTypeImpl oimpl = outerClassWrapper.impl as JavaTypeImpl;
 
631
                                                                if (oimpl != null && outerClassWrapper.GetClassLoader() == wrapper.GetClassLoader())
 
632
                                                                {
 
633
                                                                        ClassFile outerClassFile = oimpl.classFile;
 
634
                                                                        ClassFile.InnerClass[] outerInnerClasses = outerClassFile.InnerClasses;
 
635
                                                                        if (outerInnerClasses == null)
 
636
                                                                        {
 
637
                                                                                outerClassWrapper = null;
 
638
                                                                        }
 
639
                                                                        else
 
640
                                                                        {
 
641
                                                                                bool ok = false;
 
642
                                                                                for (int i = 0; i < outerInnerClasses.Length; i++)
 
643
                                                                                {
 
644
                                                                                        if (outerInnerClasses[i].outerClass != 0
 
645
                                                                                                && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].outerClass) == outerClassFile.Name
 
646
                                                                                                && outerInnerClasses[i].innerClass != 0
 
647
                                                                                                && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].innerClass) == f.Name)
 
648
                                                                                        {
 
649
                                                                                                ok = true;
 
650
                                                                                                break;
 
651
                                                                                        }
 
652
                                                                                }
 
653
                                                                                if (!ok)
 
654
                                                                                {
 
655
                                                                                        outerClassWrapper = null;
 
656
                                                                                }
 
657
                                                                        }
 
658
                                                                }
 
659
                                                                else
 
660
                                                                {
 
661
                                                                        outerClassWrapper = null;
 
662
                                                                }
 
663
                                                                if (outerClassWrapper != null)
 
664
                                                                {
 
665
                                                                        outerClassWrapper.CreateStep2();
 
666
                                                                        outer = oimpl.typeBuilder;
 
667
                                                                }
 
668
                                                                else
 
669
                                                                {
 
670
                                                                        Tracer.Warning(Tracer.Compiler, "Non-reciprocal inner class {0}", f.Name);
 
671
                                                                }
 
672
                                                        }
 
673
                                                }
 
674
                                        }
 
675
                                        if (f.IsPublic)
 
676
                                        {
 
677
                                                if (outer != null)
 
678
                                                {
 
679
                                                        if (outerClassWrapper.IsPublic)
 
680
                                                        {
 
681
                                                                typeAttribs |= TypeAttributes.NestedPublic;
 
682
                                                        }
 
683
                                                        else
 
684
                                                        {
 
685
                                                                // We're a public type nested inside a non-public type, this means that we can't compile this type as a nested type,
 
686
                                                                // because that would mean it wouldn't be visible outside the assembly.
 
687
                                                                cantNest = true;
 
688
                                                                typeAttribs |= TypeAttributes.Public;
 
689
                                                        }
 
690
                                                }
 
691
                                                else
 
692
                                                {
 
693
                                                        typeAttribs |= TypeAttributes.Public;
 
694
                                                }
 
695
                                        }
 
696
                                        else if (outer != null)
 
697
                                        {
 
698
                                                typeAttribs |= TypeAttributes.NestedAssembly;
 
699
                                        }
 
700
#else // STATIC_COMPILER
 
701
                                        if (f.IsPublic)
 
702
                                        {
 
703
                                                typeAttribs |= TypeAttributes.Public;
 
704
                                        }
 
705
#endif // STATIC_COMPILER
 
706
                                        if (f.IsInterface)
 
707
                                        {
 
708
                                                typeAttribs |= TypeAttributes.Interface | TypeAttributes.Abstract;
 
709
#if STATIC_COMPILER
 
710
                                                // if any "meaningless" bits are set, preserve them
 
711
                                                setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0;
 
712
                                                // by default we assume interfaces are abstract, so in the exceptional case we need a ModifiersAttribute
 
713
                                                setModifiers |= (f.Modifiers & Modifiers.Abstract) == 0;
 
714
                                                if (outer != null && !cantNest)
 
715
                                                {
 
716
                                                        if (wrapper.IsGhost)
 
717
                                                        {
 
718
                                                                // TODO this is low priority, since the current Java class library doesn't define any ghost interfaces
 
719
                                                                // as inner classes
 
720
                                                                throw new NotImplementedException();
 
721
                                                        }
 
722
                                                        // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced
 
723
                                                        // (and broken by J# as well), so we'll just ignore it too.
 
724
                                                        typeBuilder = outer.DefineNestedType(GetInnerClassName(outerClassWrapper.Name, f.Name), typeAttribs);
 
725
                                                }
 
726
                                                else
 
727
                                                {
 
728
                                                        if (wrapper.IsGhost)
 
729
                                                        {
 
730
                                                                typeBuilder = wrapper.DefineGhostType(mangledTypeName, typeAttribs);
 
731
                                                        }
 
732
                                                        else
 
733
                                                        {
 
734
                                                                typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
 
735
                                                        }
 
736
                                                }
 
737
#else // STATIC_COMPILER
 
738
                                                typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
 
739
#endif // STATIC_COMPILER
 
740
                                        }
 
741
                                        else
 
742
                                        {
 
743
                                                typeAttribs |= TypeAttributes.Class;
 
744
#if STATIC_COMPILER
 
745
                                                // if any "meaningless" bits are set, preserve them
 
746
                                                setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0;
 
747
                                                // by default we assume ACC_SUPER for classes, so in the exceptional case we need a ModifiersAttribute
 
748
                                                setModifiers |= !f.IsSuper;
 
749
                                                if (f.IsEffectivelyFinal)
 
750
                                                {
 
751
                                                        setModifiers = true;
 
752
                                                        typeAttribs |= TypeAttributes.Sealed;
 
753
                                                        Tracer.Info(Tracer.Compiler, "Sealing type {0}", f.Name);
 
754
                                                }
 
755
                                                if (outer != null && !cantNest)
 
756
                                                {
 
757
                                                        // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced
 
758
                                                        // (and broken by J# as well), so we'll just ignore it too.
 
759
                                                        typeBuilder = outer.DefineNestedType(GetInnerClassName(outerClassWrapper.Name, f.Name), typeAttribs);
 
760
                                                }
 
761
                                                else
 
762
#endif // STATIC_COMPILER
 
763
                                                {
 
764
                                                        typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
 
765
                                                }
 
766
                                        }
 
767
#if STATIC_COMPILER
 
768
                                        // When we're statically compiling, we associate the typeBuilder with the wrapper. This enables types in referenced assemblies to refer back to
 
769
                                        // types that we're currently compiling (i.e. a cyclic dependency between the currently assembly we're compiling and a referenced assembly).
 
770
                                        wrapper.GetClassLoader().SetWrapperForType(typeBuilder, wrapper);
 
771
                                        if (outer != null && cantNest)
 
772
                                        {
 
773
                                                AttributeHelper.SetNonNestedOuterClass(typeBuilder, outerClassWrapper.Name);
 
774
                                                AttributeHelper.SetNonNestedInnerClass(outer, f.Name);
 
775
                                        }
 
776
                                        if (outer == null && mangledTypeName != wrapper.Name)
 
777
                                        {
 
778
                                                // HACK we abuse the InnerClassAttribute to record to real name
 
779
                                                AttributeHelper.SetInnerClass(typeBuilder, wrapper.Name, wrapper.Modifiers);
 
780
                                        }
 
781
                                        if (typeBuilder.FullName != wrapper.Name
 
782
                                                && wrapper.Name.Replace('$', '+') != typeBuilder.FullName)
 
783
                                        {
 
784
                                                wrapper.classLoader.AddNameMapping(wrapper.Name, typeBuilder.FullName);
 
785
                                        }
 
786
                                        if (f.IsAnnotation && Annotation.HasRetentionPolicyRuntime(f.Annotations))
 
787
                                        {
 
788
                                                annotationBuilder = new AnnotationBuilder(this, outer);
 
789
                                                wrapper.SetAnnotation(annotationBuilder);
 
790
                                        }
 
791
                                        // For Java 5 Enum types, we generate a nested .NET enum.
 
792
                                        // This is primarily to support annotations that take enum parameters.
 
793
                                        if (f.IsEnum && f.IsPublic)
 
794
                                        {
 
795
                                                CompilerClassLoader ccl = wrapper.classLoader;
 
796
                                                string name = "__Enum";
 
797
                                                while (!ccl.ReserveName(f.Name + "$" + name))
 
798
                                                {
 
799
                                                        name += "_";
 
800
                                                }
 
801
                                                enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, Types.Enum);
 
802
                                                AttributeHelper.HideFromJava(enumBuilder);
 
803
                                                enumBuilder.DefineField("value__", Types.Int32, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
 
804
                                                for (int i = 0; i < f.Fields.Length; i++)
 
805
                                                {
 
806
                                                        if (f.Fields[i].IsEnum)
 
807
                                                        {
 
808
                                                                FieldBuilder fieldBuilder = enumBuilder.DefineField(f.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
 
809
                                                                fieldBuilder.SetConstant(i);
 
810
                                                        }
 
811
                                                }
 
812
                                                wrapper.SetEnumType(enumBuilder);
 
813
                                        }
 
814
                                        TypeWrapper[] interfaces = wrapper.Interfaces;
 
815
                                        string[] implements = new string[interfaces.Length];
 
816
                                        for (int i = 0; i < implements.Length; i++)
 
817
                                        {
 
818
                                                implements[i] = interfaces[i].Name;
 
819
                                        }
 
820
                                        if (outer != null)
 
821
                                        {
 
822
                                                Modifiers innerClassModifiers = outerClass.accessFlags;
 
823
                                                string innerClassName = classFile.GetConstantPoolClass(outerClass.innerClass);
 
824
                                                if (innerClassName == classFile.Name && innerClassName == outerClassWrapper.Name + "$" + typeBuilder.Name)
 
825
                                                {
 
826
                                                        innerClassName = null;
 
827
                                                }
 
828
                                                AttributeHelper.SetInnerClass(typeBuilder, innerClassName, innerClassModifiers);
 
829
                                        }
 
830
                                        else if (outerClass.innerClass != 0)
 
831
                                        {
 
832
                                                AttributeHelper.SetInnerClass(typeBuilder, null, outerClass.accessFlags);
 
833
                                        }
 
834
                                        AttributeHelper.SetImplementsAttribute(typeBuilder, interfaces);
 
835
                                        if (classFile.DeprecatedAttribute)
 
836
                                        {
 
837
                                                AttributeHelper.SetDeprecatedAttribute(typeBuilder);
 
838
                                        }
 
839
                                        if (classFile.GenericSignature != null)
 
840
                                        {
 
841
                                                AttributeHelper.SetSignatureAttribute(typeBuilder, classFile.GenericSignature);
 
842
                                        }
 
843
                                        if (classFile.EnclosingMethod != null)
 
844
                                        {
 
845
                                                AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, classFile.EnclosingMethod[0], classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]);
 
846
                                        }
 
847
                                        if (wrapper.classLoader.EmitStackTraceInfo)
 
848
                                        {
 
849
                                                if (f.SourceFileAttribute != null)
 
850
                                                {
 
851
                                                        if (f.SourceFileAttribute != typeBuilder.Name + ".java")
 
852
                                                        {
 
853
                                                                AttributeHelper.SetSourceFile(typeBuilder, f.SourceFileAttribute);
 
854
                                                        }
 
855
                                                }
 
856
                                                else
 
857
                                                {
 
858
                                                        AttributeHelper.SetSourceFile(typeBuilder, null);
 
859
                                                }
 
860
                                        }
 
861
                                        // NOTE in Whidbey we can (and should) use CompilerGeneratedAttribute to mark Synthetic types
 
862
                                        if (setModifiers || classFile.IsInternal || (classFile.Modifiers & (Modifiers.Synthetic | Modifiers.Annotation | Modifiers.Enum)) != 0)
 
863
                                        {
 
864
                                                AttributeHelper.SetModifiers(typeBuilder, classFile.Modifiers, classFile.IsInternal);
 
865
                                        }
 
866
#endif // STATIC_COMPILER
 
867
                                        if (hasclinit)
 
868
                                        {
 
869
                                                // We create a empty method that we can use to trigger our .cctor
 
870
                                                // (previously we used RuntimeHelpers.RunClassConstructor, but that is slow and requires additional privileges)
 
871
                                                MethodAttributes attribs = MethodAttributes.Static | MethodAttributes.SpecialName;
 
872
                                                if (classFile.IsAbstract)
 
873
                                                {
 
874
                                                        bool hasfields = false;
 
875
                                                        // If we have any public static fields, the cctor trigger must (and may) be public as well
 
876
                                                        foreach (ClassFile.Field fld in classFile.Fields)
 
877
                                                        {
 
878
                                                                if (fld.IsPublic && fld.IsStatic)
 
879
                                                                {
 
880
                                                                        hasfields = true;
 
881
                                                                        break;
 
882
                                                                }
 
883
                                                        }
 
884
                                                        attribs |= hasfields ? MethodAttributes.Public : MethodAttributes.FamORAssem;
 
885
                                                }
 
886
                                                else
 
887
                                                {
 
888
                                                        attribs |= MethodAttributes.Public;
 
889
                                                }
 
890
                                                clinitMethod = typeBuilder.DefineMethod("__<clinit>", attribs, null, null);
 
891
                                                clinitMethod.GetILGenerator().Emit(OpCodes.Ret);
 
892
                                                // FXBUG on .NET 2.0 RTM x64 the JIT sometimes throws an InvalidProgramException while trying to inline this method,
 
893
                                                // so we prevent inlining for now (it also turns out that on x86 not inlining this method actually has a positive perf impact in some cases...)
 
894
                                                // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=285772
 
895
                                                clinitMethod.SetImplementationFlags(clinitMethod.GetMethodImplementationFlags() | MethodImplAttributes.NoInlining);
 
896
                                        }
 
897
                                        if (HasStructLayoutAttributeAnnotation(classFile))
 
898
                                        {
 
899
                                                // when we have a StructLayoutAttribute, field order is significant,
 
900
                                                // so we link all fields here to make sure they are created in class file order.
 
901
                                                foreach (FieldWrapper fw in fields)
 
902
                                                {
 
903
                                                        fw.Link();
 
904
                                                }
 
905
                                        }
 
906
                                }
 
907
#if STATIC_COMPILER
 
908
                                finally { }
 
909
#else
 
910
                                catch (Exception x)
 
911
                                {
 
912
                                        JVM.CriticalFailure("Exception during JavaTypeImpl.CreateStep2", x);
 
913
                                }
 
914
#endif
 
915
                        }
 
916
 
 
917
                        private sealed class DelegateConstructorMethodWrapper : MethodWrapper
 
918
                        {
 
919
                                private MethodBuilder constructor;
 
920
                                private MethodInfo invoke;
 
921
 
 
922
                                internal DelegateConstructorMethodWrapper(DynamicTypeWrapper tw, ClassFile.Method m)
 
923
                                        : base(tw, m.Name, m.Signature, null, null, null, m.Modifiers, MemberFlags.None)
 
924
                                {
 
925
                                }
 
926
 
 
927
                                internal void DoLink(TypeBuilder typeBuilder)
 
928
                                {
 
929
                                        MethodAttributes attribs = MethodAttributes.HideBySig | MethodAttributes.Public;
 
930
                                        constructor = ReflectUtil.DefineConstructor(typeBuilder, attribs, new Type[] { Types.Object, Types.IntPtr });
 
931
                                        constructor.SetImplementationFlags(MethodImplAttributes.Runtime);
 
932
                                        MethodWrapper mw = GetParameters()[0].GetMethods()[0];
 
933
                                        mw.Link();
 
934
                                        invoke = (MethodInfo)mw.GetMethod();
 
935
                                }
 
936
 
 
937
                                internal override void EmitNewobj(CodeEmitter ilgen)
 
938
                                {
 
939
                                        ilgen.Emit(OpCodes.Dup);
 
940
                                        ilgen.Emit(OpCodes.Ldvirtftn, invoke);
 
941
                                        ilgen.Emit(OpCodes.Newobj, constructor);
 
942
                                }
 
943
                        }
 
944
 
 
945
                        private static bool HasStructLayoutAttributeAnnotation(ClassFile c)
 
946
                        {
 
947
                                if (c.Annotations != null)
 
948
                                {
 
949
                                        foreach (object[] annot in c.Annotations)
 
950
                                        {
 
951
                                                if ("Lcli/System/Runtime/InteropServices/StructLayoutAttribute$Annotation;".Equals(annot[1]))
 
952
                                                {
 
953
                                                        return true;
 
954
                                                }
 
955
                                        }
 
956
                                }
 
957
                                return false;
 
958
                        }
 
959
 
 
960
#if STATIC_COMPILER
 
961
                        private ClassFile.InnerClass getOuterClass()
 
962
                        {
 
963
                                ClassFile.InnerClass[] innerClasses = classFile.InnerClasses;
 
964
                                if (innerClasses != null)
 
965
                                {
 
966
                                        for (int j = 0; j < innerClasses.Length; j++)
 
967
                                        {
 
968
                                                if (innerClasses[j].innerClass != 0
 
969
                                                        && classFile.GetConstantPoolClass(innerClasses[j].innerClass) == classFile.Name)
 
970
                                                {
 
971
                                                        return innerClasses[j];
 
972
                                                }
 
973
                                        }
 
974
                                }
 
975
                                return new ClassFile.InnerClass();
 
976
                        }
 
977
 
 
978
                        private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out bool noop)
 
979
                        {
 
980
                                if (m.ExceptionTable.Length != 0)
 
981
                                {
 
982
                                        noop = false;
 
983
                                        return false;
 
984
                                }
 
985
                                noop = true;
 
986
                                for (int i = 0; i < m.Instructions.Length; i++)
 
987
                                {
 
988
                                        NormalizedByteCode bc = m.Instructions[i].NormalizedOpCode;
 
989
                                        if (bc == NormalizedByteCode.__getstatic || bc == NormalizedByteCode.__putstatic)
 
990
                                        {
 
991
                                                ClassFile.ConstantPoolItemFieldref fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1);
 
992
                                                if (fld == null || fld.Class != classFile.Name)
 
993
                                                {
 
994
                                                        noop = false;
 
995
                                                        return false;
 
996
                                                }
 
997
                                                // don't allow getstatic to load non-primitive fields, because that would
 
998
                                                // cause the verifier to try to load the type
 
999
                                                if (bc == NormalizedByteCode.__getstatic && "L[".IndexOf(fld.Signature[0]) != -1)
 
1000
                                                {
 
1001
                                                        noop = false;
 
1002
                                                        return false;
 
1003
                                                }
 
1004
                                                if (bc == NormalizedByteCode.__putstatic)
 
1005
                                                {
 
1006
                                                        ClassFile.Field field = classFile.GetField(fld.Name, fld.Signature);
 
1007
                                                        if (field == null)
 
1008
                                                        {
 
1009
                                                                noop = false;
 
1010
                                                                return false;
 
1011
                                                        }
 
1012
                                                        if (!field.IsFinal || !field.IsStatic || !field.IsProperty || field.PropertySetter != null)
 
1013
                                                        {
 
1014
                                                                noop = false;
 
1015
                                                        }
 
1016
                                                }
 
1017
                                        }
 
1018
                                        else if (bc == NormalizedByteCode.__areturn ||
 
1019
                                                bc == NormalizedByteCode.__ireturn ||
 
1020
                                                bc == NormalizedByteCode.__lreturn ||
 
1021
                                                bc == NormalizedByteCode.__freturn ||
 
1022
                                                bc == NormalizedByteCode.__dreturn)
 
1023
                                        {
 
1024
                                                noop = false;
 
1025
                                                return false;
 
1026
                                        }
 
1027
                                        else if (ByteCodeMetaData.CanThrowException(bc))
 
1028
                                        {
 
1029
                                                noop = false;
 
1030
                                                return false;
 
1031
                                        }
 
1032
                                        else if (bc == NormalizedByteCode.__aconst_null
 
1033
                                                || bc == NormalizedByteCode.__return
 
1034
                                                || bc == NormalizedByteCode.__nop)
 
1035
                                        {
 
1036
                                                // valid instructions in a potential noop <clinit>
 
1037
                                        }
 
1038
                                        else
 
1039
                                        {
 
1040
                                                noop = false;
 
1041
                                        }
 
1042
                                }
 
1043
                                // the method needs to be verifiable to be side effect free, since we already analysed it,
 
1044
                                // we know that the verifier won't try to load any types (which isn't allowed at this time)
 
1045
                                try
 
1046
                                {
 
1047
                                        new MethodAnalyzer(wrapper, null, classFile, m, wrapper.classLoader);
 
1048
                                        return true;
 
1049
                                }
 
1050
                                catch (VerifyError)
 
1051
                                {
 
1052
                                        return false;
 
1053
                                }
 
1054
                        }
 
1055
#endif // STATIC_COMPILER
 
1056
 
 
1057
                        private MethodWrapper GetMethodWrapperDuringCtor(TypeWrapper lookup, IList<MethodWrapper> methods, string name, string sig)
 
1058
                        {
 
1059
                                if (lookup == wrapper)
 
1060
                                {
 
1061
                                        foreach (MethodWrapper mw in methods)
 
1062
                                        {
 
1063
                                                if (mw.Name == name && mw.Signature == sig)
 
1064
                                                {
 
1065
                                                        return mw;
 
1066
                                                }
 
1067
                                        }
 
1068
                                        if (lookup.BaseTypeWrapper == null)
 
1069
                                        {
 
1070
                                                return null;
 
1071
                                        }
 
1072
                                        else
 
1073
                                        {
 
1074
                                                return lookup.BaseTypeWrapper.GetMethodWrapper(name, sig, true);
 
1075
                                        }
 
1076
                                }
 
1077
                                else
 
1078
                                {
 
1079
                                        return lookup.GetMethodWrapper(name, sig, true);
 
1080
                                }
 
1081
                        }
 
1082
 
 
1083
                        private void AddMirandaMethods(List<MethodWrapper> methods, List<MethodWrapper[]> baseMethods, TypeWrapper tw)
 
1084
                        {
 
1085
                                foreach (TypeWrapper iface in tw.Interfaces)
 
1086
                                {
 
1087
                                        if (iface.IsPublic && this.wrapper.IsInterface)
 
1088
                                        {
 
1089
                                                // for interfaces, we only need miranda methods for non-public interfaces that we extend
 
1090
                                                continue;
 
1091
                                        }
 
1092
                                        AddMirandaMethods(methods, baseMethods, iface);
 
1093
                                        foreach (MethodWrapper ifmethod in iface.GetMethods())
 
1094
                                        {
 
1095
                                                // skip <clinit>
 
1096
                                                if (!ifmethod.IsStatic)
 
1097
                                                {
 
1098
                                                        TypeWrapper lookup = wrapper;
 
1099
                                                        while (lookup != null)
 
1100
                                                        {
 
1101
                                                                MethodWrapper mw = GetMethodWrapperDuringCtor(lookup, methods, ifmethod.Name, ifmethod.Signature);
 
1102
                                                                if (mw == null)
 
1103
                                                                {
 
1104
                                                                        mw = new TypicalMethodWrapper(wrapper, ifmethod.Name, ifmethod.Signature, null, null, null, Modifiers.Public | Modifiers.Abstract, MemberFlags.HideFromReflection | MemberFlags.MirandaMethod);
 
1105
                                                                        methods.Add(mw);
 
1106
                                                                        baseMethods.Add(new MethodWrapper[] { ifmethod });
 
1107
                                                                        break;
 
1108
                                                                }
 
1109
                                                                if (!mw.IsStatic || mw.DeclaringType == wrapper)
 
1110
                                                                {
 
1111
                                                                        break;
 
1112
                                                                }
 
1113
                                                                lookup = mw.DeclaringType.BaseTypeWrapper;
 
1114
                                                        }
 
1115
                                                }
 
1116
                                        }
 
1117
                                }
 
1118
                        }
 
1119
 
 
1120
                        private void AddDelegateInvokeStubs(TypeWrapper tw, ref MethodWrapper[] methods)
 
1121
                        {
 
1122
                                foreach (TypeWrapper iface in tw.Interfaces)
 
1123
                                {
 
1124
                                        if (iface.IsFakeNestedType
 
1125
                                                && iface.GetMethods().Length == 1
 
1126
                                                && iface.GetMethods()[0].IsDelegateInvokeWithByRefParameter)
 
1127
                                        {
 
1128
                                                MethodWrapper mw = new DelegateInvokeStubMethodWrapper(wrapper, iface.DeclaringTypeWrapper.TypeAsBaseType, iface.GetMethods()[0].Signature);
 
1129
                                                if (GetMethodWrapperDuringCtor(wrapper, methods, mw.Name, mw.Signature) == null)
 
1130
                                                {
 
1131
                                                        Array.Resize(ref methods, methods.Length + 1);
 
1132
                                                        methods[methods.Length - 1] = mw;
 
1133
                                                }
 
1134
                                        }
 
1135
                                        AddDelegateInvokeStubs(iface, ref methods);
 
1136
                                }
 
1137
                        }
 
1138
 
 
1139
                        private sealed class DelegateInvokeStubMethodWrapper : MethodWrapper
 
1140
                        {
 
1141
                                private readonly Type delegateType;
 
1142
 
 
1143
                                internal DelegateInvokeStubMethodWrapper(TypeWrapper declaringType, Type delegateType, string sig)
 
1144
                                        : base(declaringType, DotNetTypeWrapper.GetDelegateInvokeStubName(delegateType), sig, null, null, null, Modifiers.Public | Modifiers.Final, MemberFlags.HideFromReflection)
 
1145
                                {
 
1146
                                        this.delegateType = delegateType;
 
1147
                                }
 
1148
 
 
1149
                                internal MethodInfo DoLink(TypeBuilder tb)
 
1150
                                {
 
1151
                                        MethodWrapper mw = this.DeclaringType.GetMethodWrapper("Invoke", this.Signature, true);
 
1152
 
 
1153
                                        MethodInfo invoke = delegateType.GetMethod("Invoke");
 
1154
                                        ParameterInfo[] parameters = invoke.GetParameters();
 
1155
                                        Type[] parameterTypes = new Type[parameters.Length];
 
1156
                                        for (int i = 0; i < parameterTypes.Length; i++)
 
1157
                                        {
 
1158
                                                parameterTypes[i] = parameters[i].ParameterType;
 
1159
                                        }
 
1160
                                        MethodBuilder mb = tb.DefineMethod(this.Name, MethodAttributes.Public, invoke.ReturnType, parameterTypes);
 
1161
                                        AttributeHelper.HideFromReflection(mb);
 
1162
                                        CodeEmitter ilgen = CodeEmitter.Create(mb);
 
1163
                                        if (mw == null || mw.IsStatic || !mw.IsPublic)
 
1164
                                        {
 
1165
                                                ilgen.EmitThrow(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError", DeclaringType.Name + ".Invoke" + Signature);
 
1166
                                                ilgen.DoEmit();
 
1167
                                                return mb;
 
1168
                                        }
 
1169
                                        CodeEmitterLocal[] byrefs = new CodeEmitterLocal[parameters.Length];
 
1170
                                        for (int i = 0; i < parameters.Length; i++)
 
1171
                                        {
 
1172
                                                if (parameters[i].ParameterType.IsByRef)
 
1173
                                                {
 
1174
                                                        Type elemType = parameters[i].ParameterType.GetElementType();
 
1175
                                                        CodeEmitterLocal local = ilgen.DeclareLocal(ArrayTypeWrapper.MakeArrayType(elemType, 1));
 
1176
                                                        byrefs[i] = local;
 
1177
                                                        ilgen.Emit(OpCodes.Ldc_I4_1);
 
1178
                                                        ilgen.Emit(OpCodes.Newarr, elemType);
 
1179
                                                        ilgen.Emit(OpCodes.Stloc, local);
 
1180
                                                        ilgen.Emit(OpCodes.Ldloc, local);
 
1181
                                                        ilgen.Emit(OpCodes.Ldc_I4_0);
 
1182
                                                        ilgen.EmitLdarg(i + 1);
 
1183
                                                        ilgen.Emit(OpCodes.Ldobj, elemType);
 
1184
                                                        ilgen.Emit(OpCodes.Stelem, elemType);
 
1185
                                                }
 
1186
                                        }
 
1187
                                        ilgen.BeginExceptionBlock();
 
1188
                                        ilgen.Emit(OpCodes.Ldarg_0);
 
1189
                                        for (int i = 0; i < parameters.Length; i++)
 
1190
                                        {
 
1191
                                                if (byrefs[i] != null)
 
1192
                                                {
 
1193
                                                        ilgen.Emit(OpCodes.Ldloc, byrefs[i]);
 
1194
                                                }
 
1195
                                                else
 
1196
                                                {
 
1197
                                                        ilgen.EmitLdarg(i + 1);
 
1198
                                                }
 
1199
                                        }
 
1200
                                        mw.Link();
 
1201
                                        mw.EmitCallvirt(ilgen);
 
1202
                                        CodeEmitterLocal returnValue = null;
 
1203
                                        if (mw.ReturnType != PrimitiveTypeWrapper.VOID)
 
1204
                                        {
 
1205
                                                returnValue = ilgen.DeclareLocal(mw.ReturnType.TypeAsSignatureType);
 
1206
                                                ilgen.Emit(OpCodes.Stloc, returnValue);
 
1207
                                        }
 
1208
                                        CodeEmitterLabel exit = ilgen.DefineLabel();
 
1209
                                        ilgen.EmitLeave(exit);
 
1210
                                        ilgen.BeginFinallyBlock();
 
1211
                                        for (int i = 0; i < parameters.Length; i++)
 
1212
                                        {
 
1213
                                                if (byrefs[i] != null)
 
1214
                                                {
 
1215
                                                        Type elemType = byrefs[i].LocalType.GetElementType();
 
1216
                                                        ilgen.EmitLdarg(i + 1);
 
1217
                                                        ilgen.Emit(OpCodes.Ldloc, byrefs[i]);
 
1218
                                                        ilgen.Emit(OpCodes.Ldc_I4_0);
 
1219
                                                        ilgen.Emit(OpCodes.Ldelem, elemType);
 
1220
                                                        ilgen.Emit(OpCodes.Stobj, elemType);
 
1221
                                                }
 
1222
                                        }
 
1223
                                        ilgen.Emit(OpCodes.Endfinally);
 
1224
                                        ilgen.EndExceptionBlock();
 
1225
                                        ilgen.MarkLabel(exit);
 
1226
                                        if (returnValue != null)
 
1227
                                        {
 
1228
                                                ilgen.Emit(OpCodes.Ldloc, returnValue);
 
1229
                                        }
 
1230
                                        ilgen.Emit(OpCodes.Ret);
 
1231
                                        ilgen.DoEmit();
 
1232
                                        return mb;
 
1233
                                }
 
1234
                        }
 
1235
 
 
1236
#if STATIC_COMPILER
 
1237
                        private static bool CheckInnerOuterNames(string inner, string outer)
 
1238
                        {
 
1239
                                // do some sanity checks on the inner/outer class names
 
1240
                                return inner.Length > outer.Length + 1 && inner[outer.Length] == '$' && inner.StartsWith(outer);
 
1241
                        }
 
1242
 
 
1243
                        private string GetInnerClassName(string outer, string inner)
 
1244
                        {
 
1245
                                Debug.Assert(CheckInnerOuterNames(inner, outer));
 
1246
                                if (nestedTypeNames == null)
 
1247
                                {
 
1248
                                        nestedTypeNames = new Dictionary<string, TypeWrapper>();
 
1249
                                }
 
1250
                                return DynamicClassLoader.TypeNameMangleImpl(nestedTypeNames, inner.Substring(outer.Length + 1), null);
 
1251
                        }
 
1252
#endif // STATIC_COMPILER
 
1253
 
 
1254
                        private int GetMethodIndex(MethodWrapper mw)
 
1255
                        {
 
1256
                                for (int i = 0; i < methods.Length; i++)
 
1257
                                {
 
1258
                                        if (methods[i] == mw)
 
1259
                                        {
 
1260
                                                return i;
 
1261
                                        }
 
1262
                                }
 
1263
                                throw new InvalidOperationException();
 
1264
                        }
 
1265
 
 
1266
                        private static void CheckLoaderConstraints(MethodWrapper mw, MethodWrapper baseMethod)
 
1267
                        {
 
1268
#if !STATIC_COMPILER
 
1269
                                if (JVM.FinishingForDebugSave)
 
1270
                                {
 
1271
                                        // when we're finishing types to save a debug image (in dynamic mode) we don't care about loader constraints anymore
 
1272
                                        // (and we can't throw a LinkageError, because that would prevent the debug image from being saved)
 
1273
                                        return;
 
1274
                                }
 
1275
#endif
 
1276
                                if (mw.ReturnType != baseMethod.ReturnType)
 
1277
                                {
 
1278
                                        if (mw.ReturnType.IsUnloadable || baseMethod.ReturnType.IsUnloadable)
 
1279
                                        {
 
1280
                                                // unloadable types can never cause a loader constraint violation
 
1281
                                                if (mw.ReturnType.IsUnloadable && baseMethod.ReturnType.IsUnloadable)
 
1282
                                                {
 
1283
                                                        ((UnloadableTypeWrapper)mw.ReturnType).SetCustomModifier(((UnloadableTypeWrapper)baseMethod.ReturnType).CustomModifier);
 
1284
                                                }
 
1285
                                        }
 
1286
                                        else
 
1287
                                        {
 
1288
#if STATIC_COMPILER
 
1289
                                                StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has a return type \"{1}\"", mw.ReturnType, baseMethod.ReturnType, mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name);
 
1290
#endif
 
1291
                                                throw new LinkageError("Loader constraints violated");
 
1292
                                        }
 
1293
                                }
 
1294
                                TypeWrapper[] here = mw.GetParameters();
 
1295
                                TypeWrapper[] there = baseMethod.GetParameters();
 
1296
                                for (int i = 0; i < here.Length; i++)
 
1297
                                {
 
1298
                                        if (here[i] != there[i])
 
1299
                                        {
 
1300
                                                if (here[i].IsUnloadable || there[i].IsUnloadable)
 
1301
                                                {
 
1302
                                                        // unloadable types can never cause a loader constraint violation
 
1303
                                                        if (here[i].IsUnloadable && there[i].IsUnloadable)
 
1304
                                                        {
 
1305
                                                                ((UnloadableTypeWrapper)here[i]).SetCustomModifier(((UnloadableTypeWrapper)there[i]).CustomModifier);
 
1306
                                                        }
 
1307
                                                }
 
1308
                                                else
 
1309
                                                {
 
1310
#if STATIC_COMPILER
 
1311
                                                        StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has an argument type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has an argument type \"{1}\"", here[i], there[i], mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name);
 
1312
#endif
 
1313
                                                        throw new LinkageError("Loader constraints violated");
 
1314
                                                }
 
1315
                                        }
 
1316
                                }
 
1317
                        }
 
1318
 
 
1319
                        private int GetFieldIndex(FieldWrapper fw)
 
1320
                        {
 
1321
                                for (int i = 0; i < fields.Length; i++)
 
1322
                                {
 
1323
                                        if (fields[i] == fw)
 
1324
                                        {
 
1325
                                                return i;
 
1326
                                        }
 
1327
                                }
 
1328
                                throw new InvalidOperationException();
 
1329
                        }
 
1330
 
 
1331
                        internal override FieldInfo LinkField(FieldWrapper fw)
 
1332
                        {
 
1333
                                if (fw is DynamicPropertyFieldWrapper)
 
1334
                                {
 
1335
                                        ((DynamicPropertyFieldWrapper)fw).DoLink(typeBuilder);
 
1336
                                        return null;
 
1337
                                }
 
1338
                                int fieldIndex = GetFieldIndex(fw);
 
1339
#if STATIC_COMPILER
 
1340
                                // for compatibility with broken Java code that assumes that reflection returns the fields in class declaration
 
1341
                                // order, we emit the fields in class declaration order in the .NET metadata (and then when we retrieve them
 
1342
                                // using .NET reflection, we sort on metadata token.)
 
1343
                                if (fieldIndex > 0)
 
1344
                                {
 
1345
                                        if (!fields[fieldIndex - 1].IsLinked)
 
1346
                                        {
 
1347
                                                for (int i = 0; i < fieldIndex; i++)
 
1348
                                                {
 
1349
                                                        fields[i].Link();
 
1350
                                                }
 
1351
                                        }
 
1352
                                }
 
1353
                                if (fieldIndex >= classFile.Fields.Length)
 
1354
                                {
 
1355
                                        // this must be a field defined in map.xml
 
1356
                                        FieldAttributes fieldAttribs = 0;
 
1357
                                        if (fw.IsPublic)
 
1358
                                        {
 
1359
                                                fieldAttribs |= FieldAttributes.Public;
 
1360
                                        }
 
1361
                                        else if (fw.IsProtected)
 
1362
                                        {
 
1363
                                                fieldAttribs |= FieldAttributes.FamORAssem;
 
1364
                                        }
 
1365
                                        else if (fw.IsPrivate)
 
1366
                                        {
 
1367
                                                fieldAttribs |= FieldAttributes.Private;
 
1368
                                        }
 
1369
                                        else
 
1370
                                        {
 
1371
                                                fieldAttribs |= FieldAttributes.Assembly;
 
1372
                                        }
 
1373
                                        if (fw.IsStatic)
 
1374
                                        {
 
1375
                                                fieldAttribs |= FieldAttributes.Static;
 
1376
                                        }
 
1377
                                        if (fw.IsFinal)
 
1378
                                        {
 
1379
                                                fieldAttribs |= FieldAttributes.InitOnly;
 
1380
                                        }
 
1381
                                        return DefineField(fw.Name, fw.FieldTypeWrapper, fieldAttribs, fw.IsVolatile);
 
1382
                                }
 
1383
#endif // STATIC_COMPILER
 
1384
                                FieldBuilder field;
 
1385
                                ClassFile.Field fld = classFile.Fields[fieldIndex];
 
1386
                                string realFieldName = fld.Name;
 
1387
                                FieldAttributes attribs = 0;
 
1388
                                MethodAttributes methodAttribs = MethodAttributes.HideBySig;
 
1389
#if STATIC_COMPILER
 
1390
                                bool setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0;
 
1391
#endif
 
1392
                                if (fld.IsPrivate)
 
1393
                                {
 
1394
                                        attribs |= FieldAttributes.Private;
 
1395
                                }
 
1396
                                else if (fld.IsProtected)
 
1397
                                {
 
1398
                                        attribs |= FieldAttributes.FamORAssem;
 
1399
                                        methodAttribs |= MethodAttributes.FamORAssem;
 
1400
                                }
 
1401
                                else if (fld.IsPublic)
 
1402
                                {
 
1403
                                        attribs |= FieldAttributes.Public;
 
1404
                                        methodAttribs |= MethodAttributes.Public;
 
1405
                                }
 
1406
                                else
 
1407
                                {
 
1408
                                        attribs |= FieldAttributes.Assembly;
 
1409
                                        methodAttribs |= MethodAttributes.Assembly;
 
1410
                                }
 
1411
 
 
1412
                                if (fld.IsStatic)
 
1413
                                {
 
1414
                                        attribs |= FieldAttributes.Static;
 
1415
                                        methodAttribs |= MethodAttributes.Static;
 
1416
                                }
 
1417
                                // NOTE "constant" static finals are converted into literals
 
1418
                                // TODO it would be possible for Java code to change the value of a non-blank static final, but I don't
 
1419
                                // know if we want to support this (since the Java JITs don't really support it either)
 
1420
                                if (fld.IsStaticFinalConstant)
 
1421
                                {
 
1422
                                        Profiler.Count("Static Final Constant");
 
1423
                                        attribs |= FieldAttributes.Literal;
 
1424
                                        field = DefineField(fld.Name, fw.FieldTypeWrapper, attribs, false);
 
1425
                                        field.SetConstant(fld.ConstantValue);
 
1426
                                }
 
1427
                                else
 
1428
                                {
 
1429
#if STATIC_COMPILER
 
1430
                                        if (wrapper.IsPublic && wrapper.NeedsType2AccessStub(fw))
 
1431
                                        {
 
1432
                                                // this field is going to get a type 2 access stub, so we hide the actual field
 
1433
                                                attribs &= ~FieldAttributes.FieldAccessMask;
 
1434
                                                attribs |= FieldAttributes.Assembly;
 
1435
                                                // instead of adding HideFromJava we rename the field to avoid confusing broken compilers
 
1436
                                                // see https://sourceforge.net/tracker/?func=detail&atid=525264&aid=3056721&group_id=69637
 
1437
                                                // additional note: now that we maintain the ordering of the fields, we need to recognize
 
1438
                                                // these fields so that we know where to insert the corresponding accessor property FieldWrapper.
 
1439
                                                realFieldName = NamePrefix.Type2AccessStubBackingField + fld.Name;
 
1440
                                        }
 
1441
                                        else if (fld.IsFinal)
 
1442
                                        {
 
1443
                                                if (wrapper.IsInterface || wrapper.classLoader.StrictFinalFieldSemantics)
 
1444
                                                {
 
1445
                                                        attribs |= FieldAttributes.InitOnly;
 
1446
                                                }
 
1447
                                                else
 
1448
                                                {
 
1449
                                                        setModifiers = true;
 
1450
                                                }
 
1451
                                        }
 
1452
#else
 
1453
                                        if (fld.IsFinal && wrapper.IsInterface)
 
1454
                                        {
 
1455
                                                attribs |= FieldAttributes.InitOnly;
 
1456
                                        }
 
1457
#endif
 
1458
 
 
1459
                                        field = DefineField(realFieldName, fw.FieldTypeWrapper, attribs, fld.IsVolatile);
 
1460
                                }
 
1461
                                if (fld.IsTransient)
 
1462
                                {
 
1463
                                        CustomAttributeBuilder transientAttrib = new CustomAttributeBuilder(JVM.Import(typeof(NonSerializedAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
1464
                                        field.SetCustomAttribute(transientAttrib);
 
1465
                                }
 
1466
#if STATIC_COMPILER
 
1467
                                {
 
1468
                                        // if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store
 
1469
                                        // the Java modifiers
 
1470
                                        if (setModifiers)
 
1471
                                        {
 
1472
                                                AttributeHelper.SetModifiers(field, fld.Modifiers, fld.IsInternal);
 
1473
                                        }
 
1474
                                        if (fld.DeprecatedAttribute)
 
1475
                                        {
 
1476
                                                AttributeHelper.SetDeprecatedAttribute(field);
 
1477
                                        }
 
1478
                                        if (fld.GenericSignature != null)
 
1479
                                        {
 
1480
                                                AttributeHelper.SetSignatureAttribute(field, fld.GenericSignature);
 
1481
                                        }
 
1482
                                }
 
1483
#endif // STATIC_COMPILER
 
1484
                                return field;
 
1485
                        }
 
1486
 
 
1487
                        private FieldBuilder DefineField(string name, TypeWrapper tw, FieldAttributes attribs, bool isVolatile)
 
1488
                        {
 
1489
                                Type[] modreq = isVolatile ? new Type[] { Types.IsVolatile } : Type.EmptyTypes;
 
1490
                                return typeBuilder.DefineField(name, tw.TypeAsSignatureType, modreq, wrapper.GetModOpt(tw, false), attribs);
 
1491
                        }
 
1492
 
 
1493
                        internal override void EmitRunClassConstructor(CodeEmitter ilgen)
 
1494
                        {
 
1495
                                if (clinitMethod != null)
 
1496
                                {
 
1497
                                        ilgen.Emit(OpCodes.Call, clinitMethod);
 
1498
                                }
 
1499
                        }
 
1500
 
 
1501
                        internal override DynamicImpl Finish()
 
1502
                        {
 
1503
                                if (wrapper.BaseTypeWrapper != null)
 
1504
                                {
 
1505
                                        wrapper.BaseTypeWrapper.Finish();
 
1506
                                }
 
1507
                                // NOTE there is a bug in the CLR (.NET 1.0 & 1.1 [1.2 is not yet available]) that
 
1508
                                // causes the AppDomain.TypeResolve event to receive the incorrect type name for nested types.
 
1509
                                // The Name in the ResolveEventArgs contains only the nested type name, not the full type name,
 
1510
                                // for example, if the type being resolved is "MyOuterType+MyInnerType", then the event only
 
1511
                                // receives "MyInnerType" as the name. Since we only compile inner classes as nested types
 
1512
                                // when we're statically compiling, we can only run into this bug when we're statically compiling.
 
1513
                                // NOTE To work around this bug, we have to make sure that all types that are going to be
 
1514
                                // required in finished form, are finished explicitly here. It isn't clear what other types are
 
1515
                                // required to be finished. I instrumented a static compilation of classpath.dll and this
 
1516
                                // turned up no other cases of the TypeResolve event firing.
 
1517
                                for (int i = 0; i < wrapper.Interfaces.Length; i++)
 
1518
                                {
 
1519
                                        wrapper.Interfaces[i].Finish();
 
1520
                                }
 
1521
                                // make sure all classes are loaded, before we start finishing the type. During finishing, we
 
1522
                                // may not run any Java code, because that might result in a request to finish the type that we
 
1523
                                // are in the process of finishing, and this would be a problem.
 
1524
                                classFile.Link(wrapper);
 
1525
                                for (int i = 0; i < fields.Length; i++)
 
1526
                                {
 
1527
                                        fields[i].Link();
 
1528
                                }
 
1529
                                for (int i = 0; i < methods.Length; i++)
 
1530
                                {
 
1531
                                        methods[i].Link();
 
1532
                                }
 
1533
                                // this is the correct lock, FinishCore doesn't call any user code and mutates global state,
 
1534
                                // so it needs to be protected by a lock.
 
1535
                                lock (this)
 
1536
                                {
 
1537
                                        FinishedTypeImpl impl;
 
1538
                                        try
 
1539
                                        {
 
1540
                                                // call FinishCore in the finally to avoid Thread.Abort interrupting the thread
 
1541
                                        }
 
1542
                                        finally
 
1543
                                        {
 
1544
                                                impl = FinishCore();
 
1545
                                        }
 
1546
                                        return impl;
 
1547
                                }
 
1548
                        }
 
1549
 
 
1550
                        private FinishedTypeImpl FinishCore()
 
1551
                        {
 
1552
                                // it is possible that the loading of the referenced classes triggered a finish of us,
 
1553
                                // if that happens, we just return
 
1554
                                if (finishedType != null)
 
1555
                                {
 
1556
                                        return finishedType;
 
1557
                                }
 
1558
                                if (finishInProgress)
 
1559
                                {
 
1560
                                        throw new InvalidOperationException("Recursive finish attempt for " + wrapper.Name);
 
1561
                                }
 
1562
                                finishInProgress = true;
 
1563
                                Tracer.Info(Tracer.Compiler, "Finishing: {0}", wrapper.Name);
 
1564
                                Profiler.Enter("JavaTypeImpl.Finish.Core");
 
1565
                                try
 
1566
                                {
 
1567
                                        TypeWrapper declaringTypeWrapper = null;
 
1568
                                        TypeWrapper[] innerClassesTypeWrappers = TypeWrapper.EmptyArray;
 
1569
                                        // if we're an inner class, we need to attach an InnerClass attribute
 
1570
                                        ClassFile.InnerClass[] innerclasses = classFile.InnerClasses;
 
1571
                                        if (innerclasses != null)
 
1572
                                        {
 
1573
                                                // TODO consider not pre-computing innerClassesTypeWrappers and declaringTypeWrapper here
 
1574
                                                List<TypeWrapper> wrappers = new List<TypeWrapper>();
 
1575
                                                for (int i = 0; i < innerclasses.Length; i++)
 
1576
                                                {
 
1577
                                                        if (innerclasses[i].innerClass != 0 && innerclasses[i].outerClass != 0)
 
1578
                                                        {
 
1579
                                                                if (classFile.GetConstantPoolClassType(innerclasses[i].outerClass) == wrapper)
 
1580
                                                                {
 
1581
                                                                        wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass));
 
1582
                                                                }
 
1583
                                                                if (classFile.GetConstantPoolClassType(innerclasses[i].innerClass) == wrapper)
 
1584
                                                                {
 
1585
                                                                        declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass);
 
1586
                                                                }
 
1587
                                                        }
 
1588
                                                }
 
1589
                                                innerClassesTypeWrappers = wrappers.ToArray();
 
1590
#if STATIC_COMPILER
 
1591
                                                // before we bake our type, we need to link any inner annotations to allow them to create their attribute type (as a nested type)
 
1592
                                                foreach (TypeWrapper tw in innerClassesTypeWrappers)
 
1593
                                                {
 
1594
                                                        DynamicTypeWrapper dtw = tw as DynamicTypeWrapper;
 
1595
                                                        if (dtw != null)
 
1596
                                                        {
 
1597
                                                                JavaTypeImpl impl = dtw.impl as JavaTypeImpl;
 
1598
                                                                if (impl != null)
 
1599
                                                                {
 
1600
                                                                        if (impl.annotationBuilder != null)
 
1601
                                                                        {
 
1602
                                                                                impl.annotationBuilder.Link();
 
1603
                                                                        }
 
1604
                                                                }
 
1605
                                                        }
 
1606
                                                }
 
1607
#endif //STATIC_COMPILER
 
1608
                                        }
 
1609
#if STATIC_COMPILER
 
1610
                                        if (annotationBuilder != null)
 
1611
                                        {
 
1612
                                                CustomAttributeBuilder cab = new CustomAttributeBuilder(JVM.LoadType(typeof(AnnotationAttributeAttribute)).GetConstructor(new Type[] { Types.String }), new object[] { annotationBuilder.AttributeTypeName });
 
1613
                                                typeBuilder.SetCustomAttribute(cab);
 
1614
                                        }
 
1615
                                        if (!wrapper.IsInterface && wrapper.IsMapUnsafeException)
 
1616
                                        {
 
1617
                                                // mark all exceptions that are unsafe for mapping with a custom attribute,
 
1618
                                                // so that at runtime we can quickly assertain if an exception type can be
 
1619
                                                // caught without filtering
 
1620
                                                AttributeHelper.SetExceptionIsUnsafeForMapping(typeBuilder);
 
1621
                                        }
 
1622
#endif
 
1623
 
 
1624
                                        FinishContext context = new FinishContext(classFile, wrapper, typeBuilder);
 
1625
                                        Type type = context.FinishImpl();
 
1626
#if STATIC_COMPILER
 
1627
                                        if (annotationBuilder != null)
 
1628
                                        {
 
1629
                                                annotationBuilder.Finish(this);
 
1630
                                        }
 
1631
                                        if (enumBuilder != null)
 
1632
                                        {
 
1633
                                                enumBuilder.CreateType();
 
1634
                                        }
 
1635
#endif
 
1636
                                        MethodInfo finishedClinitMethod = clinitMethod;
 
1637
#if !STATIC_COMPILER
 
1638
                                        if (finishedClinitMethod != null)
 
1639
                                        {
 
1640
                                                // In dynamic mode, we may need to emit a call to this method from a DynamicMethod which doesn't support calling unfinished methods,
 
1641
                                                // so we must resolve to the real method here.
 
1642
                                                finishedClinitMethod = type.GetMethod("__<clinit>", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
 
1643
                                        }
 
1644
#endif
 
1645
                                        finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, wrapper.ReflectiveModifiers, Metadata.Create(classFile), finishedClinitMethod, finalizeMethod);
 
1646
                                        return finishedType;
 
1647
                                }
 
1648
#if !STATIC_COMPILER
 
1649
                                catch (Exception x)
 
1650
                                {
 
1651
                                        JVM.CriticalFailure("Exception during finishing of: " + wrapper.Name, x);
 
1652
                                        return null;
 
1653
                                }
 
1654
#endif
 
1655
                                finally
 
1656
                                {
 
1657
                                        Profiler.Leave("JavaTypeImpl.Finish.Core");
 
1658
                                }
 
1659
                        }
 
1660
 
 
1661
#if STATIC_COMPILER
 
1662
                        private bool IsValidAnnotationElementType(string type)
 
1663
                        {
 
1664
                                if (type[0] == '[')
 
1665
                                {
 
1666
                                        type = type.Substring(1);
 
1667
                                }
 
1668
                                switch (type)
 
1669
                                {
 
1670
                                        case "Z":
 
1671
                                        case "B":
 
1672
                                        case "S":
 
1673
                                        case "C":
 
1674
                                        case "I":
 
1675
                                        case "J":
 
1676
                                        case "F":
 
1677
                                        case "D":
 
1678
                                        case "Ljava.lang.String;":
 
1679
                                        case "Ljava.lang.Class;":
 
1680
                                                return true;
 
1681
                                }
 
1682
                                if (type.StartsWith("L") && type.EndsWith(";"))
 
1683
                                {
 
1684
                                        try
 
1685
                                        {
 
1686
                                                TypeWrapper tw = wrapper.GetClassLoader().LoadClassByDottedNameFast(type.Substring(1, type.Length - 2));
 
1687
                                                if (tw != null)
 
1688
                                                {
 
1689
                                                        if ((tw.Modifiers & Modifiers.Annotation) != 0)
 
1690
                                                        {
 
1691
                                                                return true;
 
1692
                                                        }
 
1693
                                                        if ((tw.Modifiers & Modifiers.Enum) != 0)
 
1694
                                                        {
 
1695
                                                                TypeWrapper enumType = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast("java.lang.Enum");
 
1696
                                                                if (enumType != null && tw.IsSubTypeOf(enumType))
 
1697
                                                                {
 
1698
                                                                        return true;
 
1699
                                                                }
 
1700
                                                        }
 
1701
                                                }
 
1702
                                        }
 
1703
                                        catch
 
1704
                                        {
 
1705
                                        }
 
1706
                                }
 
1707
                                return false;
 
1708
                        }
 
1709
 
 
1710
                        sealed class AnnotationBuilder : Annotation
 
1711
                        {
 
1712
                                private JavaTypeImpl impl;
 
1713
                                private TypeBuilder outer;
 
1714
                                private TypeBuilder annotationTypeBuilder;
 
1715
                                private TypeBuilder attributeTypeBuilder;
 
1716
                                private MethodBuilder defineConstructor;
 
1717
 
 
1718
                                internal AnnotationBuilder(JavaTypeImpl o, TypeBuilder outer)
 
1719
                                {
 
1720
                                        this.impl = o;
 
1721
                                        this.outer = outer;
 
1722
                                }
 
1723
 
 
1724
                                internal void Link()
 
1725
                                {
 
1726
                                        if (impl == null)
 
1727
                                        {
 
1728
                                                return;
 
1729
                                        }
 
1730
                                        JavaTypeImpl o = impl;
 
1731
                                        impl = null;
 
1732
 
 
1733
                                        // Make sure the annotation type only has valid methods
 
1734
                                        for (int i = 0; i < o.methods.Length; i++)
 
1735
                                        {
 
1736
                                                if (!o.methods[i].IsStatic)
 
1737
                                                {
 
1738
                                                        if (!o.methods[i].Signature.StartsWith("()"))
 
1739
                                                        {
 
1740
                                                                return;
 
1741
                                                        }
 
1742
                                                        if (!o.IsValidAnnotationElementType(o.methods[i].Signature.Substring(2)))
 
1743
                                                        {
 
1744
                                                                return;
 
1745
                                                        }
 
1746
                                                }
 
1747
                                        }
 
1748
 
 
1749
                                        // we only set annotationTypeBuilder if we're valid
 
1750
                                        annotationTypeBuilder = o.typeBuilder;
 
1751
 
 
1752
                                        TypeWrapper annotationAttributeBaseType = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.AnnotationAttributeBase");
 
1753
 
 
1754
                                        // make sure we don't clash with another class name
 
1755
                                        CompilerClassLoader ccl = o.wrapper.classLoader;
 
1756
                                        string name = o.classFile.Name;
 
1757
                                        while (!ccl.ReserveName(name + "Attribute"))
 
1758
                                        {
 
1759
                                                name += "_";
 
1760
                                        }
 
1761
 
 
1762
                                        TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Sealed;
 
1763
                                        if (o.outerClassWrapper != null)
 
1764
                                        {
 
1765
                                                if (o.wrapper.IsPublic)
 
1766
                                                {
 
1767
                                                        typeAttributes |= TypeAttributes.NestedPublic;
 
1768
                                                }
 
1769
                                                else
 
1770
                                                {
 
1771
                                                        typeAttributes |= TypeAttributes.NestedAssembly;
 
1772
                                                }
 
1773
                                                attributeTypeBuilder = outer.DefineNestedType(o.GetInnerClassName(o.outerClassWrapper.Name, name + "Attribute"), typeAttributes, annotationAttributeBaseType.TypeAsBaseType);
 
1774
                                        }
 
1775
                                        else
 
1776
                                        {
 
1777
                                                if (o.wrapper.IsPublic)
 
1778
                                                {
 
1779
                                                        typeAttributes |= TypeAttributes.Public;
 
1780
                                                }
 
1781
                                                else
 
1782
                                                {
 
1783
                                                        typeAttributes |= TypeAttributes.NotPublic;
 
1784
                                                }
 
1785
                                                attributeTypeBuilder = o.wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name + "Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType);
 
1786
                                        }
 
1787
                                        if (o.wrapper.IsPublic)
 
1788
                                        {
 
1789
                                                // In the Java world, the class appears as a non-public proxy class
 
1790
                                                AttributeHelper.SetModifiers(attributeTypeBuilder, Modifiers.Final, false);
 
1791
                                        }
 
1792
                                        // NOTE we "abuse" the InnerClassAttribute to add a custom attribute to name the class "$Proxy[Annotation]" in the Java world
 
1793
                                        int dotindex = o.classFile.Name.LastIndexOf('.') + 1;
 
1794
                                        AttributeHelper.SetInnerClass(attributeTypeBuilder, o.classFile.Name.Substring(0, dotindex) + "$Proxy" + o.classFile.Name.Substring(dotindex), Modifiers.Final);
 
1795
                                        attributeTypeBuilder.AddInterfaceImplementation(o.typeBuilder);
 
1796
                                        AttributeHelper.SetImplementsAttribute(attributeTypeBuilder, new TypeWrapper[] { o.wrapper });
 
1797
 
 
1798
                                        if (o.classFile.Annotations != null)
 
1799
                                        {
 
1800
                                                CustomAttributeBuilder attributeUsageAttribute = null;
 
1801
                                                bool hasAttributeUsageAttribute = false;
 
1802
                                                foreach (object[] def in o.classFile.Annotations)
 
1803
                                                {
 
1804
                                                        if (def[1].Equals("Ljava/lang/annotation/Target;") && !hasAttributeUsageAttribute)
 
1805
                                                        {
 
1806
                                                                for (int i = 2; i < def.Length; i += 2)
 
1807
                                                                {
 
1808
                                                                        if (def[i].Equals("value"))
 
1809
                                                                        {
 
1810
                                                                                object[] val = def[i + 1] as object[];
 
1811
                                                                                if (val != null
 
1812
                                                                                        && val.Length > 0
 
1813
                                                                                        && val[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY))
 
1814
                                                                                {
 
1815
                                                                                        AttributeTargets targets = 0;
 
1816
                                                                                        for (int j = 1; j < val.Length; j++)
 
1817
                                                                                        {
 
1818
                                                                                                object[] eval = val[j] as object[];
 
1819
                                                                                                if (eval != null
 
1820
                                                                                                        && eval.Length == 3
 
1821
                                                                                                        && eval[0].Equals(AnnotationDefaultAttribute.TAG_ENUM)
 
1822
                                                                                                        && eval[1].Equals("Ljava/lang/annotation/ElementType;"))
 
1823
                                                                                                {
 
1824
                                                                                                        switch ((string)eval[2])
 
1825
                                                                                                        {
 
1826
                                                                                                                case "ANNOTATION_TYPE":
 
1827
                                                                                                                        targets |= AttributeTargets.Interface;
 
1828
                                                                                                                        break;
 
1829
                                                                                                                case "CONSTRUCTOR":
 
1830
                                                                                                                        targets |= AttributeTargets.Constructor;
 
1831
                                                                                                                        break;
 
1832
                                                                                                                case "FIELD":
 
1833
                                                                                                                        targets |= AttributeTargets.Field;
 
1834
                                                                                                                        break;
 
1835
                                                                                                                case "LOCAL_VARIABLE":
 
1836
                                                                                                                        break;
 
1837
                                                                                                                case "METHOD":
 
1838
                                                                                                                        targets |= AttributeTargets.Method;
 
1839
                                                                                                                        break;
 
1840
                                                                                                                case "PACKAGE":
 
1841
                                                                                                                        targets |= AttributeTargets.Interface;
 
1842
                                                                                                                        break;
 
1843
                                                                                                                case "PARAMETER":
 
1844
                                                                                                                        targets |= AttributeTargets.Parameter;
 
1845
                                                                                                                        break;
 
1846
                                                                                                                case "TYPE":
 
1847
                                                                                                                        targets |= AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum;
 
1848
                                                                                                                        break;
 
1849
                                                                                                        }
 
1850
                                                                                                }
 
1851
                                                                                        }
 
1852
                                                                                        attributeUsageAttribute = new CustomAttributeBuilder(JVM.Import(typeof(AttributeUsageAttribute)).GetConstructor(new Type[] { JVM.Import(typeof(AttributeTargets)) }), new object[] { targets });
 
1853
                                                                                }
 
1854
                                                                        }
 
1855
                                                                }
 
1856
                                                        }
 
1857
                                                        else
 
1858
                                                        {
 
1859
                                                                // apply any .NET custom attributes that are on the annotation to the custom attribute we synthesize
 
1860
                                                                // (for example, to allow AttributeUsageAttribute to be overridden)
 
1861
                                                                Annotation annotation = Annotation.Load(o.wrapper.GetClassLoader(), def);
 
1862
                                                                if (annotation != null && annotation.IsCustomAttribute)
 
1863
                                                                {
 
1864
                                                                        annotation.Apply(o.wrapper.GetClassLoader(), attributeTypeBuilder, def);
 
1865
                                                                }
 
1866
                                                                if (def[1].Equals("Lcli/System/AttributeUsageAttribute$Annotation;"))
 
1867
                                                                {
 
1868
                                                                        hasAttributeUsageAttribute = true;
 
1869
                                                                }
 
1870
                                                        }
 
1871
                                                }
 
1872
                                                if (attributeUsageAttribute != null && !hasAttributeUsageAttribute)
 
1873
                                                {
 
1874
                                                        attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute);
 
1875
                                                }
 
1876
                                        }
 
1877
 
 
1878
                                        defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { JVM.Import(typeof(object[])) });
 
1879
                                        AttributeHelper.SetEditorBrowsableNever(defineConstructor);
 
1880
                                }
 
1881
 
 
1882
                                private static Type TypeWrapperToAnnotationParameterType(TypeWrapper tw)
 
1883
                                {
 
1884
                                        bool isArray = false;
 
1885
                                        if (tw.IsArray)
 
1886
                                        {
 
1887
                                                isArray = true;
 
1888
                                                tw = tw.ElementTypeWrapper;
 
1889
                                        }
 
1890
                                        if (tw.Annotation != null)
 
1891
                                        {
 
1892
                                                // we don't support Annotation args
 
1893
                                                return null;
 
1894
                                        }
 
1895
                                        else
 
1896
                                        {
 
1897
                                                Type argType;
 
1898
                                                if (tw == CoreClasses.java.lang.Class.Wrapper)
 
1899
                                                {
 
1900
                                                        argType = Types.Type;
 
1901
                                                }
 
1902
                                                else if (tw.EnumType != null)
 
1903
                                                {
 
1904
                                                        argType = tw.EnumType;
 
1905
                                                }
 
1906
                                                else
 
1907
                                                {
 
1908
                                                        argType = tw.TypeAsSignatureType;
 
1909
                                                }
 
1910
                                                if (isArray)
 
1911
                                                {
 
1912
                                                        argType = ArrayTypeWrapper.MakeArrayType(argType, 1);
 
1913
                                                }
 
1914
                                                return argType;
 
1915
                                        }
 
1916
                                }
 
1917
 
 
1918
                                internal string AttributeTypeName
 
1919
                                {
 
1920
                                        get
 
1921
                                        {
 
1922
                                                Link();
 
1923
                                                if (attributeTypeBuilder != null)
 
1924
                                                {
 
1925
                                                        return attributeTypeBuilder.FullName;
 
1926
                                                }
 
1927
                                                return null;
 
1928
                                        }
 
1929
                                }
 
1930
 
 
1931
                                private static void EmitSetValueCall(TypeWrapper annotationAttributeBaseType, CodeEmitter ilgen, string name, TypeWrapper tw, int argIndex)
 
1932
                                {
 
1933
                                        ilgen.Emit(OpCodes.Ldarg_0);
 
1934
                                        ilgen.Emit(OpCodes.Ldstr, name);
 
1935
                                        ilgen.EmitLdarg(argIndex);
 
1936
                                        if (tw.TypeAsSignatureType.IsValueType)
 
1937
                                        {
 
1938
                                                ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType);
 
1939
                                        }
 
1940
                                        else if (tw.EnumType != null)
 
1941
                                        {
 
1942
                                                ilgen.Emit(OpCodes.Box, tw.EnumType);
 
1943
                                        }
 
1944
                                        MethodWrapper setValueMethod = annotationAttributeBaseType.GetMethodWrapper("setValue", "(Ljava.lang.String;Ljava.lang.Object;)V", false);
 
1945
                                        setValueMethod.Link();
 
1946
                                        setValueMethod.EmitCall(ilgen);
 
1947
                                }
 
1948
 
 
1949
                                internal void Finish(JavaTypeImpl o)
 
1950
                                {
 
1951
                                        Link();
 
1952
                                        if (annotationTypeBuilder == null)
 
1953
                                        {
 
1954
                                                // not a valid annotation type
 
1955
                                                return;
 
1956
                                        }
 
1957
                                        TypeWrapper annotationAttributeBaseType = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.AnnotationAttributeBase");
 
1958
                                        annotationAttributeBaseType.Finish();
 
1959
 
 
1960
                                        int requiredArgCount = 0;
 
1961
                                        int valueArg = -1;
 
1962
                                        bool unsupported = false;
 
1963
                                        for (int i = 0; i < o.methods.Length; i++)
 
1964
                                        {
 
1965
                                                if (!o.methods[i].IsStatic)
 
1966
                                                {
 
1967
                                                        if (valueArg == -1 && o.methods[i].Name == "value")
 
1968
                                                        {
 
1969
                                                                valueArg = i;
 
1970
                                                        }
 
1971
                                                        if (o.classFile.Methods[i].AnnotationDefault == null)
 
1972
                                                        {
 
1973
                                                                if (TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType) == null)
 
1974
                                                                {
 
1975
                                                                        unsupported = true;
 
1976
                                                                        break;
 
1977
                                                                }
 
1978
                                                                requiredArgCount++;
 
1979
                                                        }
 
1980
                                                }
 
1981
                                        }
 
1982
 
 
1983
                                        MethodBuilder defaultConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, unsupported || requiredArgCount > 0 ? MethodAttributes.Private : MethodAttributes.Public, Type.EmptyTypes);
 
1984
                                        CodeEmitter ilgen;
 
1985
 
 
1986
                                        if (!unsupported)
 
1987
                                        {
 
1988
                                                if (requiredArgCount > 0)
 
1989
                                                {
 
1990
                                                        Type[] args = new Type[requiredArgCount];
 
1991
                                                        for (int i = 0, j = 0; i < o.methods.Length; i++)
 
1992
                                                        {
 
1993
                                                                if (!o.methods[i].IsStatic)
 
1994
                                                                {
 
1995
                                                                        if (o.classFile.Methods[i].AnnotationDefault == null)
 
1996
                                                                        {
 
1997
                                                                                args[j++] = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType);
 
1998
                                                                        }
 
1999
                                                                }
 
2000
                                                        }
 
2001
                                                        MethodBuilder reqArgConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, args);
 
2002
                                                        AttributeHelper.HideFromJava(reqArgConstructor);
 
2003
                                                        ilgen = CodeEmitter.Create(reqArgConstructor);
 
2004
                                                        ilgen.Emit(OpCodes.Ldarg_0);
 
2005
                                                        ilgen.Emit(OpCodes.Call, defaultConstructor);
 
2006
                                                        for (int i = 0, j = 0; i < o.methods.Length; i++)
 
2007
                                                        {
 
2008
                                                                if (!o.methods[i].IsStatic)
 
2009
                                                                {
 
2010
                                                                        if (o.classFile.Methods[i].AnnotationDefault == null)
 
2011
                                                                        {
 
2012
                                                                                reqArgConstructor.DefineParameter(++j, ParameterAttributes.None, o.methods[i].Name);
 
2013
                                                                                EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, j);
 
2014
                                                                        }
 
2015
                                                                }
 
2016
                                                        }
 
2017
                                                        ilgen.Emit(OpCodes.Ret);
 
2018
                                                        ilgen.DoEmit();
 
2019
                                                }
 
2020
                                                else if (valueArg != -1)
 
2021
                                                {
 
2022
                                                        // We don't have any required parameters, but we do have an optional "value" parameter,
 
2023
                                                        // so we create an additional constructor (the default constructor will be public in this case)
 
2024
                                                        // that accepts the value parameter.
 
2025
                                                        Type argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType);
 
2026
                                                        if (argType != null)
 
2027
                                                        {
 
2028
                                                                MethodBuilder cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { argType });
 
2029
                                                                AttributeHelper.HideFromJava(cb);
 
2030
                                                                cb.DefineParameter(1, ParameterAttributes.None, "value");
 
2031
                                                                ilgen = CodeEmitter.Create(cb);
 
2032
                                                                ilgen.Emit(OpCodes.Ldarg_0);
 
2033
                                                                ilgen.Emit(OpCodes.Call, defaultConstructor);
 
2034
                                                                EmitSetValueCall(annotationAttributeBaseType, ilgen, "value", o.methods[valueArg].ReturnType, 1);
 
2035
                                                                ilgen.Emit(OpCodes.Ret);
 
2036
                                                                ilgen.DoEmit();
 
2037
                                                        }
 
2038
                                                }
 
2039
                                        }
 
2040
 
 
2041
                                        ilgen = CodeEmitter.Create(defaultConstructor);
 
2042
                                        ilgen.Emit(OpCodes.Ldarg_0);
 
2043
                                        o.wrapper.EmitClassLiteral(ilgen);
 
2044
                                        annotationAttributeBaseType.GetMethodWrapper("<init>", "(Ljava.lang.Class;)V", false).EmitCall(ilgen);
 
2045
                                        ilgen.Emit(OpCodes.Ret);
 
2046
                                        ilgen.DoEmit();
 
2047
 
 
2048
                                        ilgen = CodeEmitter.Create(defineConstructor);
 
2049
                                        ilgen.Emit(OpCodes.Ldarg_0);
 
2050
                                        ilgen.Emit(OpCodes.Call, defaultConstructor);
 
2051
                                        ilgen.Emit(OpCodes.Ldarg_0);
 
2052
                                        ilgen.Emit(OpCodes.Ldarg_1);
 
2053
                                        annotationAttributeBaseType.GetMethodWrapper("setDefinition", "([Ljava.lang.Object;)V", false).EmitCall(ilgen);
 
2054
                                        ilgen.Emit(OpCodes.Ret);
 
2055
                                        ilgen.DoEmit();
 
2056
 
 
2057
                                        MethodWrapper getValueMethod = annotationAttributeBaseType.GetMethodWrapper("getValue", "(Ljava.lang.String;)Ljava.lang.Object;", false);
 
2058
                                        MethodWrapper getByteValueMethod = annotationAttributeBaseType.GetMethodWrapper("getByteValue", "(Ljava.lang.String;)B", false);
 
2059
                                        MethodWrapper getBooleanValueMethod = annotationAttributeBaseType.GetMethodWrapper("getBooleanValue", "(Ljava.lang.String;)Z", false);
 
2060
                                        MethodWrapper getCharValueMethod = annotationAttributeBaseType.GetMethodWrapper("getCharValue", "(Ljava.lang.String;)C", false);
 
2061
                                        MethodWrapper getShortValueMethod = annotationAttributeBaseType.GetMethodWrapper("getShortValue", "(Ljava.lang.String;)S", false);
 
2062
                                        MethodWrapper getIntValueMethod = annotationAttributeBaseType.GetMethodWrapper("getIntValue", "(Ljava.lang.String;)I", false);
 
2063
                                        MethodWrapper getFloatValueMethod = annotationAttributeBaseType.GetMethodWrapper("getFloatValue", "(Ljava.lang.String;)F", false);
 
2064
                                        MethodWrapper getLongValueMethod = annotationAttributeBaseType.GetMethodWrapper("getLongValue", "(Ljava.lang.String;)J", false);
 
2065
                                        MethodWrapper getDoubleValueMethod = annotationAttributeBaseType.GetMethodWrapper("getDoubleValue", "(Ljava.lang.String;)D", false);
 
2066
                                        for (int i = 0; i < o.methods.Length; i++)
 
2067
                                        {
 
2068
                                                // skip <clinit>
 
2069
                                                if (!o.methods[i].IsStatic)
 
2070
                                                {
 
2071
                                                        MethodBuilder mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot);
 
2072
                                                        attributeTypeBuilder.DefineMethodOverride(mb, (MethodInfo)o.methods[i].GetMethod());
 
2073
                                                        ilgen = CodeEmitter.Create(mb);
 
2074
                                                        ilgen.Emit(OpCodes.Ldarg_0);
 
2075
                                                        ilgen.Emit(OpCodes.Ldstr, o.methods[i].Name);
 
2076
                                                        if (o.methods[i].ReturnType.IsPrimitive)
 
2077
                                                        {
 
2078
                                                                if (o.methods[i].ReturnType == PrimitiveTypeWrapper.BYTE)
 
2079
                                                                {
 
2080
                                                                        getByteValueMethod.EmitCall(ilgen);
 
2081
                                                                }
 
2082
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.BOOLEAN)
 
2083
                                                                {
 
2084
                                                                        getBooleanValueMethod.EmitCall(ilgen);
 
2085
                                                                }
 
2086
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.CHAR)
 
2087
                                                                {
 
2088
                                                                        getCharValueMethod.EmitCall(ilgen);
 
2089
                                                                }
 
2090
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.SHORT)
 
2091
                                                                {
 
2092
                                                                        getShortValueMethod.EmitCall(ilgen);
 
2093
                                                                }
 
2094
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.INT)
 
2095
                                                                {
 
2096
                                                                        getIntValueMethod.EmitCall(ilgen);
 
2097
                                                                }
 
2098
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.FLOAT)
 
2099
                                                                {
 
2100
                                                                        getFloatValueMethod.EmitCall(ilgen);
 
2101
                                                                }
 
2102
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.LONG)
 
2103
                                                                {
 
2104
                                                                        getLongValueMethod.EmitCall(ilgen);
 
2105
                                                                }
 
2106
                                                                else if (o.methods[i].ReturnType == PrimitiveTypeWrapper.DOUBLE)
 
2107
                                                                {
 
2108
                                                                        getDoubleValueMethod.EmitCall(ilgen);
 
2109
                                                                }
 
2110
                                                                else
 
2111
                                                                {
 
2112
                                                                        throw new InvalidOperationException();
 
2113
                                                                }
 
2114
                                                        }
 
2115
                                                        else
 
2116
                                                        {
 
2117
                                                                getValueMethod.EmitCall(ilgen);
 
2118
                                                                o.methods[i].ReturnType.EmitCheckcast(null, ilgen);
 
2119
                                                        }
 
2120
                                                        ilgen.Emit(OpCodes.Ret);
 
2121
                                                        ilgen.DoEmit();
 
2122
 
 
2123
                                                        if (o.classFile.Methods[i].AnnotationDefault != null
 
2124
                                                                && !(o.methods[i].Name == "value" && requiredArgCount == 0))
 
2125
                                                        {
 
2126
                                                                // now add a .NET property for this annotation optional parameter
 
2127
                                                                Type argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType);
 
2128
                                                                if (argType != null)
 
2129
                                                                {
 
2130
                                                                        PropertyBuilder pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, Type.EmptyTypes);
 
2131
                                                                        AttributeHelper.HideFromJava(pb);
 
2132
                                                                        MethodBuilder setter = attributeTypeBuilder.DefineMethod("set_" + o.methods[i].Name, MethodAttributes.Public, Types.Void, new Type[] { argType });
 
2133
                                                                        AttributeHelper.HideFromJava(setter);
 
2134
                                                                        pb.SetSetMethod(setter);
 
2135
                                                                        ilgen = CodeEmitter.Create(setter);
 
2136
                                                                        EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, 1);
 
2137
                                                                        ilgen.Emit(OpCodes.Ret);
 
2138
                                                                        ilgen.DoEmit();
 
2139
                                                                        MethodBuilder getter = attributeTypeBuilder.DefineMethod("get_" + o.methods[i].Name, MethodAttributes.Public, argType, Type.EmptyTypes);
 
2140
                                                                        AttributeHelper.HideFromJava(getter);
 
2141
                                                                        pb.SetGetMethod(getter);
 
2142
                                                                        // TODO implement the getter method
 
2143
                                                                        ilgen = CodeEmitter.Create(getter);
 
2144
                                                                        ilgen.ThrowException(JVM.Import(typeof(NotImplementedException)));
 
2145
                                                                        ilgen.DoEmit();
 
2146
                                                                }
 
2147
                                                        }
 
2148
                                                }
 
2149
                                        }
 
2150
                                        attributeTypeBuilder.CreateType();
 
2151
                                }
 
2152
 
 
2153
                                internal override void Apply(ClassLoaderWrapper loader, TypeBuilder tb, object annotation)
 
2154
                                {
 
2155
                                        Link();
 
2156
                                        if (annotationTypeBuilder != null)
 
2157
                                        {
 
2158
                                                annotation = QualifyClassNames(loader, annotation);
 
2159
                                                tb.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2160
                                        }
 
2161
                                }
 
2162
 
 
2163
                                internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation)
 
2164
                                {
 
2165
                                        Link();
 
2166
                                        if (annotationTypeBuilder != null)
 
2167
                                        {
 
2168
                                                annotation = QualifyClassNames(loader, annotation);
 
2169
                                                mb.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2170
                                        }
 
2171
                                }
 
2172
 
 
2173
                                internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation)
 
2174
                                {
 
2175
                                        Link();
 
2176
                                        if (annotationTypeBuilder != null)
 
2177
                                        {
 
2178
                                                annotation = QualifyClassNames(loader, annotation);
 
2179
                                                fb.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2180
                                        }
 
2181
                                }
 
2182
 
 
2183
                                internal override void Apply(ClassLoaderWrapper loader, ParameterBuilder pb, object annotation)
 
2184
                                {
 
2185
                                        Link();
 
2186
                                        if (annotationTypeBuilder != null)
 
2187
                                        {
 
2188
                                                annotation = QualifyClassNames(loader, annotation);
 
2189
                                                pb.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2190
                                        }
 
2191
                                }
 
2192
 
 
2193
                                internal override void Apply(ClassLoaderWrapper loader, AssemblyBuilder ab, object annotation)
 
2194
                                {
 
2195
                                        Link();
 
2196
                                        if (annotationTypeBuilder != null)
 
2197
                                        {
 
2198
                                                annotation = QualifyClassNames(loader, annotation);
 
2199
                                                ab.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2200
                                        }
 
2201
                                }
 
2202
 
 
2203
                                internal override void Apply(ClassLoaderWrapper loader, PropertyBuilder pb, object annotation)
 
2204
                                {
 
2205
                                        Link();
 
2206
                                        if (annotationTypeBuilder != null)
 
2207
                                        {
 
2208
                                                annotation = QualifyClassNames(loader, annotation);
 
2209
                                                pb.SetCustomAttribute(new CustomAttributeBuilder(defineConstructor.__AsConstructorInfo(), new object[] { annotation }));
 
2210
                                        }
 
2211
                                }
 
2212
 
 
2213
                                internal override bool IsCustomAttribute
 
2214
                                {
 
2215
                                        get { return false; }
 
2216
                                }
 
2217
                        }
 
2218
#endif // STATIC_COMPILER
 
2219
 
 
2220
                        internal override TypeWrapper[] InnerClasses
 
2221
                        {
 
2222
                                get
 
2223
                                {
 
2224
                                        throw new InvalidOperationException("InnerClasses is only available for finished types");
 
2225
                                }
 
2226
                        }
 
2227
 
 
2228
                        internal override TypeWrapper DeclaringTypeWrapper
 
2229
                        {
 
2230
                                get
 
2231
                                {
 
2232
                                        throw new InvalidOperationException("DeclaringTypeWrapper is only available for finished types");
 
2233
                                }
 
2234
                        }
 
2235
 
 
2236
                        internal override Modifiers ReflectiveModifiers
 
2237
                        {
 
2238
                                get
 
2239
                                {
 
2240
                                        Modifiers mods;
 
2241
                                        ClassFile.InnerClass[] innerclasses = classFile.InnerClasses;
 
2242
                                        if (innerclasses != null)
 
2243
                                        {
 
2244
                                                for (int i = 0; i < innerclasses.Length; i++)
 
2245
                                                {
 
2246
                                                        if (innerclasses[i].innerClass != 0)
 
2247
                                                        {
 
2248
                                                                if (classFile.GetConstantPoolClass(innerclasses[i].innerClass) == wrapper.Name)
 
2249
                                                                {
 
2250
                                                                        // the mask comes from RECOGNIZED_INNER_CLASS_MODIFIERS in src/hotspot/share/vm/classfile/classFileParser.cpp
 
2251
                                                                        // (minus ACC_SUPER)
 
2252
                                                                        mods = innerclasses[i].accessFlags & (Modifiers)0x761F;
 
2253
                                                                        if (classFile.IsInterface)
 
2254
                                                                        {
 
2255
                                                                                mods |= Modifiers.Abstract;
 
2256
                                                                        }
 
2257
                                                                        return mods;
 
2258
                                                                }
 
2259
                                                        }
 
2260
                                                }
 
2261
                                        }
 
2262
                                        // the mask comes from JVM_RECOGNIZED_CLASS_MODIFIERS in src/hotspot/share/vm/prims/jvm.h
 
2263
                                        // (minus ACC_SUPER)
 
2264
                                        mods = classFile.Modifiers & (Modifiers)0x7611;
 
2265
                                        if (classFile.IsInterface)
 
2266
                                        {
 
2267
                                                mods |= Modifiers.Abstract;
 
2268
                                        }
 
2269
                                        return mods;
 
2270
                                }
 
2271
                        }
 
2272
 
 
2273
                        // this finds all methods that the specified name/sig is going to be overriding
 
2274
                        private MethodWrapper[] FindBaseMethods(ClassFile.Method m, out bool explicitOverride)
 
2275
                        {
 
2276
                                Debug.Assert(!classFile.IsInterface);
 
2277
                                Debug.Assert(m.Name != "<init>");
 
2278
 
 
2279
                                // starting with Java 7 the algorithm changed
 
2280
                                return classFile.MajorVersion >= 51
 
2281
                                        ? FindBaseMethods7(m.Name, m.Signature, m.IsFinal && !m.IsPublic && !m.IsProtected, out explicitOverride)
 
2282
                                        : FindBaseMethodsLegacy(m.Name, m.Signature, out explicitOverride);
 
2283
                        }
 
2284
 
 
2285
                        private MethodWrapper[] FindBaseMethods7(string name, string sig, bool packageFinal, out bool explicitOverride)
 
2286
                        {
 
2287
                                // NOTE this implements the (completely broken) OpenJDK 7 b147 HotSpot behavior,
 
2288
                                // not the algorithm specified in section 5.4.5 of the JavaSE7 JVM spec
 
2289
                                // see http://weblog.ikvm.net/PermaLink.aspx?guid=bde44d8b-7ba9-4e0e-b3a6-b735627118ff and subsequent posts
 
2290
                                explicitOverride = false;
 
2291
                                MethodWrapper topPublicOrProtectedMethod = null;
 
2292
                                TypeWrapper tw = wrapper.BaseTypeWrapper;
 
2293
                                while (tw != null)
 
2294
                                {
 
2295
                                        MethodWrapper baseMethod = tw.GetMethodWrapper(name, sig, true);
 
2296
                                        if (baseMethod == null)
 
2297
                                        {
 
2298
                                                break;
 
2299
                                        }
 
2300
                                        else if (baseMethod.IsAccessStub)
 
2301
                                        {
 
2302
                                                // ignore
 
2303
                                        }
 
2304
                                        else if (!baseMethod.IsStatic && (baseMethod.IsPublic || baseMethod.IsProtected))
 
2305
                                        {
 
2306
                                                topPublicOrProtectedMethod = baseMethod;
 
2307
                                        }
 
2308
                                        tw = baseMethod.DeclaringType.BaseTypeWrapper;
 
2309
                                }
 
2310
                                tw = wrapper.BaseTypeWrapper; 
 
2311
                                while (tw != null)
 
2312
                                {
 
2313
                                        MethodWrapper baseMethod = tw.GetMethodWrapper(name, sig, true);
 
2314
                                        if (baseMethod == null)
 
2315
                                        {
 
2316
                                                break;
 
2317
                                        }
 
2318
                                        else if (baseMethod.IsAccessStub)
 
2319
                                        {
 
2320
                                                // ignore
 
2321
                                        }
 
2322
                                        else if (baseMethod.IsPrivate)
 
2323
                                        {
 
2324
                                                // skip
 
2325
                                        }
 
2326
                                        else if (baseMethod.IsFinal && (baseMethod.IsPublic || baseMethod.IsProtected || baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper)))
 
2327
                                        {
 
2328
                                                throw new VerifyError("final method " + baseMethod.Name + baseMethod.Signature + " in " + baseMethod.DeclaringType.Name + " is overridden in " + wrapper.Name);
 
2329
                                        }
 
2330
                                        else if (baseMethod.IsStatic)
 
2331
                                        {
 
2332
                                                // skip
 
2333
                                        }
 
2334
                                        else if (topPublicOrProtectedMethod == null && !baseMethod.IsPublic && !baseMethod.IsProtected && !baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
 
2335
                                        {
 
2336
                                                // this is a package private method that we're not overriding (unless its vtable stream interleaves ours, which is a case we handle below)
 
2337
                                                explicitOverride = true;
 
2338
                                        }
 
2339
                                        else if (topPublicOrProtectedMethod != null && baseMethod.IsFinal && !baseMethod.IsPublic && !baseMethod.IsProtected && !baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
 
2340
                                        {
 
2341
                                                // this is package private final method that we would override had it not been final, but which is ignored by HotSpot (instead of throwing a VerifyError)
 
2342
                                                explicitOverride = true;
 
2343
                                        }
 
2344
                                        else if (topPublicOrProtectedMethod == null)
 
2345
                                        {
 
2346
                                                if (explicitOverride)
 
2347
                                                {
 
2348
                                                        List<MethodWrapper> list = new List<MethodWrapper>();
 
2349
                                                        list.Add(baseMethod);
 
2350
                                                        // we might still have to override package methods from another package if the vtable streams are interleaved with ours
 
2351
                                                        tw = wrapper.BaseTypeWrapper;
 
2352
                                                        while (tw != null)
 
2353
                                                        {
 
2354
                                                                MethodWrapper baseMethod2 = tw.GetMethodWrapper(name, sig, true);
 
2355
                                                                if (baseMethod2 == null || baseMethod2 == baseMethod)
 
2356
                                                                {
 
2357
                                                                        break;
 
2358
                                                                }
 
2359
                                                                MethodWrapper baseMethod3 = GetPackageBaseMethod(baseMethod.DeclaringType.BaseTypeWrapper, name, sig, baseMethod2.DeclaringType);
 
2360
                                                                if (baseMethod3 != null)
 
2361
                                                                {
 
2362
                                                                        if (baseMethod2.IsFinal)
 
2363
                                                                        {
 
2364
                                                                                baseMethod2 = baseMethod3;
 
2365
                                                                        }
 
2366
                                                                        bool found = false;
 
2367
                                                                        foreach (MethodWrapper mw in list)
 
2368
                                                                        {
 
2369
                                                                                if (mw.DeclaringType.IsPackageAccessibleFrom(baseMethod2.DeclaringType))
 
2370
                                                                                {
 
2371
                                                                                        // we should only add each package once
 
2372
                                                                                        found = true;
 
2373
                                                                                        break;
 
2374
                                                                                }
 
2375
                                                                        }
 
2376
                                                                        if (!found)
 
2377
                                                                        {
 
2378
                                                                                list.Add(baseMethod2);
 
2379
                                                                        }
 
2380
                                                                }
 
2381
                                                                tw = baseMethod2.DeclaringType.BaseTypeWrapper;
 
2382
                                                        }
 
2383
                                                        return list.ToArray();
 
2384
                                                }
 
2385
                                                else
 
2386
                                                {
 
2387
                                                        return new MethodWrapper[] { baseMethod };
 
2388
                                                }
 
2389
                                        }
 
2390
                                        else
 
2391
                                        {
 
2392
                                                if (packageFinal)
 
2393
                                                {
 
2394
                                                        // when a package final method overrides a public or protected method, HotSpot does not mark that vtable slot as final,
 
2395
                                                        // so we need an explicit override to force the MethodAttributes.NewSlot flag, otherwise the CLR won't allow us
 
2396
                                                        // to override the original method in subsequent derived types
 
2397
                                                        explicitOverride = true;
 
2398
                                                }
 
2399
 
 
2400
                                                int majorVersion = 0;
 
2401
                                                if (!baseMethod.IsPublic && !baseMethod.IsProtected &&
 
2402
                                                        ((TryGetClassFileVersion(baseMethod.DeclaringType, ref majorVersion) && majorVersion < 51)
 
2403
                                                        // if TryGetClassFileVersion fails, we know that it is safe to call GetMethod() so we look at the actual method attributes here,
 
2404
                                                        // because access widing ensures that if the method had overridden the top level method it would also be public or protected
 
2405
                                                        || (majorVersion == 0 && (LinkAndGetMethod(baseMethod).Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly)))
 
2406
                                                {
 
2407
                                                        // the method we're overriding is not public or protected, but there is a public or protected top level method,
 
2408
                                                        // this means that baseMethod is part of a class with a major version < 51, so we have to explicitly override the top level method as well
 
2409
                                                        // (we don't need to look for another package method to override, because by necessity baseMethod is already in our package)
 
2410
                                                        return new MethodWrapper[] { baseMethod, topPublicOrProtectedMethod };
 
2411
                                                }
 
2412
                                                else if (!topPublicOrProtectedMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
 
2413
                                                {
 
2414
                                                        // check if there is another method (in the same package) that we should override
 
2415
                                                        tw = topPublicOrProtectedMethod.DeclaringType.BaseTypeWrapper;
 
2416
                                                        while (tw != null)
 
2417
                                                        {
 
2418
                                                                MethodWrapper baseMethod2 = tw.GetMethodWrapper(name, sig, true);
 
2419
                                                                if (baseMethod2 == null)
 
2420
                                                                {
 
2421
                                                                        break;
 
2422
                                                                }
 
2423
                                                                if (baseMethod2.IsAccessStub)
 
2424
                                                                {
 
2425
                                                                        // ignore
 
2426
                                                                }
 
2427
                                                                else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
 
2428
                                                                {
 
2429
                                                                        if (baseMethod2.IsFinal)
 
2430
                                                                        {
 
2431
                                                                                throw new VerifyError("final method " + baseMethod2.Name + baseMethod2.Signature + " in " + baseMethod2.DeclaringType.Name + " is overridden in " + wrapper.Name);
 
2432
                                                                        }
 
2433
                                                                        if (!baseMethod2.IsStatic)
 
2434
                                                                        {
 
2435
                                                                                if (baseMethod2.IsPublic || baseMethod2.IsProtected)
 
2436
                                                                                {
 
2437
                                                                                        break;
 
2438
                                                                                }
 
2439
                                                                                return new MethodWrapper[] { baseMethod, baseMethod2 };
 
2440
                                                                        }
 
2441
                                                                }
 
2442
                                                                tw = baseMethod2.DeclaringType.BaseTypeWrapper;
 
2443
                                                        }
 
2444
                                                }
 
2445
                                                return new MethodWrapper[] { baseMethod };
 
2446
                                        }
 
2447
                                        tw = baseMethod.DeclaringType.BaseTypeWrapper;
 
2448
                                }
 
2449
                                return null;
 
2450
                        }
 
2451
 
 
2452
                        private static MethodBase LinkAndGetMethod(MethodWrapper mw)
 
2453
                        {
 
2454
                                mw.Link();
 
2455
                                return mw.GetMethod();
 
2456
                        }
 
2457
 
 
2458
                        private static bool TryGetClassFileVersion(TypeWrapper tw, ref int majorVersion)
 
2459
                        {
 
2460
                                DynamicTypeWrapper dtw = tw as DynamicTypeWrapper;
 
2461
                                if (dtw != null)
 
2462
                                {
 
2463
                                        JavaTypeImpl impl = dtw.impl as JavaTypeImpl;
 
2464
                                        if (impl != null)
 
2465
                                        {
 
2466
                                                majorVersion = impl.classFile.MajorVersion;
 
2467
                                                return true;
 
2468
                                        }
 
2469
                                }
 
2470
                                return false;
 
2471
                        }
 
2472
 
 
2473
                        private static MethodWrapper GetPackageBaseMethod(TypeWrapper tw, string name, string sig, TypeWrapper package)
 
2474
                        {
 
2475
                                while (tw != null)
 
2476
                                {
 
2477
                                        MethodWrapper mw = tw.GetMethodWrapper(name, sig, true);
 
2478
                                        if (mw == null)
 
2479
                                        {
 
2480
                                                break;
 
2481
                                        }
 
2482
                                        if (mw.DeclaringType.IsPackageAccessibleFrom(package))
 
2483
                                        {
 
2484
                                                return mw.IsFinal ? null : mw;
 
2485
                                        }
 
2486
                                        tw = mw.DeclaringType.BaseTypeWrapper;
 
2487
                                }
 
2488
                                return null;
 
2489
                        }
 
2490
 
 
2491
                        private MethodWrapper[] FindBaseMethodsLegacy(string name, string sig, out bool explicitOverride)
 
2492
                        {
 
2493
                                explicitOverride = false;
 
2494
                                TypeWrapper tw = wrapper.BaseTypeWrapper;
 
2495
                                while (tw != null)
 
2496
                                {
 
2497
                                        MethodWrapper baseMethod = tw.GetMethodWrapper(name, sig, true);
 
2498
                                        if (baseMethod == null)
 
2499
                                        {
 
2500
                                                return null;
 
2501
                                        }
 
2502
                                        else if (baseMethod.IsAccessStub)
 
2503
                                        {
 
2504
                                                // ignore
 
2505
                                        }
 
2506
                                        // here are the complex rules for determining whether this method overrides the method we found
 
2507
                                        // RULE 1: final methods may not be overridden
 
2508
                                        // (note that we intentionally not check IsStatic here!)
 
2509
                                        else if (baseMethod.IsFinal
 
2510
                                                && !baseMethod.IsPrivate
 
2511
                                                && (baseMethod.IsPublic || baseMethod.IsProtected || baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper)))
 
2512
                                        {
 
2513
                                                throw new VerifyError("final method " + baseMethod.Name + baseMethod.Signature + " in " + baseMethod.DeclaringType.Name + " is overridden in " + wrapper.Name);
 
2514
                                        }
 
2515
                                        // RULE 1a: static methods are ignored (other than the RULE 1 check)
 
2516
                                        else if (baseMethod.IsStatic)
 
2517
                                        {
 
2518
                                        }
 
2519
                                        // RULE 2: public & protected methods can be overridden (package methods are handled by RULE 4)
 
2520
                                        // (by public, protected & *package* methods [even if they are in a different package])
 
2521
                                        else if (baseMethod.IsPublic || baseMethod.IsProtected)
 
2522
                                        {
 
2523
                                                // if we already encountered a package method, we cannot override the base method of
 
2524
                                                // that package method
 
2525
                                                if (explicitOverride)
 
2526
                                                {
 
2527
                                                        explicitOverride = false;
 
2528
                                                        return null;
 
2529
                                                }
 
2530
                                                if (!baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
 
2531
                                                {
 
2532
                                                        // check if there is another method (in the same package) that we should override
 
2533
                                                        tw = baseMethod.DeclaringType.BaseTypeWrapper;
 
2534
                                                        while (tw != null)
 
2535
                                                        {
 
2536
                                                                MethodWrapper baseMethod2 = tw.GetMethodWrapper(name, sig, true);
 
2537
                                                                if (baseMethod2 == null)
 
2538
                                                                {
 
2539
                                                                        break;
 
2540
                                                                }
 
2541
                                                                if (baseMethod2.IsAccessStub)
 
2542
                                                                {
 
2543
                                                                        // ignore
 
2544
                                                                }
 
2545
                                                                else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
 
2546
                                                                {
 
2547
                                                                        if (baseMethod2.IsFinal)
 
2548
                                                                        {
 
2549
                                                                                throw new VerifyError("final method " + baseMethod2.Name + baseMethod2.Signature + " in " + baseMethod2.DeclaringType.Name + " is overridden in " + wrapper.Name);
 
2550
                                                                        }
 
2551
                                                                        if (!baseMethod2.IsStatic)
 
2552
                                                                        {
 
2553
                                                                                if (baseMethod2.IsPublic || baseMethod2.IsProtected)
 
2554
                                                                                {
 
2555
                                                                                        break;
 
2556
                                                                                }
 
2557
                                                                                return new MethodWrapper[] { baseMethod, baseMethod2 };
 
2558
                                                                        }
 
2559
                                                                }
 
2560
                                                                tw = baseMethod2.DeclaringType.BaseTypeWrapper;
 
2561
                                                        }
 
2562
                                                }
 
2563
                                                return new MethodWrapper[] { baseMethod };
 
2564
                                        }
 
2565
                                        // RULE 3: private and static methods are ignored
 
2566
                                        else if (!baseMethod.IsPrivate)
 
2567
                                        {
 
2568
                                                // RULE 4: package methods can only be overridden in the same package
 
2569
                                                if (baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper)
 
2570
                                                        || (baseMethod.IsInternal && baseMethod.DeclaringType.InternalsVisibleTo(wrapper)))
 
2571
                                                {
 
2572
                                                        return new MethodWrapper[] { baseMethod };
 
2573
                                                }
 
2574
                                                // since we encountered a method with the same name/signature that we aren't overriding,
 
2575
                                                // we need to specify an explicit override
 
2576
                                                // NOTE we only do this if baseMethod isn't private, because if it is, Reflection.Emit
 
2577
                                                // will complain about the explicit MethodOverride (possibly a bug)
 
2578
                                                explicitOverride = true;
 
2579
                                        }
 
2580
                                        tw = baseMethod.DeclaringType.BaseTypeWrapper;
 
2581
                                }
 
2582
                                return null;
 
2583
                        }
 
2584
 
 
2585
                        private static MethodInfo GetBaseFinalizeMethod(TypeWrapper wrapper)
 
2586
                        {
 
2587
                                for (; ; )
 
2588
                                {
 
2589
                                        // HACK we get called during method linking (which is probably a bad idea) and
 
2590
                                        // it is possible for the base type not to be finished yet, so we look at the
 
2591
                                        // private state of the unfinished base types to find the finalize method.
 
2592
                                        DynamicTypeWrapper dtw = wrapper as DynamicTypeWrapper;
 
2593
                                        if (dtw == null)
 
2594
                                        {
 
2595
                                                break;
 
2596
                                        }
 
2597
                                        MethodWrapper mw = dtw.GetMethodWrapper(StringConstants.FINALIZE, StringConstants.SIG_VOID, false);
 
2598
                                        if (mw != null)
 
2599
                                        {
 
2600
                                                mw.Link();
 
2601
                                        }
 
2602
                                        MethodInfo finalizeImpl = dtw.impl.GetFinalizeMethod();
 
2603
                                        if (finalizeImpl != null)
 
2604
                                        {
 
2605
                                                return finalizeImpl;
 
2606
                                        }
 
2607
                                        wrapper = wrapper.BaseTypeWrapper;
 
2608
                                }
 
2609
                                if (wrapper == CoreClasses.java.lang.Object.Wrapper || wrapper == CoreClasses.java.lang.Throwable.Wrapper)
 
2610
                                {
 
2611
                                        return Types.Object.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance);
 
2612
                                }
 
2613
                                Type type = wrapper.TypeAsBaseType;
 
2614
                                MethodInfo baseFinalize = type.GetMethod("__<Finalize>", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
 
2615
                                if (baseFinalize != null)
 
2616
                                {
 
2617
                                        return baseFinalize;
 
2618
                                }
 
2619
                                while (type != null)
 
2620
                                {
 
2621
                                        foreach (MethodInfo m in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
 
2622
                                        {
 
2623
                                                if (m.Name == "Finalize"
 
2624
                                                        && m.ReturnType == Types.Void
 
2625
                                                        && m.GetParameters().Length == 0)
 
2626
                                                {
 
2627
                                                        if (m.GetBaseDefinition().DeclaringType == Types.Object)
 
2628
                                                        {
 
2629
                                                                return m;
 
2630
                                                        }
 
2631
                                                }
 
2632
                                        }
 
2633
                                        type = type.BaseType;
 
2634
                                }
 
2635
                                return null;
 
2636
                        }
 
2637
 
 
2638
                        private MethodAttributes GetPropertyAccess(MethodWrapper mw)
 
2639
                        {
 
2640
                                string sig = mw.ReturnType.SigName;
 
2641
                                if (sig == "V")
 
2642
                                {
 
2643
                                        sig = mw.GetParameters()[0].SigName;
 
2644
                                }
 
2645
                                int access = -1;
 
2646
                                foreach (ClassFile.Field field in classFile.Fields)
 
2647
                                {
 
2648
                                        if (field.IsProperty
 
2649
                                                && field.IsStatic == mw.IsStatic
 
2650
                                                && field.Signature == sig
 
2651
                                                && (field.PropertyGetter == mw.Name || field.PropertySetter == mw.Name))
 
2652
                                        {
 
2653
                                                int nacc;
 
2654
                                                if (field.IsPublic)
 
2655
                                                {
 
2656
                                                        nacc = 3;
 
2657
                                                }
 
2658
                                                else if (field.IsProtected)
 
2659
                                                {
 
2660
                                                        nacc = 2;
 
2661
                                                }
 
2662
                                                else if (field.IsPrivate)
 
2663
                                                {
 
2664
                                                        nacc = 0;
 
2665
                                                }
 
2666
                                                else
 
2667
                                                {
 
2668
                                                        nacc = 1;
 
2669
                                                }
 
2670
                                                if (nacc > access)
 
2671
                                                {
 
2672
                                                        access = nacc;
 
2673
                                                }
 
2674
                                        }
 
2675
                                }
 
2676
                                switch (access)
 
2677
                                {
 
2678
                                        case 0:
 
2679
                                                return MethodAttributes.Private;
 
2680
                                        case 1:
 
2681
                                                return MethodAttributes.Assembly;
 
2682
                                        case 2:
 
2683
                                                return MethodAttributes.FamORAssem;
 
2684
                                        case 3:
 
2685
                                                return MethodAttributes.Public;
 
2686
                                        default:
 
2687
                                                throw new InvalidOperationException();
 
2688
                                }
 
2689
                        }
 
2690
 
 
2691
                        internal override MethodBase LinkMethod(MethodWrapper mw)
 
2692
                        {
 
2693
                                if (mw is DelegateConstructorMethodWrapper)
 
2694
                                {
 
2695
                                        ((DelegateConstructorMethodWrapper)mw).DoLink(typeBuilder);
 
2696
                                        return null;
 
2697
                                }
 
2698
                                if (mw is DelegateInvokeStubMethodWrapper)
 
2699
                                {
 
2700
                                        return ((DelegateInvokeStubMethodWrapper)mw).DoLink(typeBuilder);
 
2701
                                }
 
2702
                                Debug.Assert(mw != null);
 
2703
                                int index = GetMethodIndex(mw);
 
2704
                                if (baseMethods[index] != null)
 
2705
                                {
 
2706
                                        foreach (MethodWrapper baseMethod in baseMethods[index])
 
2707
                                        {
 
2708
                                                baseMethod.Link();
 
2709
                                                CheckLoaderConstraints(mw, baseMethod);
 
2710
                                        }
 
2711
                                }
 
2712
                                Debug.Assert(mw.GetMethod() == null);
 
2713
                                methods[index].AssertLinked();
 
2714
                                Profiler.Enter("JavaTypeImpl.GenerateMethod");
 
2715
                                try
 
2716
                                {
 
2717
                                        if (index >= classFile.Methods.Length)
 
2718
                                        {
 
2719
                                                if (methods[index].IsMirandaMethod)
 
2720
                                                {
 
2721
                                                        // We're a Miranda method
 
2722
                                                        Debug.Assert(baseMethods[index].Length == 1 && baseMethods[index][0].DeclaringType.IsInterface);
 
2723
                                                        MethodBuilder mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, methods[index].Name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Abstract | MethodAttributes.CheckAccessOnOverride);
 
2724
                                                        AttributeHelper.HideFromReflection(mb);
 
2725
                                                        if (CheckRequireOverrideStub(methods[index], baseMethods[index][0]))
 
2726
                                                        {
 
2727
                                                                wrapper.GenerateOverrideStub(typeBuilder, baseMethods[index][0], mb, methods[index]);
 
2728
                                                        }
 
2729
                                                        // if we changed the name or if the interface method name is remapped, we need to add an explicit methodoverride.
 
2730
                                                        else if (!baseMethods[index][0].IsDynamicOnly && methods[index].Name != baseMethods[index][0].RealName)
 
2731
                                                        {
 
2732
                                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)baseMethods[index][0].GetMethod());
 
2733
                                                        }
 
2734
                                                        return mb;
 
2735
                                                }
 
2736
                                                else
 
2737
                                                {
 
2738
                                                        throw new InvalidOperationException();
 
2739
                                                }
 
2740
                                        }
 
2741
                                        ClassFile.Method m = classFile.Methods[index];
 
2742
                                        MethodBuilder method;
 
2743
                                        bool setModifiers = false;
 
2744
                                        if (methods[index].HasCallerID && (m.Modifiers & Modifiers.VarArgs) != 0)
 
2745
                                        {
 
2746
                                                // the implicit callerID parameter was added at the end so that means we shouldn't use ParamArrayAttribute,
 
2747
                                                // so we need to explicitly record that the method is varargs
 
2748
                                                setModifiers = true;
 
2749
                                        }
 
2750
                                        if (m.IsConstructor)
 
2751
                                        {
 
2752
                                                method = GenerateConstructor(methods[index]);
 
2753
                                                // strictfp is the only modifier that a constructor can have
 
2754
                                                if (m.IsStrictfp)
 
2755
                                                {
 
2756
                                                        setModifiers = true;
 
2757
                                                }
 
2758
                                        }
 
2759
                                        else if (m.IsClassInitializer)
 
2760
                                        {
 
2761
                                                method = ReflectUtil.DefineTypeInitializer(typeBuilder);
 
2762
                                        }
 
2763
                                        else
 
2764
                                        {
 
2765
                                                method = GenerateMethod(index, m, ref setModifiers);
 
2766
                                        }
 
2767
                                        string[] exceptions = m.ExceptionsAttribute;
 
2768
                                        methods[index].SetDeclaredExceptions(exceptions);
 
2769
#if STATIC_COMPILER
 
2770
                                        AttributeHelper.SetThrowsAttribute(method, exceptions);
 
2771
                                        if (setModifiers || m.IsInternal || (m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0)
 
2772
                                        {
 
2773
                                                AttributeHelper.SetModifiers(method, m.Modifiers, m.IsInternal);
 
2774
                                        }
 
2775
                                        if ((m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0
 
2776
                                                && (m.IsPublic || m.IsProtected)
 
2777
                                                && wrapper.IsPublic
 
2778
                                                && !IsAccessBridge(classFile, m))
 
2779
                                        {
 
2780
                                                AttributeHelper.SetEditorBrowsableNever(method);
 
2781
                                                // TODO on WHIDBEY apply CompilerGeneratedAttribute
 
2782
                                        }
 
2783
                                        if (m.DeprecatedAttribute)
 
2784
                                        {
 
2785
                                                AttributeHelper.SetDeprecatedAttribute(method);
 
2786
                                        }
 
2787
                                        if (m.GenericSignature != null)
 
2788
                                        {
 
2789
                                                AttributeHelper.SetSignatureAttribute(method, m.GenericSignature);
 
2790
                                        }
 
2791
#else // STATIC_COMPILER
 
2792
                                        if (setModifiers)
 
2793
                                        {
 
2794
                                                // shut up the compiler
 
2795
                                        }
 
2796
#endif // STATIC_COMPILER
 
2797
                                        return method;
 
2798
                                }
 
2799
                                finally
 
2800
                                {
 
2801
                                        Profiler.Leave("JavaTypeImpl.GenerateMethod");
 
2802
                                }
 
2803
                        }
 
2804
 
 
2805
                        private MethodBuilder GenerateConstructor(MethodWrapper mw)
 
2806
                        {
 
2807
                                MethodBuilder cb = mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig);
 
2808
                                cb.SetImplementationFlags(MethodImplAttributes.NoInlining);
 
2809
                                return cb;
 
2810
                        }
 
2811
 
 
2812
                        private MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifiers)
 
2813
                        {
 
2814
                                MethodAttributes attribs = MethodAttributes.HideBySig;
 
2815
                                if (m.IsNative)
 
2816
                                {
 
2817
                                        if (wrapper.IsPInvokeMethod(m))
 
2818
                                        {
 
2819
                                                // this doesn't appear to be necessary, but we use the flag in Finish to know
 
2820
                                                // that we shouldn't emit a method body
 
2821
                                                attribs |= MethodAttributes.PinvokeImpl;
 
2822
                                        }
 
2823
                                        else
 
2824
                                        {
 
2825
                                                setModifiers = true;
 
2826
                                        }
 
2827
                                }
 
2828
                                if (methods[index].IsPropertyAccessor)
 
2829
                                {
 
2830
                                        attribs |= GetPropertyAccess(methods[index]);
 
2831
                                        attribs |= MethodAttributes.SpecialName;
 
2832
                                        setModifiers = true;
 
2833
                                }
 
2834
                                else
 
2835
                                {
 
2836
                                        attribs |= GetMethodAccess(methods[index]);
 
2837
                                }
 
2838
                                if (m.IsAbstract)
 
2839
                                {
 
2840
                                        // only if the classfile is abstract, we make the CLR method abstract, otherwise,
 
2841
                                        // we have to generate a method that throws an AbstractMethodError (because the JVM
 
2842
                                        // allows abstract methods in non-abstract classes)
 
2843
                                        if (classFile.IsAbstract)
 
2844
                                        {
 
2845
                                                if (classFile.IsPublic && !classFile.IsFinal && !(m.IsPublic || m.IsProtected))
 
2846
                                                {
 
2847
                                                        setModifiers = true;
 
2848
                                                }
 
2849
                                                else
 
2850
                                                {
 
2851
                                                        attribs |= MethodAttributes.Abstract;
 
2852
                                                }
 
2853
                                        }
 
2854
                                        else
 
2855
                                        {
 
2856
                                                setModifiers = true;
 
2857
                                        }
 
2858
                                }
 
2859
                                if (m.IsFinal)
 
2860
                                {
 
2861
                                        if (!m.IsStatic && !m.IsPrivate)
 
2862
                                        {
 
2863
                                                attribs |= MethodAttributes.Final;
 
2864
                                        }
 
2865
                                        else
 
2866
                                        {
 
2867
                                                setModifiers = true;
 
2868
                                        }
 
2869
                                }
 
2870
                                if (m.IsStatic)
 
2871
                                {
 
2872
                                        attribs |= MethodAttributes.Static;
 
2873
                                        if (m.IsSynchronized)
 
2874
                                        {
 
2875
                                                setModifiers = true;
 
2876
                                        }
 
2877
                                }
 
2878
                                else if (!m.IsPrivate)
 
2879
                                {
 
2880
                                        attribs |= MethodAttributes.Virtual | MethodAttributes.CheckAccessOnOverride;
 
2881
                                }
 
2882
                                string name = m.Name;
 
2883
#if STATIC_COMPILER
 
2884
                                if ((m.Modifiers & Modifiers.Bridge) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic)
 
2885
                                {
 
2886
                                        string sigbase = m.Signature.Substring(0, m.Signature.LastIndexOf(')') + 1);
 
2887
                                        foreach (MethodWrapper mw in methods)
 
2888
                                        {
 
2889
                                                if (mw.Name == m.Name && mw.Signature.StartsWith(sigbase) && mw.Signature != m.Signature)
 
2890
                                                {
 
2891
                                                        // To prevent bridge methods with covariant return types from confusing
 
2892
                                                        // other .NET compilers (like C#), we rename the bridge method.
 
2893
                                                        name = NamePrefix.Bridge + name;
 
2894
                                                        break;
 
2895
                                                }
 
2896
                                        }
 
2897
                                }
 
2898
#endif
 
2899
                                if ((attribs & MethodAttributes.Virtual) != 0 && !classFile.IsInterface)
 
2900
                                {
 
2901
                                        if (baseMethods[index] == null || (baseMethods[index].Length == 1 && baseMethods[index][0].DeclaringType.IsInterface))
 
2902
                                        {
 
2903
                                                // we need to set NewSlot here, to prevent accidentally overriding methods
 
2904
                                                // (for example, if a Java class has a method "boolean Equals(object)", we don't want that method
 
2905
                                                // to override System.Object.Equals)
 
2906
                                                attribs |= MethodAttributes.NewSlot;
 
2907
                                        }
 
2908
                                        else
 
2909
                                        {
 
2910
                                                // if we have a method overriding a more accessible method (the JVM allows this), we need to make the
 
2911
                                                // method more accessible, because otherwise the CLR will complain that we're reducing access
 
2912
                                                bool hasPublicBaseMethod = false;
 
2913
                                                foreach (MethodWrapper baseMethodWrapper in baseMethods[index])
 
2914
                                                {
 
2915
                                                        MethodBase baseMethod = baseMethodWrapper.GetMethod();
 
2916
                                                        if ((baseMethod.IsPublic && !m.IsPublic) ||
 
2917
                                                                ((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) ||
 
2918
                                                                (!m.IsPublic && !m.IsProtected && !baseMethodWrapper.DeclaringType.IsPackageAccessibleFrom(wrapper)))
 
2919
                                                        {
 
2920
                                                                hasPublicBaseMethod |= baseMethod.IsPublic;
 
2921
                                                                attribs &= ~MethodAttributes.MemberAccessMask;
 
2922
                                                                attribs |= hasPublicBaseMethod ? MethodAttributes.Public : MethodAttributes.FamORAssem;
 
2923
                                                                setModifiers = true;
 
2924
                                                        }
 
2925
                                                }
 
2926
                                        }
 
2927
                                }
 
2928
                                MethodBuilder mb = null;
 
2929
#if STATIC_COMPILER
 
2930
                                mb = wrapper.DefineGhostMethod(name, attribs, methods[index]);
 
2931
#endif
 
2932
                                if (mb == null)
 
2933
                                {
 
2934
                                        bool needFinalize = false;
 
2935
                                        bool needDispatch = false;
 
2936
                                        MethodInfo baseFinalize = null;
 
2937
                                        if (baseMethods[index] != null && ReferenceEquals(m.Name, StringConstants.FINALIZE) && ReferenceEquals(m.Signature, StringConstants.SIG_VOID))
 
2938
                                        {
 
2939
                                                baseFinalize = GetBaseFinalizeMethod(wrapper.BaseTypeWrapper);
 
2940
                                                if (baseMethods[index][0].DeclaringType == CoreClasses.java.lang.Object.Wrapper)
 
2941
                                                {
 
2942
                                                        // This type is the first type in the hierarchy to introduce a finalize method
 
2943
                                                        // (other than the one in java.lang.Object obviously), so we need to override
 
2944
                                                        // the real Finalize method and emit a dispatch call to our finalize method.
 
2945
                                                        needFinalize = true;
 
2946
                                                        needDispatch = true;
 
2947
                                                }
 
2948
                                                else if (m.IsFinal)
 
2949
                                                {
 
2950
                                                        // One of our base classes already has a  finalize method, so we already are
 
2951
                                                        // hooked into the real Finalize, but we need to override it again, to make it
 
2952
                                                        // final (so that non-Java types cannot override it either).
 
2953
                                                        needFinalize = true;
 
2954
                                                        needDispatch = false;
 
2955
                                                        // If the base class finalize was optimized away, we need a dispatch call after all.
 
2956
                                                        if (baseFinalize.DeclaringType == Types.Object)
 
2957
                                                        {
 
2958
                                                                needDispatch = true;
 
2959
                                                        }
 
2960
                                                }
 
2961
                                                else
 
2962
                                                {
 
2963
                                                        // One of our base classes already has a finalize method, but it may have been an empty
 
2964
                                                        // method so that the hookup to the real Finalize was optimized away, we need to check
 
2965
                                                        // for that.
 
2966
                                                        if (baseFinalize.DeclaringType == Types.Object)
 
2967
                                                        {
 
2968
                                                                needFinalize = true;
 
2969
                                                                needDispatch = true;
 
2970
                                                        }
 
2971
                                                }
 
2972
                                                if (needFinalize &&
 
2973
                                                        !m.IsAbstract && !m.IsNative &&
 
2974
                                                        (!m.IsFinal || classFile.IsFinal) &&
 
2975
                                                        m.Instructions.Length > 0 &&
 
2976
                                                        m.Instructions[0].NormalizedOpCode == NormalizedByteCode.__return)
 
2977
                                                {
 
2978
                                                        // we've got an empty finalize method, so we don't need to override the real finalizer
 
2979
                                                        // (not having a finalizer makes a huge perf difference)
 
2980
                                                        needFinalize = false;
 
2981
                                                }
 
2982
                                        }
 
2983
                                        bool newslot = baseMethods[index] != null
 
2984
                                                && (methods[index].IsExplicitOverride || baseMethods[index][0].RealName != name || CheckRequireOverrideStub(methods[index], baseMethods[index][0]))
 
2985
                                                && !needFinalize;
 
2986
                                        if (newslot)
 
2987
                                        {
 
2988
                                                attribs |= MethodAttributes.NewSlot;
 
2989
                                        }
 
2990
                                        mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, attribs);
 
2991
                                        if (baseMethods[index] != null && !needFinalize)
 
2992
                                        {
 
2993
                                                bool subsequent = false;
 
2994
                                                foreach (MethodWrapper baseMethod in baseMethods[index])
 
2995
                                                {
 
2996
                                                        if (CheckRequireOverrideStub(methods[index], baseMethod))
 
2997
                                                        {
 
2998
                                                                wrapper.GenerateOverrideStub(typeBuilder, baseMethod, mb, methods[index]);
 
2999
                                                        }
 
3000
                                                        else if (subsequent || methods[index].IsExplicitOverride || baseMethod.RealName != name)
 
3001
                                                        {
 
3002
                                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)baseMethod.GetMethod());
 
3003
                                                        }
 
3004
                                                        // the non-primary base methods always need an explicit method override
 
3005
                                                        subsequent = true;
 
3006
                                                }
 
3007
                                        }
 
3008
                                        // if we're overriding java.lang.Object.finalize we need to emit a stub to override System.Object.Finalize,
 
3009
                                        // or if we're subclassing a non-Java class that has a Finalize method, we need a new Finalize override
 
3010
                                        if (needFinalize)
 
3011
                                        {
 
3012
                                                string finalizeName = baseFinalize.Name;
 
3013
                                                MethodWrapper mwClash = wrapper.GetMethodWrapper(finalizeName, StringConstants.SIG_VOID, true);
 
3014
                                                if (mwClash != null && mwClash.GetMethod() != baseFinalize)
 
3015
                                                {
 
3016
                                                        finalizeName = "__<Finalize>";
 
3017
                                                }
 
3018
                                                MethodAttributes attr = MethodAttributes.HideBySig | MethodAttributes.Virtual;
 
3019
                                                // make sure we don't reduce accessibility
 
3020
                                                attr |= baseFinalize.IsPublic ? MethodAttributes.Public : MethodAttributes.Family;
 
3021
                                                if (m.IsFinal)
 
3022
                                                {
 
3023
                                                        attr |= MethodAttributes.Final;
 
3024
                                                }
 
3025
                                                finalizeMethod = typeBuilder.DefineMethod(finalizeName, attr, CallingConventions.Standard, Types.Void, Type.EmptyTypes);
 
3026
                                                if (finalizeName != baseFinalize.Name)
 
3027
                                                {
 
3028
                                                        typeBuilder.DefineMethodOverride(finalizeMethod, baseFinalize);
 
3029
                                                }
 
3030
                                                AttributeHelper.HideFromJava(finalizeMethod);
 
3031
                                                CodeEmitter ilgen = CodeEmitter.Create(finalizeMethod);
 
3032
                                                ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.SkipFinalizer);
 
3033
                                                CodeEmitterLabel skip = ilgen.DefineLabel();
 
3034
                                                ilgen.EmitBrtrue(skip);
 
3035
                                                if (needDispatch)
 
3036
                                                {
 
3037
                                                        ilgen.BeginExceptionBlock();
 
3038
                                                        ilgen.Emit(OpCodes.Ldarg_0);
 
3039
                                                        ilgen.Emit(OpCodes.Callvirt, mb);
 
3040
                                                        ilgen.EmitLeave(skip);
 
3041
                                                        ilgen.BeginCatchBlock(Types.Object);
 
3042
                                                        ilgen.EmitLeave(skip);
 
3043
                                                        ilgen.EndExceptionBlock();
 
3044
                                                }
 
3045
                                                else
 
3046
                                                {
 
3047
                                                        ilgen.Emit(OpCodes.Ldarg_0);
 
3048
                                                        ilgen.Emit(OpCodes.Call, baseFinalize);
 
3049
                                                }
 
3050
                                                ilgen.MarkLabel(skip);
 
3051
                                                ilgen.Emit(OpCodes.Ret);
 
3052
                                                ilgen.DoEmit();
 
3053
                                        }
 
3054
#if STATIC_COMPILER
 
3055
                                        if (classFile.Methods[index].AnnotationDefault != null)
 
3056
                                        {
 
3057
                                                CustomAttributeBuilder cab = new CustomAttributeBuilder(StaticCompiler.GetRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor(new Type[] { Types.Object }), new object[] { classFile.Methods[index].AnnotationDefault });
 
3058
                                                mb.SetCustomAttribute(cab);
 
3059
                                        }
 
3060
#endif // STATIC_COMPILER
 
3061
                                }
 
3062
 
 
3063
                                if ((methods[index].Modifiers & (Modifiers.Synchronized | Modifiers.Static)) == Modifiers.Synchronized)
 
3064
                                {
 
3065
                                        mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.Synchronized);
 
3066
                                }
 
3067
 
 
3068
                                return mb;
 
3069
                        }
 
3070
 
 
3071
                        private static MethodAttributes GetMethodAccess(MethodWrapper mw)
 
3072
                        {
 
3073
                                switch (mw.Modifiers & Modifiers.AccessMask)
 
3074
                                {
 
3075
                                        case Modifiers.Private:
 
3076
                                                return MethodAttributes.Private;
 
3077
                                        case Modifiers.Protected:
 
3078
                                                return MethodAttributes.FamORAssem;
 
3079
                                        case Modifiers.Public:
 
3080
                                                return MethodAttributes.Public;
 
3081
                                        default:
 
3082
                                                return MethodAttributes.Assembly;
 
3083
                                }
 
3084
                        }
 
3085
 
 
3086
#if STATIC_COMPILER
 
3087
                        // The classic example of an access bridge is StringBuilder.length(), the JDK 6 compiler
 
3088
                        // generates this to work around a reflection problem (which otherwise wouldn't surface the
 
3089
                        // length() method, because it is defined in the non-public base class AbstractStringBuilder.)
 
3090
                        private static bool IsAccessBridge(ClassFile classFile, ClassFile.Method m)
 
3091
                        {
 
3092
                                // HACK this is a pretty gross hack
 
3093
                                // We look at the method body to figure out if the bridge method calls another method with the exact
 
3094
                                // same name/signature and if that is the case, we assume that it is an access bridge.
 
3095
                                // This code is based on the javac algorithm in addBridgeIfNeeded(...) in com/sun/tools/javac/comp/TransTypes.java.
 
3096
                                if ((m.Modifiers & (Modifiers.Abstract | Modifiers.Native | Modifiers.Public | Modifiers.Bridge)) == (Modifiers.Public | Modifiers.Bridge))
 
3097
                                {
 
3098
                                        foreach (ClassFile.Method.Instruction instr in m.Instructions)
 
3099
                                        {
 
3100
                                                if (instr.NormalizedOpCode == NormalizedByteCode.__invokespecial)
 
3101
                                                {
 
3102
                                                        ClassFile.ConstantPoolItemMI cpi = classFile.SafeGetMethodref(instr.Arg1);
 
3103
                                                        return cpi != null && cpi.Name == m.Name && cpi.Signature == m.Signature;
 
3104
                                                }
 
3105
                                        }
 
3106
                                }
 
3107
                                return false;
 
3108
                        }
 
3109
#endif // STATIC_COMPILER
 
3110
 
 
3111
                        internal override Type Type
 
3112
                        {
 
3113
                                get
 
3114
                                {
 
3115
                                        return typeBuilder;
 
3116
                                }
 
3117
                        }
 
3118
 
 
3119
                        internal override string GetGenericSignature()
 
3120
                        {
 
3121
                                Debug.Fail("Unreachable code");
 
3122
                                return null;
 
3123
                        }
 
3124
 
 
3125
                        internal override string[] GetEnclosingMethod()
 
3126
                        {
 
3127
                                Debug.Fail("Unreachable code");
 
3128
                                return null;
 
3129
                        }
 
3130
 
 
3131
                        internal override string GetGenericMethodSignature(int index)
 
3132
                        {
 
3133
                                Debug.Fail("Unreachable code");
 
3134
                                return null;
 
3135
                        }
 
3136
 
 
3137
                        internal override string GetGenericFieldSignature(int index)
 
3138
                        {
 
3139
                                Debug.Fail("Unreachable code");
 
3140
                                return null;
 
3141
                        }
 
3142
 
 
3143
                        internal override object[] GetDeclaredAnnotations()
 
3144
                        {
 
3145
                                Debug.Fail("Unreachable code");
 
3146
                                return null;
 
3147
                        }
 
3148
 
 
3149
                        internal override object GetMethodDefaultValue(int index)
 
3150
                        {
 
3151
                                Debug.Fail("Unreachable code");
 
3152
                                return null;
 
3153
                        }
 
3154
 
 
3155
                        internal override object[] GetMethodAnnotations(int index)
 
3156
                        {
 
3157
                                Debug.Fail("Unreachable code");
 
3158
                                return null;
 
3159
                        }
 
3160
 
 
3161
                        internal override object[][] GetParameterAnnotations(int index)
 
3162
                        {
 
3163
                                Debug.Fail("Unreachable code");
 
3164
                                return null;
 
3165
                        }
 
3166
 
 
3167
                        internal override object[] GetFieldAnnotations(int index)
 
3168
                        {
 
3169
                                Debug.Fail("Unreachable code");
 
3170
                                return null;
 
3171
                        }
 
3172
 
 
3173
                        internal override MethodInfo GetFinalizeMethod()
 
3174
                        {
 
3175
                                return finalizeMethod;
 
3176
                        }
 
3177
                }
 
3178
 
 
3179
                private sealed class Metadata
 
3180
                {
 
3181
                        private string[][] genericMetaData;
 
3182
                        private object[][] annotations;
 
3183
 
 
3184
                        private Metadata(string[][] genericMetaData, object[][] annotations)
 
3185
                        {
 
3186
                                this.genericMetaData = genericMetaData;
 
3187
                                this.annotations = annotations;
 
3188
                        }
 
3189
 
 
3190
                        internal static Metadata Create(ClassFile classFile)
 
3191
                        {
 
3192
                                if (classFile.MajorVersion < 49)
 
3193
                                {
 
3194
                                        return null;
 
3195
                                }
 
3196
                                string[][] genericMetaData = null;
 
3197
                                object[][] annotations = null;
 
3198
                                for (int i = 0; i < classFile.Methods.Length; i++)
 
3199
                                {
 
3200
                                        if (classFile.Methods[i].GenericSignature != null)
 
3201
                                        {
 
3202
                                                if (genericMetaData == null)
 
3203
                                                {
 
3204
                                                        genericMetaData = new string[4][];
 
3205
                                                }
 
3206
                                                if (genericMetaData[0] == null)
 
3207
                                                {
 
3208
                                                        genericMetaData[0] = new string[classFile.Methods.Length];
 
3209
                                                }
 
3210
                                                genericMetaData[0][i] = classFile.Methods[i].GenericSignature;
 
3211
                                        }
 
3212
                                        if (classFile.Methods[i].Annotations != null)
 
3213
                                        {
 
3214
                                                if (annotations == null)
 
3215
                                                {
 
3216
                                                        annotations = new object[5][];
 
3217
                                                }
 
3218
                                                if (annotations[1] == null)
 
3219
                                                {
 
3220
                                                        annotations[1] = new object[classFile.Methods.Length];
 
3221
                                                }
 
3222
                                                annotations[1][i] = classFile.Methods[i].Annotations;
 
3223
                                        }
 
3224
                                        if (classFile.Methods[i].ParameterAnnotations != null)
 
3225
                                        {
 
3226
                                                if (annotations == null)
 
3227
                                                {
 
3228
                                                        annotations = new object[5][];
 
3229
                                                }
 
3230
                                                if (annotations[2] == null)
 
3231
                                                {
 
3232
                                                        annotations[2] = new object[classFile.Methods.Length];
 
3233
                                                }
 
3234
                                                annotations[2][i] = classFile.Methods[i].ParameterAnnotations;
 
3235
                                        }
 
3236
                                        if (classFile.Methods[i].AnnotationDefault != null)
 
3237
                                        {
 
3238
                                                if (annotations == null)
 
3239
                                                {
 
3240
                                                        annotations = new object[5][];
 
3241
                                                }
 
3242
                                                if (annotations[3] == null)
 
3243
                                                {
 
3244
                                                        annotations[3] = new object[classFile.Methods.Length];
 
3245
                                                }
 
3246
                                                annotations[3][i] = classFile.Methods[i].AnnotationDefault;
 
3247
                                        }
 
3248
                                }
 
3249
                                for (int i = 0; i < classFile.Fields.Length; i++)
 
3250
                                {
 
3251
                                        if (classFile.Fields[i].GenericSignature != null)
 
3252
                                        {
 
3253
                                                if (genericMetaData == null)
 
3254
                                                {
 
3255
                                                        genericMetaData = new string[4][];
 
3256
                                                }
 
3257
                                                if (genericMetaData[1] == null)
 
3258
                                                {
 
3259
                                                        genericMetaData[1] = new string[classFile.Fields.Length];
 
3260
                                                }
 
3261
                                                genericMetaData[1][i] = classFile.Fields[i].GenericSignature;
 
3262
                                        }
 
3263
                                        if (classFile.Fields[i].Annotations != null)
 
3264
                                        {
 
3265
                                                if (annotations == null)
 
3266
                                                {
 
3267
                                                        annotations = new object[5][];
 
3268
                                                }
 
3269
                                                if (annotations[4] == null)
 
3270
                                                {
 
3271
                                                        annotations[4] = new object[classFile.Fields.Length][];
 
3272
                                                }
 
3273
                                                annotations[4][i] = classFile.Fields[i].Annotations;
 
3274
                                        }
 
3275
                                }
 
3276
                                if (classFile.EnclosingMethod != null)
 
3277
                                {
 
3278
                                        if (genericMetaData == null)
 
3279
                                        {
 
3280
                                                genericMetaData = new string[4][];
 
3281
                                        }
 
3282
                                        genericMetaData[2] = classFile.EnclosingMethod;
 
3283
                                }
 
3284
                                if (classFile.GenericSignature != null)
 
3285
                                {
 
3286
                                        if (genericMetaData == null)
 
3287
                                        {
 
3288
                                                genericMetaData = new string[4][];
 
3289
                                        }
 
3290
                                        genericMetaData[3] = new string[] { classFile.GenericSignature };
 
3291
                                }
 
3292
                                if (classFile.Annotations != null)
 
3293
                                {
 
3294
                                        if (annotations == null)
 
3295
                                        {
 
3296
                                                annotations = new object[5][];
 
3297
                                        }
 
3298
                                        annotations[0] = classFile.Annotations;
 
3299
                                }
 
3300
                                if (genericMetaData != null || annotations != null)
 
3301
                                {
 
3302
                                        return new Metadata(genericMetaData, annotations);
 
3303
                                }
 
3304
                                return null;
 
3305
                        }
 
3306
 
 
3307
                        internal static string GetGenericSignature(Metadata m)
 
3308
                        {
 
3309
                                if (m != null && m.genericMetaData != null && m.genericMetaData[3] != null)
 
3310
                                {
 
3311
                                        return m.genericMetaData[3][0];
 
3312
                                }
 
3313
                                return null;
 
3314
                        }
 
3315
 
 
3316
                        internal static string[] GetEnclosingMethod(Metadata m)
 
3317
                        {
 
3318
                                if (m != null && m.genericMetaData != null)
 
3319
                                {
 
3320
                                        return m.genericMetaData[2];
 
3321
                                }
 
3322
                                return null;
 
3323
                        }
 
3324
 
 
3325
                        internal static string GetGenericMethodSignature(Metadata m, int index)
 
3326
                        {
 
3327
                                if (m != null && m.genericMetaData != null && m.genericMetaData[0] != null)
 
3328
                                {
 
3329
                                        return m.genericMetaData[0][index];
 
3330
                                }
 
3331
                                return null;
 
3332
                        }
 
3333
 
 
3334
                        internal static string GetGenericFieldSignature(Metadata m, int index)
 
3335
                        {
 
3336
                                if (m != null && m.genericMetaData != null && m.genericMetaData[1] != null)
 
3337
                                {
 
3338
                                        return m.genericMetaData[1][index];
 
3339
                                }
 
3340
                                return null;
 
3341
                        }
 
3342
 
 
3343
                        internal static object[] GetAnnotations(Metadata m)
 
3344
                        {
 
3345
                                if (m != null && m.annotations != null)
 
3346
                                {
 
3347
                                        return m.annotations[0];
 
3348
                                }
 
3349
                                return null;
 
3350
                        }
 
3351
 
 
3352
                        internal static object[] GetMethodAnnotations(Metadata m, int index)
 
3353
                        {
 
3354
                                if (m != null && m.annotations != null && m.annotations[1] != null)
 
3355
                                {
 
3356
                                        return (object[])m.annotations[1][index];
 
3357
                                }
 
3358
                                return null;
 
3359
                        }
 
3360
 
 
3361
                        internal static object[][] GetMethodParameterAnnotations(Metadata m, int index)
 
3362
                        {
 
3363
                                if (m != null && m.annotations != null && m.annotations[2] != null)
 
3364
                                {
 
3365
                                        return (object[][])m.annotations[2][index];
 
3366
                                }
 
3367
                                return null;
 
3368
                        }
 
3369
 
 
3370
                        internal static object GetMethodDefaultValue(Metadata m, int index)
 
3371
                        {
 
3372
                                if (m != null && m.annotations != null && m.annotations[3] != null)
 
3373
                                {
 
3374
                                        return m.annotations[3][index];
 
3375
                                }
 
3376
                                return null;
 
3377
                        }
 
3378
 
 
3379
                        // note that unlike GetGenericFieldSignature, the index is simply the field index 
 
3380
                        internal static object[] GetFieldAnnotations(Metadata m, int index)
 
3381
                        {
 
3382
                                if (m != null && m.annotations != null && m.annotations[4] != null)
 
3383
                                {
 
3384
                                        return (object[])m.annotations[4][index];
 
3385
                                }
 
3386
                                return null;
 
3387
                        }
 
3388
                }
 
3389
 
 
3390
                private sealed class FinishedTypeImpl : DynamicImpl
 
3391
                {
 
3392
                        private Type type;
 
3393
                        private TypeWrapper[] innerclasses;
 
3394
                        private TypeWrapper declaringTypeWrapper;
 
3395
                        private Modifiers reflectiveModifiers;
 
3396
                        private MethodInfo clinitMethod;
 
3397
                        private MethodInfo finalizeMethod;
 
3398
                        private Metadata metadata;
 
3399
 
 
3400
                        internal FinishedTypeImpl(Type type, TypeWrapper[] innerclasses, TypeWrapper declaringTypeWrapper, Modifiers reflectiveModifiers, Metadata metadata, MethodInfo clinitMethod, MethodInfo finalizeMethod)
 
3401
                        {
 
3402
                                this.type = type;
 
3403
                                this.innerclasses = innerclasses;
 
3404
                                this.declaringTypeWrapper = declaringTypeWrapper;
 
3405
                                this.reflectiveModifiers = reflectiveModifiers;
 
3406
                                this.clinitMethod = clinitMethod;
 
3407
                                this.finalizeMethod = finalizeMethod;
 
3408
                                this.metadata = metadata;
 
3409
                        }
 
3410
 
 
3411
                        internal override TypeWrapper[] InnerClasses
 
3412
                        {
 
3413
                                get
 
3414
                                {
 
3415
                                        // TODO compute the innerclasses lazily (and fix JavaTypeImpl to not always compute them)
 
3416
                                        return innerclasses;
 
3417
                                }
 
3418
                        }
 
3419
 
 
3420
                        internal override TypeWrapper DeclaringTypeWrapper
 
3421
                        {
 
3422
                                get
 
3423
                                {
 
3424
                                        // TODO compute lazily (and fix JavaTypeImpl to not always compute it)
 
3425
                                        return declaringTypeWrapper;
 
3426
                                }
 
3427
                        }
 
3428
 
 
3429
                        internal override Modifiers ReflectiveModifiers
 
3430
                        {
 
3431
                                get
 
3432
                                {
 
3433
                                        return reflectiveModifiers;
 
3434
                                }
 
3435
                        }
 
3436
 
 
3437
                        internal override Type Type
 
3438
                        {
 
3439
                                get
 
3440
                                {
 
3441
                                        return type;
 
3442
                                }
 
3443
                        }
 
3444
 
 
3445
                        internal override void EmitRunClassConstructor(CodeEmitter ilgen)
 
3446
                        {
 
3447
                                if (clinitMethod != null)
 
3448
                                {
 
3449
                                        ilgen.Emit(OpCodes.Call, clinitMethod);
 
3450
                                }
 
3451
                        }
 
3452
 
 
3453
                        internal override DynamicImpl Finish()
 
3454
                        {
 
3455
                                return this;
 
3456
                        }
 
3457
 
 
3458
                        internal override MethodBase LinkMethod(MethodWrapper mw)
 
3459
                        {
 
3460
                                // we should never be called, because all methods on a finished type are already linked
 
3461
                                Debug.Assert(false);
 
3462
                                return mw.GetMethod();
 
3463
                        }
 
3464
 
 
3465
                        internal override FieldInfo LinkField(FieldWrapper fw)
 
3466
                        {
 
3467
                                // we should never be called, because all fields on a finished type are already linked
 
3468
                                Debug.Assert(false);
 
3469
                                return fw.GetField();
 
3470
                        }
 
3471
 
 
3472
                        internal override string GetGenericSignature()
 
3473
                        {
 
3474
                                return Metadata.GetGenericSignature(metadata);
 
3475
                        }
 
3476
 
 
3477
                        internal override string[] GetEnclosingMethod()
 
3478
                        {
 
3479
                                return Metadata.GetEnclosingMethod(metadata);
 
3480
                        }
 
3481
 
 
3482
                        internal override string GetGenericMethodSignature(int index)
 
3483
                        {
 
3484
                                return Metadata.GetGenericMethodSignature(metadata, index);
 
3485
                        }
 
3486
 
 
3487
                        internal override string GetGenericFieldSignature(int index)
 
3488
                        {
 
3489
                                return Metadata.GetGenericFieldSignature(metadata, index);
 
3490
                        }
 
3491
 
 
3492
                        internal override object[] GetDeclaredAnnotations()
 
3493
                        {
 
3494
                                return Metadata.GetAnnotations(metadata);
 
3495
                        }
 
3496
 
 
3497
                        internal override object GetMethodDefaultValue(int index)
 
3498
                        {
 
3499
                                return Metadata.GetMethodDefaultValue(metadata, index);
 
3500
                        }
 
3501
 
 
3502
                        internal override object[] GetMethodAnnotations(int index)
 
3503
                        {
 
3504
                                return Metadata.GetMethodAnnotations(metadata, index);
 
3505
                        }
 
3506
 
 
3507
                        internal override object[][] GetParameterAnnotations(int index)
 
3508
                        {
 
3509
                                return Metadata.GetMethodParameterAnnotations(metadata, index);
 
3510
                        }
 
3511
 
 
3512
                        internal override object[] GetFieldAnnotations(int index)
 
3513
                        {
 
3514
                                return Metadata.GetFieldAnnotations(metadata, index);
 
3515
                        }
 
3516
 
 
3517
                        internal override MethodInfo GetFinalizeMethod()
 
3518
                        {
 
3519
                                return finalizeMethod;
 
3520
                        }
 
3521
                }
 
3522
 
 
3523
                internal sealed class FinishContext
 
3524
                {
 
3525
                        private readonly ClassFile classFile;
 
3526
                        private readonly DynamicOrAotTypeWrapper wrapper;
 
3527
                        private readonly TypeBuilder typeBuilder;
 
3528
                        private List<TypeBuilder> nestedTypeBuilders;
 
3529
                        private MethodInfo callerIDMethod;
 
3530
                        private List<Item> items;
 
3531
                        private Dictionary<FieldWrapper, MethodBuilder> arfuMap;
 
3532
 
 
3533
                        private struct Item
 
3534
                        {
 
3535
                                internal int key;
 
3536
                                internal object value;
 
3537
                        }
 
3538
 
 
3539
                        internal FinishContext(ClassFile classFile, DynamicOrAotTypeWrapper wrapper, TypeBuilder typeBuilder)
 
3540
                        {
 
3541
                                this.classFile = classFile;
 
3542
                                this.wrapper = wrapper;
 
3543
                                this.typeBuilder = typeBuilder;
 
3544
                        }
 
3545
 
 
3546
                        internal T GetValue<T>(int key)
 
3547
                                where T : class, new()
 
3548
                        {
 
3549
                                if (items == null)
 
3550
                                {
 
3551
                                        items = new List<Item>();
 
3552
                                }
 
3553
                                for (int i = 0; i < items.Count; i++)
 
3554
                                {
 
3555
                                        T value;
 
3556
                                        if (items[i].key == key && (value = items[i].value as T) != null)
 
3557
                                        {
 
3558
                                                return value;
 
3559
                                        }
 
3560
                                }
 
3561
                                Item item;
 
3562
                                item.key = key;
 
3563
                                T val = new T();
 
3564
                                item.value = val;
 
3565
                                items.Add(item);
 
3566
                                return val;
 
3567
                        }
 
3568
 
 
3569
                        internal void EmitCallerID(CodeEmitter ilgen)
 
3570
                        {
 
3571
                                if (callerIDMethod == null)
 
3572
                                {
 
3573
                                        CreateGetCallerID();
 
3574
                                }
 
3575
                                ilgen.Emit(OpCodes.Call, callerIDMethod);
 
3576
                        }
 
3577
 
 
3578
                        private void CreateGetCallerID()
 
3579
                        {
 
3580
                                TypeWrapper tw = CoreClasses.ikvm.@internal.CallerID.Wrapper;
 
3581
                                FieldBuilder callerIDField = typeBuilder.DefineField("__<callerID>", tw.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.SpecialName);
 
3582
                                MethodBuilder mb = typeBuilder.DefineMethod("__<GetCallerID>", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName, tw.TypeAsSignatureType, Type.EmptyTypes);
 
3583
                                callerIDMethod = mb;
 
3584
                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
3585
                                ilgen.Emit(OpCodes.Ldsfld, callerIDField);
 
3586
                                CodeEmitterLabel done = ilgen.DefineLabel();
 
3587
                                ilgen.EmitBrtrue(done);
 
3588
                                EmitCallerIDInitialization(ilgen, callerIDField);
 
3589
                                ilgen.MarkLabel(done);
 
3590
                                ilgen.Emit(OpCodes.Ldsfld, callerIDField);
 
3591
                                ilgen.Emit(OpCodes.Ret);
 
3592
                                ilgen.DoEmit();
 
3593
                        }
 
3594
 
 
3595
                        private void RegisterNestedTypeBuilder(TypeBuilder tb)
 
3596
                        {
 
3597
                                if (nestedTypeBuilders == null)
 
3598
                                {
 
3599
                                        nestedTypeBuilders = new List<TypeBuilder>();
 
3600
                                }
 
3601
                                nestedTypeBuilders.Add(tb);
 
3602
                        }
 
3603
 
 
3604
                        internal Type FinishImpl()
 
3605
                        {
 
3606
                                MethodWrapper[] methods = wrapper.GetMethods();
 
3607
                                FieldWrapper[] fields = wrapper.GetFields();
 
3608
#if STATIC_COMPILER
 
3609
                                wrapper.FinishGhost(typeBuilder, methods);
 
3610
#endif // STATIC_COMPILER
 
3611
 
 
3612
                                if (!classFile.IsInterface)
 
3613
                                {
 
3614
                                        // set the base type (this needs to be done before we emit any methods, because in the static compiler
 
3615
                                        // GetBaseTypeForDefineType() has the side effect of inserting the __WorkaroundBaseClass__ when necessary)
 
3616
                                        typeBuilder.SetParent(wrapper.GetBaseTypeForDefineType());
 
3617
                                }
 
3618
 
 
3619
                                // if we're not abstract make sure we don't inherit any abstract methods
 
3620
                                if (!wrapper.IsAbstract)
 
3621
                                {
 
3622
                                        TypeWrapper parent = wrapper.BaseTypeWrapper;
 
3623
                                        // if parent is not abstract, the .NET implementation will never have abstract methods (only
 
3624
                                        // stubs that throw AbstractMethodError)
 
3625
                                        // NOTE interfaces are supposed to be abstract, but the VM doesn't enforce this, so
 
3626
                                        // we have to check for a null parent (interfaces have no parent).
 
3627
                                        while (parent != null && parent.IsAbstract)
 
3628
                                        {
 
3629
                                                foreach (MethodWrapper mw in parent.GetMethods())
 
3630
                                                {
 
3631
                                                        MethodInfo mi = mw.GetMethod() as MethodInfo;
 
3632
                                                        if (mi != null && mi.IsAbstract && !mi.DeclaringType.IsInterface)
 
3633
                                                        {
 
3634
                                                                bool needStub = false;
 
3635
                                                                bool needRename = false;
 
3636
                                                                if (mw.IsPublic || mw.IsProtected)
 
3637
                                                                {
 
3638
                                                                        MethodWrapper fmw = wrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
 
3639
                                                                        while (fmw != mw && (fmw.IsStatic || fmw.IsPrivate))
 
3640
                                                                        {
 
3641
                                                                                needRename = true;
 
3642
                                                                                fmw = fmw.DeclaringType.BaseTypeWrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
 
3643
                                                                        }
 
3644
                                                                        if (fmw == mw && fmw.DeclaringType != wrapper)
 
3645
                                                                        {
 
3646
                                                                                needStub = true;
 
3647
                                                                        }
 
3648
                                                                }
 
3649
                                                                else
 
3650
                                                                {
 
3651
                                                                        MethodWrapper fmw = wrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
 
3652
                                                                        while (fmw != mw && (fmw.IsStatic || fmw.IsPrivate || !(mw.DeclaringType.IsPackageAccessibleFrom(fmw.DeclaringType) || (mw.IsInternal && mw.DeclaringType.InternalsVisibleTo(fmw.DeclaringType)))))
 
3653
                                                                        {
 
3654
                                                                                needRename = true;
 
3655
                                                                                fmw = fmw.DeclaringType.BaseTypeWrapper.GetMethodWrapper(mw.Name, mw.Signature, true);
 
3656
                                                                        }
 
3657
                                                                        if (fmw == mw && fmw.DeclaringType != wrapper)
 
3658
                                                                        {
 
3659
                                                                                needStub = true;
 
3660
                                                                        }
 
3661
                                                                }
 
3662
                                                                if (needStub)
 
3663
                                                                {
 
3664
                                                                        // NOTE in Sun's JRE 1.4.1 this method cannot be overridden by subclasses,
 
3665
                                                                        // but I think this is a bug, so we'll support it anyway.
 
3666
                                                                        string name = mi.Name;
 
3667
                                                                        MethodAttributes attr = mi.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.NewSlot);
 
3668
                                                                        if (needRename)
 
3669
                                                                        {
 
3670
                                                                                name = "__<>" + name + "/" + mi.DeclaringType.FullName;
 
3671
                                                                                attr = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot;
 
3672
                                                                        }
 
3673
                                                                        MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, attr);
 
3674
                                                                        if (needRename)
 
3675
                                                                        {
 
3676
                                                                                typeBuilder.DefineMethodOverride(mb, mi);
 
3677
                                                                        }
 
3678
                                                                        AttributeHelper.HideFromJava(mb);
 
3679
                                                                        CodeEmitter ilgen = CodeEmitter.Create(mb);
 
3680
                                                                        ilgen.EmitThrow("java.lang.AbstractMethodError", mw.DeclaringType.Name + "." + mw.Name + mw.Signature);
 
3681
                                                                        ilgen.DoEmit();
 
3682
                                                                }
 
3683
                                                        }
 
3684
                                                }
 
3685
                                                parent = parent.BaseTypeWrapper;
 
3686
                                        }
 
3687
                                }
 
3688
                                Dictionary<MethodKey, MethodInfo> invokespecialstubcache = new Dictionary<MethodKey, MethodInfo>();
 
3689
                                bool basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer;
 
3690
                                int clinitIndex = -1;
 
3691
                                bool hasConstructor = false;
 
3692
                                for (int i = 0; i < classFile.Methods.Length; i++)
 
3693
                                {
 
3694
                                        ClassFile.Method m = classFile.Methods[i];
 
3695
                                        MethodBuilder mb = (MethodBuilder)methods[i].GetMethod();
 
3696
                                        if (mb == null)
 
3697
                                        {
 
3698
                                                // method doesn't really exist (e.g. delegate constructor or <clinit> that is optimized away)
 
3699
                                                if (m.IsConstructor)
 
3700
                                                {
 
3701
                                                        hasConstructor = true;
 
3702
                                                }
 
3703
                                        }
 
3704
                                        else if (m.IsClassInitializer)
 
3705
                                        {
 
3706
                                                // we handle the <clinit> after we've done the other methods,
 
3707
                                                // to make it easier to inject code needed by the other methods
 
3708
                                                clinitIndex = i;
 
3709
                                                continue;
 
3710
                                        }
 
3711
                                        else if (m.IsConstructor)
 
3712
                                        {
 
3713
                                                hasConstructor = true;
 
3714
                                                CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
3715
                                                CompileConstructorBody(this, ilGenerator, i, invokespecialstubcache);
 
3716
                                        }
 
3717
                                        else
 
3718
                                        {
 
3719
                                                if (m.IsAbstract)
 
3720
                                                {
 
3721
                                                        bool stub = false;
 
3722
                                                        if (!classFile.IsAbstract)
 
3723
                                                        {
 
3724
                                                                // NOTE in the JVM it is apparently legal for a non-abstract class to have abstract methods, but
 
3725
                                                                // the CLR doens't allow this, so we have to emit a method that throws an AbstractMethodError
 
3726
                                                                stub = true;
 
3727
                                                        }
 
3728
                                                        else if (classFile.IsPublic && !classFile.IsFinal && !(m.IsPublic || m.IsProtected))
 
3729
                                                        {
 
3730
                                                                // We have an abstract package accessible method in our public class. To allow a class in another
 
3731
                                                                // assembly to subclass this class, we must fake the abstractness of this method.
 
3732
                                                                stub = true;
 
3733
                                                        }
 
3734
                                                        if (stub)
 
3735
                                                        {
 
3736
                                                                CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
3737
                                                                TraceHelper.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
 
3738
                                                                ilGenerator.EmitThrow("java.lang.AbstractMethodError", classFile.Name + "." + m.Name + m.Signature);
 
3739
                                                                ilGenerator.DoEmit();
 
3740
                                                        }
 
3741
                                                }
 
3742
                                                else if (m.IsNative)
 
3743
                                                {
 
3744
                                                        if ((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
 
3745
                                                        {
 
3746
                                                                continue;
 
3747
                                                        }
 
3748
                                                        if (wrapper.IsDelegate)
 
3749
                                                        {
 
3750
                                                                mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.Runtime);
 
3751
                                                                continue;
 
3752
                                                        }
 
3753
                                                        Profiler.Enter("JavaTypeImpl.Finish.Native");
 
3754
                                                        try
 
3755
                                                        {
 
3756
                                                                CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
3757
                                                                TraceHelper.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
 
3758
#if STATIC_COMPILER
 
3759
                                                                // do we have an implementation in map.xml?
 
3760
                                                                if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m))
 
3761
                                                                {
 
3762
                                                                        ilGenerator.DoEmit();
 
3763
                                                                        continue;
 
3764
                                                                }
 
3765
#endif
 
3766
                                                                // see if there exists a "managed JNI" class for this type
 
3767
                                                                Type nativeCodeType = null;
 
3768
#if STATIC_COMPILER
 
3769
                                                                nativeCodeType = StaticCompiler.GetType(wrapper.GetClassLoader(), "IKVM.NativeCode." + classFile.Name.Replace('$', '+'));
 
3770
                                                                if (nativeCodeType == null)
 
3771
                                                                {
 
3772
                                                                        // simple JNI like class name mangling
 
3773
                                                                        nativeCodeType = StaticCompiler.GetType(wrapper.GetClassLoader(), "Java_" + classFile.Name.Replace('.', '_'));
 
3774
                                                                }
 
3775
#endif
 
3776
                                                                MethodInfo nativeMethod = null;
 
3777
                                                                TypeWrapper[] args = methods[i].GetParameters();
 
3778
                                                                if (nativeCodeType != null)
 
3779
                                                                {
 
3780
                                                                        TypeWrapper[] nargs = args;
 
3781
                                                                        if (!m.IsStatic)
 
3782
                                                                        {
 
3783
                                                                                nargs = new TypeWrapper[args.Length + 1];
 
3784
                                                                                args.CopyTo(nargs, 1);
 
3785
                                                                                nargs[0] = this.wrapper;
 
3786
                                                                        }
 
3787
                                                                        MethodInfo[] nativeCodeTypeMethods = nativeCodeType.GetMethods(BindingFlags.Static | BindingFlags.Public);
 
3788
                                                                        foreach (MethodInfo method in nativeCodeTypeMethods)
 
3789
                                                                        {
 
3790
                                                                                ParameterInfo[] param = method.GetParameters();
 
3791
                                                                                TypeWrapper[] match = new TypeWrapper[param.Length];
 
3792
                                                                                for (int j = 0; j < param.Length; j++)
 
3793
                                                                                {
 
3794
                                                                                        match[j] = ClassLoaderWrapper.GetWrapperFromType(param[j].ParameterType);
 
3795
                                                                                }
 
3796
                                                                                if (m.Name == method.Name && IsCompatibleArgList(nargs, match))
 
3797
                                                                                {
 
3798
                                                                                        // TODO instead of taking the first matching method, we should find the best one
 
3799
                                                                                        nativeMethod = method;
 
3800
                                                                                        break;
 
3801
                                                                                }
 
3802
                                                                        }
 
3803
                                                                }
 
3804
                                                                if (nativeMethod != null)
 
3805
                                                                {
 
3806
                                                                        int add = 0;
 
3807
                                                                        if (!m.IsStatic)
 
3808
                                                                        {
 
3809
                                                                                ilGenerator.Emit(OpCodes.Ldarg_0);
 
3810
                                                                                add = 1;
 
3811
                                                                        }
 
3812
                                                                        for (int j = 0; j < args.Length; j++)
 
3813
                                                                        {
 
3814
                                                                                ilGenerator.EmitLdarg(j + add);
 
3815
                                                                        }
 
3816
                                                                        ilGenerator.Emit(OpCodes.Call, nativeMethod);
 
3817
                                                                        TypeWrapper retTypeWrapper = methods[i].ReturnType;
 
3818
                                                                        if (!retTypeWrapper.TypeAsTBD.Equals(nativeMethod.ReturnType) && !retTypeWrapper.IsGhost)
 
3819
                                                                        {
 
3820
                                                                                ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsTBD);
 
3821
                                                                        }
 
3822
                                                                        ilGenerator.Emit(OpCodes.Ret);
 
3823
                                                                }
 
3824
                                                                else
 
3825
                                                                {
 
3826
                                                                        if (wrapper.classLoader.NoJNI)
 
3827
                                                                        {
 
3828
                                                                                // since NoJniStubs can only be set when we're statically compiling, it is safe to use the "compiler" trace switch
 
3829
                                                                                Tracer.Warning(Tracer.Compiler, "Native method not implemented: {0}.{1}.{2}", classFile.Name, m.Name, m.Signature);
 
3830
                                                                                ilGenerator.EmitThrow("java.lang.UnsatisfiedLinkError", "Native method not implemented (compiled with -nojni): " + classFile.Name + "." + m.Name + m.Signature);
 
3831
                                                                        }
 
3832
#if STATIC_COMPILER
 
3833
                                                                        else if (StaticCompiler.runtimeJniAssembly == null)
 
3834
                                                                        {
 
3835
                                                                                Console.Error.WriteLine("Error: Native method not implemented: {0}.{1}{2}", classFile.Name, m.Name, m.Signature);
 
3836
                                                                                StaticCompiler.errorCount++;
 
3837
                                                                        }
 
3838
#endif
 
3839
                                                                        else
 
3840
                                                                        {
 
3841
                                                                                if (JVM.IsSaveDebugImage)
 
3842
                                                                                {
 
3843
#if !STATIC_COMPILER
 
3844
                                                                                        JniProxyBuilder.Generate(this, ilGenerator, wrapper, methods[i], typeBuilder, classFile, m, args);
 
3845
#endif // !STATIC_COMPILER
 
3846
                                                                                }
 
3847
                                                                                else
 
3848
                                                                                {
 
3849
                                                                                        JniBuilder.Generate(this, ilGenerator, wrapper, methods[i], typeBuilder, classFile, m, args, false);
 
3850
                                                                                }
 
3851
                                                                        }
 
3852
                                                                }
 
3853
                                                                ilGenerator.DoEmit();
 
3854
                                                        }
 
3855
                                                        finally
 
3856
                                                        {
 
3857
                                                                Profiler.Leave("JavaTypeImpl.Finish.Native");
 
3858
                                                        }
 
3859
                                                }
 
3860
                                                else
 
3861
                                                {
 
3862
                                                        CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
3863
                                                        TraceHelper.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
 
3864
#if STATIC_COMPILER
 
3865
                                                        // do we have an implementation in map.xml?
 
3866
                                                        if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m))
 
3867
                                                        {
 
3868
                                                                ilGenerator.DoEmit();
 
3869
                                                                continue;
 
3870
                                                        }
 
3871
#endif // STATIC_COMPILER
 
3872
                                                        bool nonleaf = false;
 
3873
                                                        Compiler.Compile(this, wrapper, methods[i], classFile, m, ilGenerator, ref nonleaf, invokespecialstubcache);
 
3874
                                                        ilGenerator.CheckLabels();
 
3875
                                                        ilGenerator.DoEmit();
 
3876
                                                        if (nonleaf)
 
3877
                                                        {
 
3878
                                                                mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.NoInlining);
 
3879
                                                        }
 
3880
#if STATIC_COMPILER
 
3881
                                                        ilGenerator.EmitLineNumberTable((MethodBuilder)methods[i].GetMethod());
 
3882
#else // STATIC_COMPILER
 
3883
                                                        byte[] linenumbers = ilGenerator.GetLineNumberTable();
 
3884
                                                        if (linenumbers != null)
 
3885
                                                        {
 
3886
                                                                if (wrapper.lineNumberTables == null)
 
3887
                                                                {
 
3888
                                                                        wrapper.lineNumberTables = new byte[methods.Length][];
 
3889
                                                                }
 
3890
                                                                wrapper.lineNumberTables[i] = linenumbers;
 
3891
                                                        }
 
3892
#endif // STATIC_COMPILER
 
3893
                                                }
 
3894
                                        }
 
3895
                                }
 
3896
 
 
3897
                                if (clinitIndex != -1 || (basehasclinit && !classFile.IsInterface) || classFile.HasInitializedFields)
 
3898
                                {
 
3899
                                        MethodBuilder cb;
 
3900
                                        if (clinitIndex != -1)
 
3901
                                        {
 
3902
                                                cb = (MethodBuilder)methods[clinitIndex].GetMethod();
 
3903
                                        }
 
3904
                                        else
 
3905
                                        {
 
3906
                                                cb = ReflectUtil.DefineTypeInitializer(typeBuilder);
 
3907
                                                AttributeHelper.HideFromJava(cb);
 
3908
                                        }
 
3909
                                        CodeEmitter ilGenerator = CodeEmitter.Create(cb);
 
3910
                                        // before we call the base class initializer, we need to set the non-final static ConstantValue fields
 
3911
                                        EmitConstantValueInitialization(fields, ilGenerator);
 
3912
                                        if (basehasclinit)
 
3913
                                        {
 
3914
                                                wrapper.BaseTypeWrapper.EmitRunClassConstructor(ilGenerator);
 
3915
                                        }
 
3916
                                        if (clinitIndex != -1)
 
3917
                                        {
 
3918
                                                CompileConstructorBody(this, ilGenerator, clinitIndex, invokespecialstubcache);
 
3919
                                        }
 
3920
                                        else
 
3921
                                        {
 
3922
                                                ilGenerator.Emit(OpCodes.Ret);
 
3923
                                                ilGenerator.DoEmit();
 
3924
                                        }
 
3925
                                        ilGenerator.CheckLabels();
 
3926
                                }
 
3927
 
 
3928
                                // add all interfaces that we implement (including the magic ones) and handle ghost conversions
 
3929
                                ImplementInterfaces(wrapper.Interfaces, new List<TypeWrapper>());
 
3930
 
 
3931
                                // NOTE non-final fields aren't allowed in interfaces so we don't have to initialize constant fields
 
3932
                                if (!classFile.IsInterface)
 
3933
                                {
 
3934
                                        // if a class has no constructor, we generate one otherwise Ref.Emit will create a default ctor
 
3935
                                        // and that has several problems:
 
3936
                                        // - base type may not have an accessible default constructor
 
3937
                                        // - Ref.Emit uses BaseType.GetConstructors() which may trigger a TypeResolve event
 
3938
                                        // - we don't want the synthesized constructor to show up in Java
 
3939
                                        if (!hasConstructor)
 
3940
                                        {
 
3941
                                                CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineConstructor(typeBuilder, MethodAttributes.PrivateScope, Type.EmptyTypes));
 
3942
                                                ilgen.Emit(OpCodes.Ldnull);
 
3943
                                                ilgen.Emit(OpCodes.Throw);
 
3944
                                                ilgen.DoEmit();
 
3945
                                        }
 
3946
 
 
3947
                                        // here we loop thru all the interfaces to explicitly implement any methods that we inherit from
 
3948
                                        // base types that may have a different name from the name in the interface
 
3949
                                        // (e.g. interface that has an equals() method that should override System.Object.Equals())
 
3950
                                        // also deals with interface methods that aren't implemented (generate a stub that throws AbstractMethodError)
 
3951
                                        // and with methods that aren't public (generate a stub that throws IllegalAccessError)
 
3952
                                        Dictionary<TypeWrapper, TypeWrapper> doneSet = new Dictionary<TypeWrapper, TypeWrapper>();
 
3953
                                        TypeWrapper[] interfaces = wrapper.Interfaces;
 
3954
                                        for (int i = 0; i < interfaces.Length; i++)
 
3955
                                        {
 
3956
                                                ImplementInterfaceMethodStubs(doneSet, interfaces[i], false);
 
3957
                                        }
 
3958
                                        // if any of our base classes has an incomplete interface implementation we need to look through all
 
3959
                                        // the base class interfaces to see if we've got an implementation now
 
3960
                                        TypeWrapper baseTypeWrapper = wrapper.BaseTypeWrapper;
 
3961
                                        while (baseTypeWrapper.HasIncompleteInterfaceImplementation)
 
3962
                                        {
 
3963
                                                for (int i = 0; i < baseTypeWrapper.Interfaces.Length; i++)
 
3964
                                                {
 
3965
                                                        ImplementInterfaceMethodStubs(doneSet, baseTypeWrapper.Interfaces[i], true);
 
3966
                                                }
 
3967
                                                baseTypeWrapper = baseTypeWrapper.BaseTypeWrapper;
 
3968
                                        }
 
3969
                                        if (!wrapper.IsAbstract && wrapper.HasUnsupportedAbstractMethods)
 
3970
                                        {
 
3971
                                                AddUnsupportedAbstractMethods();
 
3972
                                        }
 
3973
                                        if (!wrapper.GetClassLoader().NoAutomagicSerialization)
 
3974
                                        {
 
3975
                                                wrapper.automagicSerializationCtor = Serialization.AddAutomagicSerialization(wrapper, typeBuilder);
 
3976
                                        }
 
3977
                                }
 
3978
 
 
3979
#if STATIC_COMPILER
 
3980
                                // If we're an interface that has public/protected fields, we create an inner class
 
3981
                                // to expose these fields to C# (which stubbornly refuses to see fields in interfaces).
 
3982
                                TypeBuilder tbFields = null;
 
3983
                                if (classFile.IsInterface && classFile.IsPublic && !wrapper.IsGhost && classFile.Fields.Length > 0)
 
3984
                                {
 
3985
                                        CompilerClassLoader ccl = wrapper.classLoader;
 
3986
                                        string name = "__Fields";
 
3987
                                        while (!ccl.ReserveName(classFile.Name + "$" + name))
 
3988
                                        {
 
3989
                                                name += "_";
 
3990
                                        }
 
3991
                                        tbFields = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.Abstract);
 
3992
                                        AttributeHelper.HideFromJava(tbFields);
 
3993
                                        CodeEmitter ilgenClinit = null;
 
3994
                                        for (int i = 0; i < classFile.Fields.Length; i++)
 
3995
                                        {
 
3996
                                                ClassFile.Field f = classFile.Fields[i];
 
3997
                                                if (f.ConstantValue != null)
 
3998
                                                {
 
3999
                                                        FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
 
4000
                                                        FieldBuilder fb = tbFields.DefineField(f.Name, fields[i].FieldTypeWrapper.TypeAsSignatureType, attribs);
 
4001
                                                        fb.SetConstant(f.ConstantValue);
 
4002
                                                }
 
4003
                                                else
 
4004
                                                {
 
4005
                                                        FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly;
 
4006
                                                        FieldBuilder fb = tbFields.DefineField(f.Name, ToPublicSignatureType(fields[i].FieldTypeWrapper), attribs);
 
4007
                                                        if (ilgenClinit == null)
 
4008
                                                        {
 
4009
                                                                ilgenClinit = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tbFields));
 
4010
                                                        }
 
4011
                                                        wrapper.GetFieldWrapper(f.Name, f.Signature).EmitGet(ilgenClinit);
 
4012
                                                        ilgenClinit.Emit(OpCodes.Stsfld, fb);
 
4013
                                                }
 
4014
                                        }
 
4015
                                        if (ilgenClinit != null)
 
4016
                                        {
 
4017
                                                ilgenClinit.Emit(OpCodes.Ret);
 
4018
                                                ilgenClinit.DoEmit();
 
4019
                                        }
 
4020
                                }
 
4021
 
 
4022
                                // See if there is any additional metadata
 
4023
                                wrapper.EmitMapXmlMetadata(typeBuilder, classFile, fields, methods);
 
4024
 
 
4025
                                // if we inherit public members from non-public base classes or have public members with non-public types in their signature, we need access stubs
 
4026
                                if (wrapper.IsPublic)
 
4027
                                {
 
4028
                                        AddAccessStubs();
 
4029
                                }
 
4030
#endif // STATIC_COMPILER
 
4031
 
 
4032
                                for (int i = 0; i < classFile.Methods.Length; i++)
 
4033
                                {
 
4034
                                        ClassFile.Method m = classFile.Methods[i];
 
4035
                                        MethodBuilder mb = (MethodBuilder)methods[i].GetMethod();
 
4036
                                        if (mb == null)
 
4037
                                        {
 
4038
                                                continue;
 
4039
                                        }
 
4040
                                        ParameterBuilder returnParameter = null;
 
4041
                                        ParameterBuilder[] parameterBuilders = null;
 
4042
                                        string[] parameterNames = null;
 
4043
                                        if (wrapper.GetClassLoader().EmitDebugInfo
 
4044
#if STATIC_COMPILER
 
4045
 || (classFile.IsPublic && (m.IsPublic || m.IsProtected))
 
4046
#endif
 
4047
)
 
4048
                                        {
 
4049
                                                parameterNames = new string[methods[i].GetParameters().Length];
 
4050
                                                GetParameterNamesFromLVT(m, parameterNames);
 
4051
                                                GetParameterNamesFromSig(m.Signature, parameterNames);
 
4052
#if STATIC_COMPILER
 
4053
                                                wrapper.GetParameterNamesFromXml(m.Name, m.Signature, parameterNames);
 
4054
#endif
 
4055
                                                parameterBuilders = GetParameterBuilders(mb, parameterNames.Length, parameterNames);
 
4056
                                        }
 
4057
#if STATIC_COMPILER
 
4058
                                        if ((m.Modifiers & Modifiers.VarArgs) != 0 && !methods[i].HasCallerID)
 
4059
                                        {
 
4060
                                                if (parameterBuilders == null)
 
4061
                                                {
 
4062
                                                        parameterBuilders = GetParameterBuilders(mb, methods[i].GetParameters().Length, null);
 
4063
                                                }
 
4064
                                                if (parameterBuilders.Length > 0)
 
4065
                                                {
 
4066
                                                        AttributeHelper.SetParamArrayAttribute(parameterBuilders[parameterBuilders.Length - 1]);
 
4067
                                                }
 
4068
                                        }
 
4069
                                        wrapper.AddXmlMapParameterAttributes(mb, classFile.Name, m.Name, m.Signature, ref parameterBuilders);
 
4070
#endif
 
4071
                                        if (m.Annotations != null)
 
4072
                                        {
 
4073
                                                foreach (object[] def in m.Annotations)
 
4074
                                                {
 
4075
                                                        Annotation annotation = Annotation.Load(wrapper.GetClassLoader(), def);
 
4076
                                                        if (annotation != null)
 
4077
                                                        {
 
4078
                                                                annotation.Apply(wrapper.GetClassLoader(), mb, def);
 
4079
                                                                annotation.ApplyReturnValue(wrapper.GetClassLoader(), mb, ref returnParameter, def);
 
4080
                                                        }
 
4081
                                                }
 
4082
                                        }
 
4083
                                        if (m.ParameterAnnotations != null)
 
4084
                                        {
 
4085
                                                if (parameterBuilders == null)
 
4086
                                                {
 
4087
                                                        parameterBuilders = GetParameterBuilders(mb, methods[i].GetParameters().Length, null);
 
4088
                                                }
 
4089
                                                object[][] defs = m.ParameterAnnotations;
 
4090
                                                for (int j = 0; j < defs.Length; j++)
 
4091
                                                {
 
4092
                                                        foreach (object[] def in defs[j])
 
4093
                                                        {
 
4094
                                                                Annotation annotation = Annotation.Load(wrapper.GetClassLoader(), def);
 
4095
                                                                if (annotation != null)
 
4096
                                                                {
 
4097
                                                                        annotation.Apply(wrapper.GetClassLoader(), parameterBuilders[j], def);
 
4098
                                                                }
 
4099
                                                        }
 
4100
                                                }
 
4101
                                        }
 
4102
#if STATIC_COMPILER
 
4103
                                        if (methods[i].HasCallerID)
 
4104
                                        {
 
4105
                                                AttributeHelper.SetEditorBrowsableNever(mb);
 
4106
                                                EmitCallerIDStub(methods[i], parameterNames);
 
4107
                                        }
 
4108
                                        if (m.DllExportName != null && wrapper.classLoader.TryEnableUnmanagedExports())
 
4109
                                        {
 
4110
                                                mb.__AddUnmanagedExport(m.DllExportName, m.DllExportOrdinal);
 
4111
                                        }
 
4112
#endif // STATIC_COMPILER
 
4113
                                }
 
4114
 
 
4115
                                for (int i = 0; i < classFile.Fields.Length; i++)
 
4116
                                {
 
4117
                                        if (classFile.Fields[i].Annotations != null)
 
4118
                                        {
 
4119
                                                foreach (object[] def in classFile.Fields[i].Annotations)
 
4120
                                                {
 
4121
                                                        Annotation annotation = Annotation.Load(wrapper.GetClassLoader(), def);
 
4122
                                                        if (annotation != null)
 
4123
                                                        {
 
4124
                                                                {
 
4125
                                                                        DynamicPropertyFieldWrapper prop = fields[i] as DynamicPropertyFieldWrapper;
 
4126
                                                                        if (prop != null)
 
4127
                                                                        {
 
4128
                                                                                annotation.Apply(wrapper.GetClassLoader(), prop.GetPropertyBuilder(), def);
 
4129
                                                                        }
 
4130
                                                                        else
 
4131
                                                                        {
 
4132
                                                                                annotation.Apply(wrapper.GetClassLoader(), (FieldBuilder)fields[i].GetField(), def);
 
4133
                                                                        }
 
4134
                                                                }
 
4135
                                                        }
 
4136
                                                }
 
4137
                                        }
 
4138
                                }
 
4139
 
 
4140
                                if (classFile.Annotations != null)
 
4141
                                {
 
4142
                                        foreach (object[] def in classFile.Annotations)
 
4143
                                        {
 
4144
                                                Annotation annotation = Annotation.Load(wrapper.GetClassLoader(), def);
 
4145
                                                if (annotation != null)
 
4146
                                                {
 
4147
                                                        annotation.Apply(wrapper.GetClassLoader(), typeBuilder, def);
 
4148
                                                }
 
4149
                                        }
 
4150
                                }
 
4151
 
 
4152
                                Type type;
 
4153
                                Profiler.Enter("TypeBuilder.CreateType");
 
4154
                                try
 
4155
                                {
 
4156
                                        type = typeBuilder.CreateType();
 
4157
                                        if (nestedTypeBuilders != null)
 
4158
                                        {
 
4159
                                                ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater").Finish();
 
4160
                                                ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal").Finish();
 
4161
                                                foreach (TypeBuilder tb in nestedTypeBuilders)
 
4162
                                                {
 
4163
                                                        tb.CreateType();
 
4164
                                                }
 
4165
                                        }
 
4166
#if STATIC_COMPILER
 
4167
                                        if (tbFields != null)
 
4168
                                        {
 
4169
                                                tbFields.CreateType();
 
4170
                                        }
 
4171
                                        if (classFile.IsInterface && !classFile.IsPublic)
 
4172
                                        {
 
4173
                                                ((DynamicClassLoader)wrapper.classLoader.GetTypeWrapperFactory()).DefineProxyHelper(type);
 
4174
                                        }
 
4175
#endif
 
4176
                                }
 
4177
                                finally
 
4178
                                {
 
4179
                                        Profiler.Leave("TypeBuilder.CreateType");
 
4180
                                }
 
4181
#if !STATIC_COMPILER
 
4182
                                // When we're statically compiling we don't need to set the wrapper here, because we've already done so for the typeBuilder earlier.
 
4183
                                wrapper.GetClassLoader().SetWrapperForType(type, wrapper);
 
4184
#endif
 
4185
#if STATIC_COMPILER
 
4186
                                wrapper.FinishGhostStep2();
 
4187
#endif
 
4188
                                BakedTypeCleanupHack.Process(wrapper);
 
4189
                                return type;
 
4190
                        }
 
4191
 
 
4192
#if STATIC_COMPILER
 
4193
                        private void AddAccessStubs()
 
4194
                        {
 
4195
                                /*
 
4196
                                 * There are two types of access stubs:
 
4197
                                 * 
 
4198
                                 * Type 1   These are required when a public class extends a non-public class.
 
4199
                                 *                      In that case we need access stubs for all public and protected members
 
4200
                                 *                      of the non-public base classes.
 
4201
                                 *
 
4202
                                 * Type 2       When a public class exposes a member that contains a non-public type in
 
4203
                                 *                      its signature, we need an access stub for that member (where we convert
 
4204
                                 *                      the non-public type in the signature to the first public base type).
 
4205
                                 *                      Additionally, when a public or protected final field is compiled
 
4206
                                 *                      without -strictfinalfieldsemantics, a the field will be wrapper with a
 
4207
                                 *                      read-only property.
 
4208
                                 *
 
4209
                                 * Note that type 1 access stubs may also need the type 2 signature type widening
 
4210
                                 * if the signature contains non-public types.
 
4211
                                 * 
 
4212
                                 * Type 1 access stubs are always required, because the JVM allow access to these
 
4213
                                 * members via the derived class while the CLR doesn't. Historically, we've exposed
 
4214
                                 * these access stubs in such a way that they are also consumable from other .NET
 
4215
                                 * languages (when feasible), so we'll continue to do that for back compat.
 
4216
                                 * 
 
4217
                                 * Type 2 access stubs are only required by the CLR when running on CLR v4 and the
 
4218
                                 * caller assembly is security transparent code (level 2). We also want the access
 
4219
                                 * stubs to allow other .NET languages (e.g. C#) to consume broken APIs that
 
4220
                                 * (accidentally) expose these members.
 
4221
                                 */
 
4222
                                AddType2FieldAccessStubs();
 
4223
                                AddType1FieldAccessStubs(wrapper);
 
4224
                                if (!wrapper.IsInterface)
 
4225
                                {
 
4226
                                        int id = 0;
 
4227
                                        AddType2MethodAccessStubs(ref id);
 
4228
                                        AddType1MethodAccessStubs(ref id);
 
4229
                                }
 
4230
                        }
 
4231
 
 
4232
                        private void AddType1FieldAccessStubs(TypeWrapper tw)
 
4233
                        {
 
4234
                                do
 
4235
                                {
 
4236
                                        if (!tw.IsPublic)
 
4237
                                        {
 
4238
                                                foreach (FieldWrapper fw in tw.GetFields())
 
4239
                                                {
 
4240
                                                        if ((fw.IsPublic || (fw.IsProtected && !wrapper.IsFinal))
 
4241
                                                                && wrapper.GetFieldWrapper(fw.Name, fw.Signature) == fw)
 
4242
                                                        {
 
4243
                                                                GenerateAccessStub(fw, true);
 
4244
                                                        }
 
4245
                                                }
 
4246
                                        }
 
4247
                                        foreach (TypeWrapper iface in tw.Interfaces)
 
4248
                                        {
 
4249
                                                AddType1FieldAccessStubs(iface);
 
4250
                                        }
 
4251
                                        tw = tw.BaseTypeWrapper;
 
4252
                                } while (tw != null && !tw.IsPublic);
 
4253
                        }
 
4254
 
 
4255
                        private void AddType2FieldAccessStubs()
 
4256
                        {
 
4257
                                foreach (FieldWrapper fw in wrapper.GetFields())
 
4258
                                {
 
4259
                                        if (wrapper.NeedsType2AccessStub(fw))
 
4260
                                        {
 
4261
                                                GenerateAccessStub(fw, false);
 
4262
                                        }
 
4263
                                }
 
4264
                        }
 
4265
 
 
4266
                        private void GenerateAccessStub(FieldWrapper fw, bool type1)
 
4267
                        {
 
4268
                                if (fw is ConstantFieldWrapper)
 
4269
                                {
 
4270
                                        // constants cannot have a type 2 access stub, because constant types are always public
 
4271
                                        Debug.Assert(type1);
 
4272
 
 
4273
                                        FieldAttributes attribs = fw.IsPublic ? FieldAttributes.Public : FieldAttributes.FamORAssem;
 
4274
                                        attribs |= FieldAttributes.Static | FieldAttributes.Literal;
 
4275
                                        // we attach the AccessStub custom modifier because the C# compiler prefers fields without custom modifiers
 
4276
                                        // so if this class defines a field with the same name, that will be preferred over this one by the C# compiler
 
4277
                                        FieldBuilder fb = typeBuilder.DefineField(fw.Name, fw.FieldTypeWrapper.TypeAsSignatureType, null, new Type[] { JVM.LoadType(typeof(IKVM.Attributes.AccessStub)) }, attribs);
 
4278
                                        AttributeHelper.HideFromReflection(fb);
 
4279
                                        fb.SetConstant(((ConstantFieldWrapper)fw).GetConstantValue());
 
4280
                                }
 
4281
                                else
 
4282
                                {
 
4283
                                        Type propType = ToPublicSignatureType(fw.FieldTypeWrapper);
 
4284
                                        Type[] modopt = wrapper.GetModOpt(fw.FieldTypeWrapper, true);
 
4285
                                        PropertyBuilder pb = typeBuilder.DefineProperty(fw.Name, PropertyAttributes.None, propType, null, modopt, Type.EmptyTypes, null, null);
 
4286
                                        if (type1)
 
4287
                                        {
 
4288
                                                AttributeHelper.HideFromReflection(pb);
 
4289
                                        }
 
4290
                                        else
 
4291
                                        {
 
4292
                                                AttributeHelper.SetModifiers(pb, fw.Modifiers, fw.IsInternal);
 
4293
                                        }
 
4294
                                        MethodAttributes attribs = fw.IsPublic ? MethodAttributes.Public : MethodAttributes.FamORAssem;
 
4295
                                        attribs |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 
4296
                                        if (fw.IsStatic)
 
4297
                                        {
 
4298
                                                attribs |= MethodAttributes.Static;
 
4299
                                        }
 
4300
                                        // we append the IKVM.Attributes.AccessStub type to the modopt array for use in the property accessor method signature
 
4301
                                        // to make sure they never conflict with any user defined methhods
 
4302
                                        Type[] modopt2 = modopt;
 
4303
                                        Array.Resize(ref modopt2, modopt2.Length + 1);
 
4304
                                        modopt2[modopt2.Length - 1] = JVM.LoadType(typeof(IKVM.Attributes.AccessStub));
 
4305
                                        MethodBuilder getter = typeBuilder.DefineMethod("get_" + fw.Name, attribs, CallingConventions.Standard, propType, null, modopt2, Type.EmptyTypes, null, null);
 
4306
                                        AttributeHelper.HideFromJava(getter);
 
4307
                                        pb.SetGetMethod(getter);
 
4308
                                        CodeEmitter ilgen = CodeEmitter.Create(getter);
 
4309
                                        if (!fw.IsStatic)
 
4310
                                        {
 
4311
                                                ilgen.Emit(OpCodes.Ldarg_0);
 
4312
                                        }
 
4313
                                        fw.EmitGet(ilgen);
 
4314
                                        ilgen.Emit(OpCodes.Ret);
 
4315
                                        ilgen.DoEmit();
 
4316
                                        if (!fw.IsFinal || (!fw.IsStatic && !type1))
 
4317
                                        {
 
4318
                                                if (fw.IsFinal)
 
4319
                                                {
 
4320
                                                        // we need to generate a (private) setter for final fields for reflection and serialization
 
4321
                                                        attribs &= ~MethodAttributes.MemberAccessMask;
 
4322
                                                        attribs |= MethodAttributes.Private;
 
4323
                                                }
 
4324
                                                MethodBuilder setter = typeBuilder.DefineMethod("set_" + fw.Name, attribs, CallingConventions.Standard, null, null, null, new Type[] { propType }, null, new Type[][] { modopt2 });
 
4325
                                                AttributeHelper.HideFromJava(setter);
 
4326
                                                pb.SetSetMethod(setter);
 
4327
                                                ilgen = CodeEmitter.Create(setter);
 
4328
                                                ilgen.Emit(OpCodes.Ldarg_0);
 
4329
                                                if (!fw.IsStatic)
 
4330
                                                {
 
4331
                                                        ilgen.Emit(OpCodes.Ldarg_1);
 
4332
                                                }
 
4333
                                                // we don't do a DynamicCast if fw.FieldTypeWrapper is unloadable, because for normal unloadable fields we don't enfore the type either
 
4334
                                                if (propType != fw.FieldTypeWrapper.TypeAsSignatureType)
 
4335
                                                {
 
4336
                                                        ilgen.Emit(OpCodes.Castclass, fw.FieldTypeWrapper.TypeAsSignatureType);
 
4337
                                                }
 
4338
                                                fw.EmitSet(ilgen);
 
4339
                                                ilgen.Emit(OpCodes.Ret);
 
4340
                                                ilgen.DoEmit();
 
4341
                                        }
 
4342
                                }
 
4343
                        }
 
4344
 
 
4345
                        private void AddType1MethodAccessStubs(ref int id)
 
4346
                        {
 
4347
                                for (TypeWrapper tw = wrapper.BaseTypeWrapper; tw != null && !tw.IsPublic; tw = tw.BaseTypeWrapper)
 
4348
                                {
 
4349
                                        foreach (MethodWrapper mw in tw.GetMethods())
 
4350
                                        {
 
4351
                                                if ((mw.IsPublic || (mw.IsProtected && !wrapper.IsFinal))
 
4352
                                                        && (!mw.IsAbstract || wrapper.IsAbstract)
 
4353
                                                        && mw.Name != StringConstants.INIT
 
4354
                                                        && wrapper.GetMethodWrapper(mw.Name, mw.Signature, true) == mw
 
4355
                                                        && ParametersAreAccessible(mw))
 
4356
                                                {
 
4357
                                                        GenerateAccessStub(id, mw, true, true);
 
4358
                                                        if (!mw.IsStatic && !mw.IsFinal && !mw.IsAbstract && !wrapper.IsFinal)
 
4359
                                                        {
 
4360
                                                                GenerateAccessStub(id, mw, false, true);
 
4361
                                                        }
 
4362
                                                        id++;
 
4363
                                                }
 
4364
                                        }
 
4365
                                }
 
4366
                        }
 
4367
 
 
4368
                        private void AddType2MethodAccessStubs(ref int id)
 
4369
                        {
 
4370
                                foreach (MethodWrapper mw in wrapper.GetMethods())
 
4371
                                {
 
4372
                                        if (mw.HasNonPublicTypeInSignature
 
4373
                                                && (mw.IsPublic || (mw.IsProtected && !wrapper.IsFinal))
 
4374
                                                && ParametersAreAccessible(mw))
 
4375
                                        {
 
4376
                                                GenerateAccessStub(id, mw, true, false);
 
4377
                                                if (!mw.IsStatic && !mw.IsFinal && !mw.IsAbstract && mw.Name != StringConstants.INIT && !wrapper.IsFinal)
 
4378
                                                {
 
4379
                                                        GenerateAccessStub(id, mw, false, false);
 
4380
                                                }
 
4381
                                                id++;
 
4382
                                        }
 
4383
                                }
 
4384
                        }
 
4385
 
 
4386
                        private void GenerateAccessStub(int id, MethodWrapper mw, bool virt, bool type1)
 
4387
                        {
 
4388
                                Debug.Assert(!mw.HasCallerID);
 
4389
                                MethodAttributes stubattribs = mw.IsPublic && virt ? MethodAttributes.Public : MethodAttributes.FamORAssem;
 
4390
                                stubattribs |= MethodAttributes.HideBySig;
 
4391
                                if (mw.IsStatic)
 
4392
                                {
 
4393
                                        stubattribs |= MethodAttributes.Static;
 
4394
                                }
 
4395
                                TypeWrapper[] parameters = mw.GetParameters();
 
4396
                                Type[] realParameterTypes = new Type[parameters.Length];
 
4397
                                Type[] parameterTypes = new Type[parameters.Length];
 
4398
                                Type[][] modopt = new Type[parameters.Length][];
 
4399
                                for (int i = 0; i < parameters.Length; i++)
 
4400
                                {
 
4401
                                        realParameterTypes[i] = parameters[i].TypeAsSignatureType;
 
4402
                                        parameterTypes[i] = ToPublicSignatureType(parameters[i]);
 
4403
                                        modopt[i] = wrapper.GetModOpt(parameters[i], true);
 
4404
                                }
 
4405
                                Type returnType = ToPublicSignatureType(mw.ReturnType);
 
4406
                                Type[] modoptReturnType = wrapper.GetModOpt(mw.ReturnType, true);
 
4407
                                Array.Resize(ref modoptReturnType, modoptReturnType.Length + 1);
 
4408
                                modoptReturnType[modoptReturnType.Length - 1] = JVM.LoadType(typeof(IKVM.Attributes.AccessStub));
 
4409
                                string name;
 
4410
                                if (mw.Name == StringConstants.INIT)
 
4411
                                {
 
4412
                                        name = ConstructorInfo.ConstructorName;
 
4413
                                        stubattribs |= MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
 
4414
                                }
 
4415
                                else
 
4416
                                {
 
4417
                                        name = virt
 
4418
                                                ? (mw.Modifiers & Modifiers.Bridge) == 0 ? mw.Name : NamePrefix.Bridge + mw.Name
 
4419
                                                : NamePrefix.NonVirtual + id;
 
4420
                                }
 
4421
                                MethodBuilder mb = typeBuilder.DefineMethod(name, stubattribs, CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt);
 
4422
                                if (virt && type1)
 
4423
                                {
 
4424
                                        AttributeHelper.HideFromReflection(mb);
 
4425
                                        AttributeHelper.SetNameSig(mb, NamePrefix.AccessStub + id + "|" + mw.Name, mw.Signature);
 
4426
                                }
 
4427
                                else
 
4428
                                {
 
4429
                                        AttributeHelper.HideFromJava(mb);
 
4430
                                        if (!type1)
 
4431
                                        {
 
4432
                                                AttributeHelper.SetNameSig(mb, mw.Name, mw.Signature);
 
4433
                                        }
 
4434
                                }
 
4435
                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
4436
                                int argpos = 0;
 
4437
                                if (!mw.IsStatic)
 
4438
                                {
 
4439
                                        ilgen.EmitLdarg(argpos++);
 
4440
                                }
 
4441
                                for (int i = 0; i < parameterTypes.Length; i++)
 
4442
                                {
 
4443
                                        ilgen.EmitLdarg(argpos++);
 
4444
                                        // we don't need to do a DynamicCast if for unloadables, because the method itself will already do that
 
4445
                                        if (parameterTypes[i] != realParameterTypes[i])
 
4446
                                        {
 
4447
                                                ilgen.Emit(OpCodes.Castclass, realParameterTypes[i]);
 
4448
                                        }
 
4449
                                }
 
4450
                                if (mw.IsStatic || !virt || mw.Name == StringConstants.INIT)
 
4451
                                {
 
4452
                                        mw.EmitCall(ilgen);
 
4453
                                }
 
4454
                                else
 
4455
                                {
 
4456
                                        mw.EmitCallvirt(ilgen);
 
4457
                                }
 
4458
                                ilgen.Emit(OpCodes.Ret);
 
4459
                                ilgen.DoEmit();
 
4460
                        }
 
4461
 
 
4462
                        private static Type ToPublicSignatureType(TypeWrapper tw)
 
4463
                        {
 
4464
                                return (tw.IsPublic ? tw : tw.GetPublicBaseTypeWrapper()).TypeAsSignatureType;
 
4465
                        }
 
4466
 
 
4467
                        private bool ParametersAreAccessible(MethodWrapper mw)
 
4468
                        {
 
4469
                                foreach (TypeWrapper tw in mw.GetParameters())
 
4470
                                {
 
4471
                                        if (!tw.IsAccessibleFrom(wrapper))
 
4472
                                        {
 
4473
                                                return false;
 
4474
                                        }
 
4475
                                }
 
4476
                                return true;
 
4477
                        }
 
4478
#endif // STATIC_COMPILER
 
4479
 
 
4480
                        private void ImplementInterfaceMethodStubs(Dictionary<TypeWrapper, TypeWrapper> doneSet, TypeWrapper interfaceTypeWrapper, bool baseClassInterface)
 
4481
                        {
 
4482
                                Debug.Assert(interfaceTypeWrapper.IsInterface);
 
4483
 
 
4484
                                // make sure we don't do the same method twice
 
4485
                                if (doneSet.ContainsKey(interfaceTypeWrapper))
 
4486
                                {
 
4487
                                        return;
 
4488
                                }
 
4489
                                doneSet.Add(interfaceTypeWrapper, interfaceTypeWrapper);
 
4490
                                foreach (MethodWrapper method in interfaceTypeWrapper.GetMethods())
 
4491
                                {
 
4492
                                        if (!method.IsStatic && !method.IsDynamicOnly)
 
4493
                                        {
 
4494
                                                ImplementInterfaceMethodStubImpl(method, baseClassInterface);
 
4495
                                        }
 
4496
                                }
 
4497
                                TypeWrapper[] interfaces = interfaceTypeWrapper.Interfaces;
 
4498
                                for (int i = 0; i < interfaces.Length; i++)
 
4499
                                {
 
4500
                                        ImplementInterfaceMethodStubs(doneSet, interfaces[i], baseClassInterface);
 
4501
                                }
 
4502
                        }
 
4503
 
 
4504
                        private void ImplementInterfaceMethodStubImpl(MethodWrapper ifmethod, bool baseClassInterface)
 
4505
                        {
 
4506
                                // we're mangling the name to prevent subclasses from accidentally overriding this method and to
 
4507
                                // prevent clashes with overloaded method stubs that are erased to the same signature (e.g. unloadable types and ghost arrays)
 
4508
                                // HACK the signature and name are the wrong way around to work around a C++/CLI bug (apparantely it looks looks at the last n
 
4509
                                // characters of the method name, or something bizarre like that)
 
4510
                                // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=234167
 
4511
                                string mangledName = ifmethod.DeclaringType.Name + "/" + ifmethod.Signature + ifmethod.Name;
 
4512
                                MethodWrapper mce = null;
 
4513
                                TypeWrapper lookup = wrapper;
 
4514
                                while (lookup != null)
 
4515
                                {
 
4516
                                        mce = lookup.GetMethodWrapper(ifmethod.Name, ifmethod.Signature, true);
 
4517
                                        if (mce == null || !mce.IsStatic)
 
4518
                                        {
 
4519
                                                break;
 
4520
                                        }
 
4521
                                        lookup = mce.DeclaringType.BaseTypeWrapper;
 
4522
                                }
 
4523
                                if (mce != null)
 
4524
                                {
 
4525
                                        Debug.Assert(!mce.HasCallerID);
 
4526
                                        if (mce.DeclaringType != wrapper)
 
4527
                                        {
 
4528
                                                // check the loader constraints
 
4529
                                                bool error = false;
 
4530
                                                if (mce.ReturnType != ifmethod.ReturnType)
 
4531
                                                {
 
4532
                                                        // TODO handle unloadable
 
4533
                                                        error = true;
 
4534
                                                }
 
4535
                                                TypeWrapper[] mceparams = mce.GetParameters();
 
4536
                                                TypeWrapper[] ifparams = ifmethod.GetParameters();
 
4537
                                                for (int i = 0; i < mceparams.Length; i++)
 
4538
                                                {
 
4539
                                                        if (mceparams[i] != ifparams[i])
 
4540
                                                        {
 
4541
                                                                // TODO handle unloadable
 
4542
                                                                error = true;
 
4543
                                                                break;
 
4544
                                                        }
 
4545
                                                }
 
4546
                                                if (error)
 
4547
                                                {
 
4548
                                                        MethodBuilder mb = DefineInterfaceStubMethod(mangledName, ifmethod);
 
4549
                                                        AttributeHelper.HideFromJava(mb);
 
4550
                                                        CodeEmitter ilgen = CodeEmitter.Create(mb);
 
4551
                                                        ilgen.EmitThrow("java.lang.LinkageError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature);
 
4552
                                                        ilgen.DoEmit();
 
4553
                                                        typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod());
 
4554
                                                        return;
 
4555
                                                }
 
4556
                                        }
 
4557
                                        if (mce.IsMirandaMethod && mce.DeclaringType == wrapper)
 
4558
                                        {
 
4559
                                                // Miranda methods already have a methodimpl (if needed) to implement the correct interface method
 
4560
                                        }
 
4561
                                        else if (!mce.IsPublic && !mce.IsInternal)
 
4562
                                        {
 
4563
                                                // NOTE according to the ECMA spec it isn't legal for a privatescope method to be virtual, but this works and
 
4564
                                                // it makes sense, so I hope the spec is wrong
 
4565
                                                // UPDATE unfortunately, according to Serge Lidin the spec is correct, and it is not allowed to have virtual privatescope
 
4566
                                                // methods. Sigh! So I have to use private methods and mangle the name
 
4567
                                                MethodBuilder mb = DefineInterfaceStubMethod(mangledName, ifmethod);
 
4568
                                                AttributeHelper.HideFromJava(mb);
 
4569
                                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
4570
                                                ilgen.EmitThrow("java.lang.IllegalAccessError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature);
 
4571
                                                ilgen.DoEmit();
 
4572
                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod());
 
4573
                                                wrapper.HasIncompleteInterfaceImplementation = true;
 
4574
                                        }
 
4575
                                        else if (mce.GetMethod() == null || mce.RealName != ifmethod.RealName || mce.IsInternal)
 
4576
                                        {
 
4577
                                                MethodBuilder mb = DefineInterfaceStubMethod(mangledName, ifmethod);
 
4578
                                                AttributeHelper.HideFromJava(mb);
 
4579
                                                CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
4580
                                                ilGenerator.Emit(OpCodes.Ldarg_0);
 
4581
                                                int argc = mce.GetParameters().Length;
 
4582
                                                for (int n = 0; n < argc; n++)
 
4583
                                                {
 
4584
                                                        ilGenerator.EmitLdarg(n + 1);
 
4585
                                                }
 
4586
                                                mce.EmitCallvirt(ilGenerator);
 
4587
                                                ilGenerator.Emit(OpCodes.Ret);
 
4588
                                                ilGenerator.DoEmit();
 
4589
                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod());
 
4590
                                        }
 
4591
                                        else if (!ReflectUtil.IsSameAssembly(mce.DeclaringType.TypeAsTBD, typeBuilder))
 
4592
                                        {
 
4593
                                                // NOTE methods inherited from base classes in a different assembly do *not* automatically implement
 
4594
                                                // interface methods, so we have to generate a stub here that doesn't do anything but call the base
 
4595
                                                // implementation
 
4596
                                                MethodBuilder mb = DefineInterfaceStubMethod(mangledName, ifmethod);
 
4597
                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod());
 
4598
                                                AttributeHelper.HideFromJava(mb);
 
4599
                                                CodeEmitter ilGenerator = CodeEmitter.Create(mb);
 
4600
                                                ilGenerator.Emit(OpCodes.Ldarg_0);
 
4601
                                                int argc = mce.GetParameters().Length;
 
4602
                                                for (int n = 0; n < argc; n++)
 
4603
                                                {
 
4604
                                                        ilGenerator.EmitLdarg(n + 1);
 
4605
                                                }
 
4606
                                                mce.EmitCallvirt(ilGenerator);
 
4607
                                                ilGenerator.Emit(OpCodes.Ret);
 
4608
                                                ilGenerator.DoEmit();
 
4609
                                        }
 
4610
                                        else if (CheckRequireOverrideStub(mce, ifmethod))
 
4611
                                        {
 
4612
                                                wrapper.GenerateOverrideStub(typeBuilder, ifmethod, (MethodInfo)mce.GetMethod(), mce);
 
4613
                                        }
 
4614
                                        else if (baseClassInterface && mce.DeclaringType == wrapper)
 
4615
                                        {
 
4616
                                                typeBuilder.DefineMethodOverride((MethodInfo)mce.GetMethod(), (MethodInfo)ifmethod.GetMethod());
 
4617
                                        }
 
4618
                                }
 
4619
                                else
 
4620
                                {
 
4621
                                        if (!wrapper.IsAbstract || (!baseClassInterface && wrapper.GetMethodWrapper(ifmethod.Name, ifmethod.Signature, false) != null))
 
4622
                                        {
 
4623
                                                // the type doesn't implement the interface method and isn't abstract either. The JVM allows this, but the CLR doesn't,
 
4624
                                                // so we have to create a stub method that throws an AbstractMethodError
 
4625
                                                MethodBuilder mb = DefineInterfaceStubMethod(mangledName, ifmethod);
 
4626
                                                AttributeHelper.HideFromJava(mb);
 
4627
                                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
4628
                                                ilgen.EmitThrow("java.lang.AbstractMethodError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature);
 
4629
                                                ilgen.DoEmit();
 
4630
                                                typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod());
 
4631
                                                wrapper.HasIncompleteInterfaceImplementation = true;
 
4632
                                        }
 
4633
                                }
 
4634
                        }
 
4635
 
 
4636
                        private MethodBuilder DefineInterfaceStubMethod(string name, MethodWrapper mw)
 
4637
                        {
 
4638
                                return mw.GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final);
 
4639
                        }
 
4640
 
 
4641
                        private static class BakedTypeCleanupHack
 
4642
                        {
 
4643
#if NET_4_0 || STATIC_COMPILER
 
4644
                                internal static void Process(DynamicTypeWrapper wrapper) { }
 
4645
#else
 
4646
                                private static readonly FieldInfo m_methodBuilder = typeof(ConstructorBuilder).GetField("m_methodBuilder", BindingFlags.Instance | BindingFlags.NonPublic);
 
4647
                                private static readonly FieldInfo[] methodBuilderFields = GetFieldList(typeof(MethodBuilder), new string[]
 
4648
                                        {
 
4649
                                                "m_ilGenerator",
 
4650
                                                "m_ubBody",
 
4651
                                                "m_RVAFixups",
 
4652
                                                "m_mdMethodFixups",
 
4653
                                                "m_localSignature",
 
4654
                                                "m_localSymInfo",
 
4655
                                                "m_exceptions",
 
4656
                                                "m_parameterTypes",
 
4657
                                                "m_retParam",
 
4658
                                                "m_returnType",
 
4659
                                                "m_signature"
 
4660
                                        });
 
4661
                                private static readonly FieldInfo[] fieldBuilderFields = GetFieldList(typeof(FieldBuilder), new string[]
 
4662
                                        {
 
4663
                                                "m_data",
 
4664
                                                "m_fieldType",
 
4665
                                        });
 
4666
 
 
4667
                                private static bool IsSupportedVersion
 
4668
                                {
 
4669
                                        get
 
4670
                                        {
 
4671
                                                return Environment.Version.Major == 2 && Environment.Version.Minor == 0 && Environment.Version.Build == 50727 && Environment.Version.Revision == 4016;
 
4672
                                        }
 
4673
                                }
 
4674
 
 
4675
                                [SecurityCritical]
 
4676
                                [SecurityTreatAsSafe]
 
4677
                                private static FieldInfo[] GetFieldList(Type type, string[] list)
 
4678
                                {
 
4679
                                        if (JVM.SafeGetEnvironmentVariable("IKVM_DISABLE_TYPEBUILDER_HACK") != null || !IsSupportedVersion)
 
4680
                                        {
 
4681
                                                return null;
 
4682
                                        }
 
4683
                                        if (!SecurityManager.IsGranted(new SecurityPermission(SecurityPermissionFlag.Assertion)) ||
 
4684
                                                !SecurityManager.IsGranted(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)))
 
4685
                                        {
 
4686
                                                return null;
 
4687
                                        }
 
4688
                                        FieldInfo[] fields = new FieldInfo[list.Length];
 
4689
                                        for (int i = 0; i < list.Length; i++)
 
4690
                                        {
 
4691
                                                fields[i] = type.GetField(list[i], BindingFlags.Instance | BindingFlags.NonPublic);
 
4692
                                                if (fields[i] == null)
 
4693
                                                {
 
4694
                                                        return null;
 
4695
                                                }
 
4696
                                        }
 
4697
                                        return fields;
 
4698
                                }
 
4699
 
 
4700
                                [SecurityCritical]
 
4701
                                [SecurityTreatAsSafe]
 
4702
                                internal static void Process(DynamicTypeWrapper wrapper)
 
4703
                                {
 
4704
                                        if (m_methodBuilder != null && methodBuilderFields != null && fieldBuilderFields != null)
 
4705
                                        {
 
4706
                                                foreach (MethodWrapper mw in wrapper.GetMethods())
 
4707
                                                {
 
4708
                                                        MethodBuilder mb = mw.GetMethod() as MethodBuilder;
 
4709
                                                        if (mb == null)
 
4710
                                                        {
 
4711
                                                                ConstructorBuilder cb = mw.GetMethod() as ConstructorBuilder;
 
4712
                                                                if (cb != null)
 
4713
                                                                {
 
4714
                                                                        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
 
4715
                                                                        mb = (MethodBuilder)m_methodBuilder.GetValue(cb);
 
4716
                                                                        CodeAccessPermission.RevertAssert();
 
4717
                                                                }
 
4718
                                                        }
 
4719
                                                        if (mb != null)
 
4720
                                                        {
 
4721
                                                                new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
 
4722
                                                                foreach (FieldInfo fi in methodBuilderFields)
 
4723
                                                                {
 
4724
                                                                        fi.SetValue(mb, null);
 
4725
                                                                }
 
4726
                                                                CodeAccessPermission.RevertAssert();
 
4727
                                                        }
 
4728
                                                }
 
4729
                                                foreach (FieldWrapper fw in wrapper.GetFields())
 
4730
                                                {
 
4731
                                                        FieldBuilder fb = fw.GetField() as FieldBuilder;
 
4732
                                                        if (fb != null)
 
4733
                                                        {
 
4734
                                                                new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
 
4735
                                                                foreach (FieldInfo fi in fieldBuilderFields)
 
4736
                                                                {
 
4737
                                                                        fi.SetValue(fb, null);
 
4738
                                                                }
 
4739
                                                                CodeAccessPermission.RevertAssert();
 
4740
                                                        }
 
4741
                                                }
 
4742
                                        }
 
4743
                                }
 
4744
#endif // NET_4_0
 
4745
                        }
 
4746
 
 
4747
#if !STATIC_COMPILER
 
4748
                        internal static class JniProxyBuilder
 
4749
                        {
 
4750
                                private static ModuleBuilder mod;
 
4751
                                private static int count;
 
4752
 
 
4753
                                static JniProxyBuilder()
 
4754
                                {
 
4755
                                        AssemblyName name = new AssemblyName();
 
4756
                                        name.Name = "jniproxy";
 
4757
                                        AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(name, JVM.IsSaveDebugImage ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
 
4758
                                        DynamicClassLoader.RegisterForSaveDebug(ab);
 
4759
                                        mod = ab.DefineDynamicModule("jniproxy.dll", "jniproxy.dll");
 
4760
                                        CustomAttributeBuilder cab = new CustomAttributeBuilder(JVM.LoadType(typeof(JavaModuleAttribute)).GetConstructor(Type.EmptyTypes), new object[0]);
 
4761
                                        mod.SetCustomAttribute(cab);
 
4762
                                }
 
4763
 
 
4764
                                internal static void Generate(DynamicTypeWrapper.FinishContext context, CodeEmitter ilGenerator, DynamicTypeWrapper wrapper, MethodWrapper mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, TypeWrapper[] args)
 
4765
                                {
 
4766
                                        TypeBuilder tb = mod.DefineType("__<jni>" + (count++), TypeAttributes.Public | TypeAttributes.Class);
 
4767
                                        int instance = m.IsStatic ? 0 : 1;
 
4768
                                        Type[] argTypes = new Type[args.Length + instance + 1];
 
4769
                                        if (instance != 0)
 
4770
                                        {
 
4771
                                                argTypes[0] = typeof(object);
 
4772
                                        }
 
4773
                                        for (int i = 0; i < args.Length; i++)
 
4774
                                        {
 
4775
                                                // NOTE we take a shortcut here by assuming that all "special" types (i.e. ghost or value types)
 
4776
                                                // are public and so we can get away with replacing all other types with object.
 
4777
                                                argTypes[i + instance] = (args[i].IsPrimitive || args[i].IsGhost || args[i].IsNonPrimitiveValueType) ? args[i].TypeAsSignatureType : typeof(object);
 
4778
                                        }
 
4779
                                        argTypes[argTypes.Length - 1] = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.CallerID").TypeAsSignatureType;
 
4780
                                        Type retType = (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : typeof(object);
 
4781
                                        MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, retType, argTypes);
 
4782
                                        AttributeHelper.HideFromJava(mb);
 
4783
                                        CodeEmitter ilgen = CodeEmitter.Create(mb);
 
4784
                                        JniBuilder.Generate(context, ilgen, wrapper, mw, tb, classFile, m, args, true);
 
4785
                                        ilgen.DoEmit();
 
4786
                                        tb.CreateType();
 
4787
                                        for (int i = 0; i < argTypes.Length - 1; i++)
 
4788
                                        {
 
4789
                                                ilGenerator.EmitLdarg(i);
 
4790
                                        }
 
4791
                                        context.EmitCallerID(ilGenerator);
 
4792
                                        ilGenerator.Emit(OpCodes.Call, mb);
 
4793
                                        if (!mw.ReturnType.IsPrimitive && !mw.ReturnType.IsGhost && !mw.ReturnType.IsNonPrimitiveValueType)
 
4794
                                        {
 
4795
                                                ilGenerator.Emit(OpCodes.Castclass, mw.ReturnType.TypeAsSignatureType);
 
4796
                                        }
 
4797
                                        ilGenerator.Emit(OpCodes.Ret);
 
4798
                                }
 
4799
                        }
 
4800
#endif // !STATIC_COMPILER
 
4801
 
 
4802
                        private static class JniBuilder
 
4803
                        {
 
4804
#if STATIC_COMPILER
 
4805
                                private static readonly Type localRefStructType = StaticCompiler.GetRuntimeType("IKVM.Runtime.JNI+Frame");
 
4806
#elif FIRST_PASS
 
4807
                                private static readonly Type localRefStructType = null;
 
4808
#else
 
4809
                                private static readonly Type localRefStructType = JVM.LoadType(typeof(IKVM.Runtime.JNI.Frame));
 
4810
#endif
 
4811
                                private static readonly MethodInfo jniFuncPtrMethod = localRefStructType.GetMethod("GetFuncPtr");
 
4812
                                private static readonly MethodInfo enterLocalRefStruct = localRefStructType.GetMethod("Enter");
 
4813
                                private static readonly MethodInfo leaveLocalRefStruct = localRefStructType.GetMethod("Leave");
 
4814
                                private static readonly MethodInfo makeLocalRef = localRefStructType.GetMethod("MakeLocalRef");
 
4815
                                private static readonly MethodInfo unwrapLocalRef = localRefStructType.GetMethod("UnwrapLocalRef");
 
4816
                                private static readonly MethodInfo writeLine = JVM.Import(typeof(Console)).GetMethod("WriteLine", new Type[] { Types.Object });
 
4817
                                private static readonly MethodInfo monitorEnter = JVM.Import(typeof(System.Threading.Monitor)).GetMethod("Enter", new Type[] { Types.Object });
 
4818
                                private static readonly MethodInfo monitorExit = JVM.Import(typeof(System.Threading.Monitor)).GetMethod("Exit", new Type[] { Types.Object });
 
4819
 
 
4820
                                internal static void Generate(DynamicTypeWrapper.FinishContext context, CodeEmitter ilGenerator, DynamicTypeWrapper wrapper, MethodWrapper mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, TypeWrapper[] args, bool thruProxy)
 
4821
                                {
 
4822
                                        CodeEmitterLocal syncObject = null;
 
4823
                                        if (m.IsSynchronized && m.IsStatic)
 
4824
                                        {
 
4825
                                                wrapper.EmitClassLiteral(ilGenerator);
 
4826
                                                ilGenerator.Emit(OpCodes.Dup);
 
4827
                                                syncObject = ilGenerator.DeclareLocal(Types.Object);
 
4828
                                                ilGenerator.Emit(OpCodes.Stloc, syncObject);
 
4829
                                                ilGenerator.Emit(OpCodes.Call, monitorEnter);
 
4830
                                                ilGenerator.BeginExceptionBlock();
 
4831
                                        }
 
4832
                                        string sig = m.Signature.Replace('.', '/');
 
4833
                                        // TODO use/unify JNI.METHOD_PTR_FIELD_PREFIX
 
4834
                                        FieldBuilder methodPtr = typeBuilder.DefineField("__<jniptr>" + m.Name + sig, Types.IntPtr, FieldAttributes.Static | FieldAttributes.PrivateScope);
 
4835
                                        CodeEmitterLocal localRefStruct = ilGenerator.DeclareLocal(localRefStructType);
 
4836
                                        ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4837
                                        ilGenerator.Emit(OpCodes.Initobj, localRefStructType);
 
4838
                                        ilGenerator.Emit(OpCodes.Ldsfld, methodPtr);
 
4839
                                        CodeEmitterLabel oklabel = ilGenerator.DefineLabel();
 
4840
                                        ilGenerator.EmitBrtrue(oklabel);
 
4841
                                        if (thruProxy)
 
4842
                                        {
 
4843
                                                ilGenerator.EmitLdarg(args.Length + (mw.IsStatic ? 0 : 1));
 
4844
                                        }
 
4845
                                        else
 
4846
                                        {
 
4847
                                                context.EmitCallerID(ilGenerator);
 
4848
                                        }
 
4849
                                        ilGenerator.Emit(OpCodes.Ldstr, classFile.Name.Replace('.', '/'));
 
4850
                                        ilGenerator.Emit(OpCodes.Ldstr, m.Name);
 
4851
                                        ilGenerator.Emit(OpCodes.Ldstr, sig);
 
4852
                                        ilGenerator.Emit(OpCodes.Call, jniFuncPtrMethod);
 
4853
                                        ilGenerator.Emit(OpCodes.Stsfld, methodPtr);
 
4854
                                        ilGenerator.MarkLabel(oklabel);
 
4855
                                        ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4856
                                        if (thruProxy)
 
4857
                                        {
 
4858
                                                ilGenerator.EmitLdarg(args.Length + (mw.IsStatic ? 0 : 1));
 
4859
                                        }
 
4860
                                        else
 
4861
                                        {
 
4862
                                                context.EmitCallerID(ilGenerator);
 
4863
                                        }
 
4864
                                        ilGenerator.Emit(OpCodes.Call, enterLocalRefStruct);
 
4865
                                        CodeEmitterLocal jnienv = ilGenerator.DeclareLocal(Types.IntPtr);
 
4866
                                        ilGenerator.Emit(OpCodes.Stloc, jnienv);
 
4867
                                        ilGenerator.BeginExceptionBlock();
 
4868
                                        TypeWrapper retTypeWrapper = mw.ReturnType;
 
4869
                                        if (!retTypeWrapper.IsUnloadable && !retTypeWrapper.IsPrimitive)
 
4870
                                        {
 
4871
                                                // this one is for use after we return from "calli"
 
4872
                                                ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4873
                                        }
 
4874
                                        ilGenerator.Emit(OpCodes.Ldloc, jnienv);
 
4875
                                        Type[] modargs = new Type[args.Length + 2];
 
4876
                                        modargs[0] = Types.IntPtr;
 
4877
                                        modargs[1] = Types.IntPtr;
 
4878
                                        for (int i = 0; i < args.Length; i++)
 
4879
                                        {
 
4880
                                                modargs[i + 2] = args[i].TypeAsSignatureType;
 
4881
                                        }
 
4882
                                        int add = 0;
 
4883
                                        if (!m.IsStatic)
 
4884
                                        {
 
4885
                                                ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4886
                                                ilGenerator.Emit(OpCodes.Ldarg_0);
 
4887
                                                ilGenerator.Emit(OpCodes.Call, makeLocalRef);
 
4888
                                                add = 1;
 
4889
                                        }
 
4890
                                        else
 
4891
                                        {
 
4892
                                                ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4893
                                                wrapper.EmitClassLiteral(ilGenerator);
 
4894
                                                ilGenerator.Emit(OpCodes.Call, makeLocalRef);
 
4895
                                        }
 
4896
                                        for (int j = 0; j < args.Length; j++)
 
4897
                                        {
 
4898
                                                if (args[j].IsUnloadable || !args[j].IsPrimitive)
 
4899
                                                {
 
4900
                                                        ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4901
                                                        if (!args[j].IsUnloadable && args[j].IsNonPrimitiveValueType)
 
4902
                                                        {
 
4903
                                                                ilGenerator.EmitLdarg(j + add);
 
4904
                                                                args[j].EmitBox(ilGenerator);
 
4905
                                                        }
 
4906
                                                        else if (!args[j].IsUnloadable && args[j].IsGhost)
 
4907
                                                        {
 
4908
                                                                ilGenerator.EmitLdarga(j + add);
 
4909
                                                                ilGenerator.Emit(OpCodes.Ldfld, args[j].GhostRefField);
 
4910
                                                        }
 
4911
                                                        else
 
4912
                                                        {
 
4913
                                                                ilGenerator.EmitLdarg(j + add);
 
4914
                                                        }
 
4915
                                                        ilGenerator.Emit(OpCodes.Call, makeLocalRef);
 
4916
                                                        modargs[j + 2] = Types.IntPtr;
 
4917
                                                }
 
4918
                                                else
 
4919
                                                {
 
4920
                                                        ilGenerator.EmitLdarg(j + add);
 
4921
                                                }
 
4922
                                        }
 
4923
                                        ilGenerator.Emit(OpCodes.Ldsfld, methodPtr);
 
4924
                                        Type realRetType;
 
4925
                                        if (retTypeWrapper == PrimitiveTypeWrapper.BOOLEAN)
 
4926
                                        {
 
4927
                                                realRetType = Types.Byte;
 
4928
                                        }
 
4929
                                        else if (retTypeWrapper.IsPrimitive)
 
4930
                                        {
 
4931
                                                realRetType = retTypeWrapper.TypeAsSignatureType;
 
4932
                                        }
 
4933
                                        else
 
4934
                                        {
 
4935
                                                realRetType = Types.IntPtr;
 
4936
                                        }
 
4937
                                        ilGenerator.EmitCalli(OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, realRetType, modargs);
 
4938
                                        CodeEmitterLocal retValue = null;
 
4939
                                        if (retTypeWrapper != PrimitiveTypeWrapper.VOID)
 
4940
                                        {
 
4941
                                                if (!retTypeWrapper.IsUnloadable && !retTypeWrapper.IsPrimitive)
 
4942
                                                {
 
4943
                                                        ilGenerator.Emit(OpCodes.Call, unwrapLocalRef);
 
4944
                                                        if (retTypeWrapper.IsNonPrimitiveValueType)
 
4945
                                                        {
 
4946
                                                                retTypeWrapper.EmitUnbox(ilGenerator);
 
4947
                                                        }
 
4948
                                                        else if (retTypeWrapper.IsGhost)
 
4949
                                                        {
 
4950
                                                                CodeEmitterLocal ghost = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
 
4951
                                                                CodeEmitterLocal obj = ilGenerator.DeclareLocal(Types.Object);
 
4952
                                                                ilGenerator.Emit(OpCodes.Stloc, obj);
 
4953
                                                                ilGenerator.Emit(OpCodes.Ldloca, ghost);
 
4954
                                                                ilGenerator.Emit(OpCodes.Ldloc, obj);
 
4955
                                                                ilGenerator.Emit(OpCodes.Stfld, retTypeWrapper.GhostRefField);
 
4956
                                                                ilGenerator.Emit(OpCodes.Ldloc, ghost);
 
4957
                                                        }
 
4958
                                                        else
 
4959
                                                        {
 
4960
                                                                ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsTBD);
 
4961
                                                        }
 
4962
                                                }
 
4963
                                                retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
 
4964
                                                ilGenerator.Emit(OpCodes.Stloc, retValue);
 
4965
                                        }
 
4966
                                        CodeEmitterLabel retLabel = ilGenerator.DefineLabel();
 
4967
                                        ilGenerator.EmitLeave(retLabel);
 
4968
                                        ilGenerator.BeginCatchBlock(Types.Object);
 
4969
                                        ilGenerator.Emit(OpCodes.Ldstr, "*** exception in native code ***");
 
4970
                                        ilGenerator.Emit(OpCodes.Call, writeLine);
 
4971
                                        ilGenerator.Emit(OpCodes.Call, writeLine);
 
4972
                                        ilGenerator.Emit(OpCodes.Rethrow);
 
4973
                                        ilGenerator.BeginFinallyBlock();
 
4974
                                        ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
 
4975
                                        ilGenerator.Emit(OpCodes.Call, leaveLocalRefStruct);
 
4976
                                        ilGenerator.Emit(OpCodes.Endfinally);
 
4977
                                        ilGenerator.EndExceptionBlock();
 
4978
                                        if (m.IsSynchronized && m.IsStatic)
 
4979
                                        {
 
4980
                                                ilGenerator.BeginFinallyBlock();
 
4981
                                                ilGenerator.Emit(OpCodes.Ldloc, syncObject);
 
4982
                                                ilGenerator.Emit(OpCodes.Call, monitorExit);
 
4983
                                                ilGenerator.Emit(OpCodes.Endfinally);
 
4984
                                                ilGenerator.EndExceptionBlock();
 
4985
                                        }
 
4986
                                        ilGenerator.MarkLabel(retLabel);
 
4987
                                        if (retTypeWrapper != PrimitiveTypeWrapper.VOID)
 
4988
                                        {
 
4989
                                                ilGenerator.Emit(OpCodes.Ldloc, retValue);
 
4990
                                        }
 
4991
                                        ilGenerator.Emit(OpCodes.Ret);
 
4992
                                }
 
4993
                        }
 
4994
 
 
4995
                        private static class TraceHelper
 
4996
                        {
 
4997
#if STATIC_COMPILER
 
4998
                                private readonly static MethodInfo methodIsTracedMethod = JVM.LoadType(typeof(Tracer)).GetMethod("IsTracedMethod");
 
4999
#endif
 
5000
                                private readonly static MethodInfo methodMethodInfo = JVM.LoadType(typeof(Tracer)).GetMethod("MethodInfo");
 
5001
 
 
5002
                                internal static void EmitMethodTrace(CodeEmitter ilgen, string tracemessage)
 
5003
                                {
 
5004
                                        if (Tracer.IsTracedMethod(tracemessage))
 
5005
                                        {
 
5006
                                                CodeEmitterLabel label = ilgen.DefineLabel();
 
5007
#if STATIC_COMPILER
 
5008
                                                // TODO this should be a boolean field test instead of a call to Tracer.IsTracedMessage
 
5009
                                                ilgen.Emit(OpCodes.Ldstr, tracemessage);
 
5010
                                                ilgen.Emit(OpCodes.Call, methodIsTracedMethod);
 
5011
                                                ilgen.EmitBrfalse(label);
 
5012
#endif
 
5013
                                                ilgen.Emit(OpCodes.Ldstr, tracemessage);
 
5014
                                                ilgen.Emit(OpCodes.Call, methodMethodInfo);
 
5015
                                                ilgen.MarkLabel(label);
 
5016
                                        }
 
5017
                                }
 
5018
                        }
 
5019
 
 
5020
#if STATIC_COMPILER
 
5021
                        private void EmitCallerIDStub(MethodWrapper mw, string[] parameterNames)
 
5022
                        {
 
5023
                                // we don't need to support custom modifiers, because there aren't any callerid methods that have parameter types that require a custom modifier
 
5024
                                TypeWrapper[] parameters = mw.GetParameters();
 
5025
                                Type[] parameterTypes = new Type[parameters.Length];
 
5026
                                for (int i = 0; i < parameterTypes.Length; i++)
 
5027
                                {
 
5028
                                        parameterTypes[i] = parameters[i].TypeAsSignatureType;
 
5029
                                }
 
5030
                                MethodAttributes attribs = MethodAttributes.HideBySig;
 
5031
                                int argcount = parameterTypes.Length;
 
5032
                                if (mw.IsStatic)
 
5033
                                {
 
5034
                                        attribs |= MethodAttributes.Static;
 
5035
                                }
 
5036
                                else
 
5037
                                {
 
5038
                                        argcount++;
 
5039
                                }
 
5040
                                if (mw.IsPublic)
 
5041
                                {
 
5042
                                        attribs |= MethodAttributes.Public;
 
5043
                                }
 
5044
                                else if (mw.IsProtected)
 
5045
                                {
 
5046
                                        attribs |= MethodAttributes.FamORAssem;
 
5047
                                }
 
5048
                                else if (mw.IsPrivate)
 
5049
                                {
 
5050
                                        attribs |= MethodAttributes.Private;
 
5051
                                }
 
5052
                                else
 
5053
                                {
 
5054
                                        attribs |= MethodAttributes.Assembly;
 
5055
                                }
 
5056
                                MethodBuilder mb = typeBuilder.DefineMethod(mw.Name, attribs, mw.ReturnType.TypeAsSignatureType, parameterTypes);
 
5057
                                AttributeHelper.HideFromJava(mb);
 
5058
                                mb.SetImplementationFlags(MethodImplAttributes.NoInlining);
 
5059
                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
5060
                                for (int i = 0; i < argcount; i++)
 
5061
                                {
 
5062
                                        if (parameterNames != null && (mw.IsStatic || i > 0))
 
5063
                                        {
 
5064
                                                ParameterBuilder pb = mb.DefineParameter(mw.IsStatic ? i + 1 : i, ParameterAttributes.None, parameterNames[mw.IsStatic ? i : i - 1]);
 
5065
                                                if (i == argcount - 1 && (mw.Modifiers & Modifiers.VarArgs) != 0)
 
5066
                                                {
 
5067
                                                        AttributeHelper.SetParamArrayAttribute(pb);
 
5068
                                                }
 
5069
                                        }
 
5070
                                        ilgen.EmitLdarg(i);
 
5071
                                }
 
5072
                                ilgen.Emit(OpCodes.Ldc_I4_1);
 
5073
                                ilgen.Emit(OpCodes.Ldc_I4_0);
 
5074
                                ilgen.Emit(OpCodes.Newobj, JVM.Import(typeof(StackFrame)).GetConstructor(new Type[] { Types.Int32, Types.Boolean }));
 
5075
                                MethodWrapper callerID = CoreClasses.ikvm.@internal.CallerID.Wrapper.GetMethodWrapper("create", "(Lcli.System.Diagnostics.StackFrame;)Likvm.internal.CallerID;", false);
 
5076
                                callerID.Link();
 
5077
                                callerID.EmitCall(ilgen);
 
5078
                                if (mw.IsStatic)
 
5079
                                {
 
5080
                                        mw.EmitCall(ilgen);
 
5081
                                }
 
5082
                                else
 
5083
                                {
 
5084
                                        mw.EmitCallvirt(ilgen);
 
5085
                                }
 
5086
                                ilgen.Emit(OpCodes.Ret);
 
5087
                                ilgen.DoEmit();
 
5088
                        }
 
5089
#endif // STATIC_COMPILER
 
5090
 
 
5091
                        private void ImplementInterfaces(TypeWrapper[] interfaces, List<TypeWrapper> interfaceList)
 
5092
                        {
 
5093
                                foreach (TypeWrapper iface in interfaces)
 
5094
                                {
 
5095
                                        if (!interfaceList.Contains(iface))
 
5096
                                        {
 
5097
                                                interfaceList.Add(iface);
 
5098
                                                // NOTE we're using TypeAsBaseType for the interfaces!
 
5099
                                                Type ifaceType = iface.TypeAsBaseType;
 
5100
                                                if (!iface.IsPublic && !ReflectUtil.IsSameAssembly(ifaceType, typeBuilder))
 
5101
                                                {
 
5102
                                                        ifaceType = ReflectUtil.GetAssembly(ifaceType).GetType(DynamicClassLoader.GetProxyHelperName(ifaceType));
 
5103
                                                }
 
5104
                                                typeBuilder.AddInterfaceImplementation(ifaceType);
 
5105
#if STATIC_COMPILER
 
5106
                                                if (!wrapper.IsInterface)
 
5107
                                                {
 
5108
                                                        // look for "magic" interfaces that imply a .NET interface
 
5109
                                                        if (iface.GetClassLoader() == CoreClasses.java.lang.Object.Wrapper.GetClassLoader())
 
5110
                                                        {
 
5111
                                                                if (iface.Name == "java.lang.Iterable"
 
5112
                                                                        && !wrapper.ImplementsInterface(ClassLoaderWrapper.GetWrapperFromType(JVM.Import(typeof(System.Collections.IEnumerable)))))
 
5113
                                                                {
 
5114
                                                                        TypeWrapper enumeratorType = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast("ikvm.lang.IterableEnumerator");
 
5115
                                                                        if (enumeratorType != null)
 
5116
                                                                        {
 
5117
                                                                                typeBuilder.AddInterfaceImplementation(JVM.Import(typeof(System.Collections.IEnumerable)));
 
5118
                                                                                // FXBUG we're using the same method name as the C# compiler here because both the .NET and Mono implementations of Xml serialization depend on this method name
 
5119
                                                                                MethodBuilder mb = typeBuilder.DefineMethod("System.Collections.IEnumerable.GetEnumerator", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName, JVM.Import(typeof(System.Collections.IEnumerator)), Type.EmptyTypes);
 
5120
                                                                                AttributeHelper.HideFromJava(mb);
 
5121
                                                                                typeBuilder.DefineMethodOverride(mb, JVM.Import(typeof(System.Collections.IEnumerable)).GetMethod("GetEnumerator"));
 
5122
                                                                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
5123
                                                                                ilgen.Emit(OpCodes.Ldarg_0);
 
5124
                                                                                MethodWrapper mw = enumeratorType.GetMethodWrapper("<init>", "(Ljava.lang.Iterable;)V", false);
 
5125
                                                                                mw.Link();
 
5126
                                                                                mw.EmitNewobj(ilgen);
 
5127
                                                                                ilgen.Emit(OpCodes.Ret);
 
5128
                                                                                ilgen.DoEmit();
 
5129
                                                                        }
 
5130
                                                                }
 
5131
                                                        }
 
5132
                                                        // if we implement a ghost interface, add an implicit conversion to the ghost reference value type
 
5133
                                                        if (iface.IsGhost && wrapper.IsPublic)
 
5134
                                                        {
 
5135
                                                                MethodBuilder mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, iface.TypeAsSignatureType, new Type[] { wrapper.TypeAsSignatureType });
 
5136
                                                                AttributeHelper.HideFromJava(mb);
 
5137
                                                                CodeEmitter ilgen = CodeEmitter.Create(mb);
 
5138
                                                                CodeEmitterLocal local = ilgen.DeclareLocal(iface.TypeAsSignatureType);
 
5139
                                                                ilgen.Emit(OpCodes.Ldloca, local);
 
5140
                                                                ilgen.Emit(OpCodes.Ldarg_0);
 
5141
                                                                ilgen.Emit(OpCodes.Stfld, iface.GhostRefField);
 
5142
                                                                ilgen.Emit(OpCodes.Ldloca, local);
 
5143
                                                                ilgen.Emit(OpCodes.Ldobj, iface.TypeAsSignatureType);
 
5144
                                                                ilgen.Emit(OpCodes.Ret);
 
5145
                                                                ilgen.DoEmit();
 
5146
                                                        }
 
5147
                                                }
 
5148
#endif // STATIC_COMPILER
 
5149
                                                // NOTE we're recursively "implementing" all interfaces that we inherit from the interfaces we implement.
 
5150
                                                // The C# compiler also does this and the Compact Framework requires it.
 
5151
                                                ImplementInterfaces(iface.Interfaces, interfaceList);
 
5152
                                        }
 
5153
                                }
 
5154
                        }
 
5155
 
 
5156
                        private void AddUnsupportedAbstractMethods()
 
5157
                        {
 
5158
                                foreach (MethodBase mb in wrapper.BaseTypeWrapper.TypeAsBaseType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
 
5159
                                {
 
5160
                                        if (DotNetTypeWrapper.IsUnsupportedAbstractMethod(mb))
 
5161
                                        {
 
5162
                                                GenerateUnsupportedAbstractMethodStub(mb);
 
5163
                                        }
 
5164
                                }
 
5165
                                Dictionary<MethodBase, MethodBase> h = new Dictionary<MethodBase, MethodBase>();
 
5166
                                TypeWrapper tw = wrapper;
 
5167
                                while (tw != null)
 
5168
                                {
 
5169
                                        foreach (TypeWrapper iface in tw.Interfaces)
 
5170
                                        {
 
5171
                                                foreach (MethodBase mb in iface.TypeAsBaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
 
5172
                                                {
 
5173
                                                        if (!h.ContainsKey(mb))
 
5174
                                                        {
 
5175
                                                                h.Add(mb, mb);
 
5176
                                                                if (DotNetTypeWrapper.IsUnsupportedAbstractMethod(mb))
 
5177
                                                                {
 
5178
                                                                        GenerateUnsupportedAbstractMethodStub(mb);
 
5179
                                                                }
 
5180
                                                        }
 
5181
                                                }
 
5182
                                        }
 
5183
                                        tw = tw.BaseTypeWrapper;
 
5184
                                }
 
5185
                        }
 
5186
 
 
5187
                        private void GenerateUnsupportedAbstractMethodStub(MethodBase mb)
 
5188
                        {
 
5189
                                ParameterInfo[] parameters = mb.GetParameters();
 
5190
                                Type[] parameterTypes = new Type[parameters.Length];
 
5191
                                for (int i = 0; i < parameters.Length; i++)
 
5192
                                {
 
5193
                                        parameterTypes[i] = parameters[i].ParameterType;
 
5194
                                }
 
5195
                                MethodAttributes attr = MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Private;
 
5196
                                MethodBuilder m = typeBuilder.DefineMethod("__<unsupported>" + mb.DeclaringType.FullName + "/" + mb.Name, attr, ((MethodInfo)mb).ReturnType, parameterTypes);
 
5197
                                if (mb.IsGenericMethodDefinition)
 
5198
                                {
 
5199
                                        CopyGenericArguments(mb, m);
 
5200
                                }
 
5201
                                CodeEmitter ilgen = CodeEmitter.Create(m);
 
5202
                                ilgen.EmitThrow("java.lang.AbstractMethodError", "Method " + mb.DeclaringType.FullName + "." + mb.Name + " is unsupported by IKVM.");
 
5203
                                ilgen.DoEmit();
 
5204
                                typeBuilder.DefineMethodOverride(m, (MethodInfo)mb);
 
5205
                        }
 
5206
 
 
5207
                        private static void CopyGenericArguments(MethodBase mi, MethodBuilder mb)
 
5208
                        {
 
5209
                                Type[] genericParameters = mi.GetGenericArguments();
 
5210
                                string[] genParamNames = new string[genericParameters.Length];
 
5211
                                for (int i = 0; i < genParamNames.Length; i++)
 
5212
                                {
 
5213
                                        genParamNames[i] = genericParameters[i].Name;
 
5214
                                }
 
5215
                                GenericTypeParameterBuilder[] genParamBuilders = mb.DefineGenericParameters(genParamNames);
 
5216
                                for (int i = 0; i < genParamBuilders.Length; i++)
 
5217
                                {
 
5218
                                        // NOTE apparently we don't need to set the interface constraints
 
5219
                                        // (and if we do, it fails for some reason)
 
5220
                                        if (genericParameters[i].BaseType != Types.Object)
 
5221
                                        {
 
5222
                                                genParamBuilders[i].SetBaseTypeConstraint(genericParameters[i].BaseType);
 
5223
                                        }
 
5224
                                        genParamBuilders[i].SetGenericParameterAttributes(genericParameters[i].GenericParameterAttributes);
 
5225
                                }
 
5226
                        }
 
5227
 
 
5228
                        private void CompileConstructorBody(FinishContext context, CodeEmitter ilGenerator, int methodIndex, Dictionary<MethodKey, MethodInfo> invokespecialstubcache)
 
5229
                        {
 
5230
                                MethodWrapper[] methods = wrapper.GetMethods();
 
5231
                                ClassFile.Method m = classFile.Methods[methodIndex];
 
5232
                                TraceHelper.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
 
5233
#if STATIC_COMPILER
 
5234
                                // do we have an implementation in map.xml?
 
5235
                                if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m))
 
5236
                                {
 
5237
                                        ilGenerator.DoEmit();
 
5238
                                        return;
 
5239
                                }
 
5240
#endif
 
5241
                                bool nonLeaf = false;
 
5242
                                Compiler.Compile(context, wrapper, methods[methodIndex], classFile, m, ilGenerator, ref nonLeaf, invokespecialstubcache);
 
5243
                                ilGenerator.DoEmit();
 
5244
#if STATIC_COMPILER
 
5245
                                ilGenerator.EmitLineNumberTable((MethodBuilder)methods[methodIndex].GetMethod());
 
5246
#else // STATIC_COMPILER
 
5247
                                byte[] linenumbers = ilGenerator.GetLineNumberTable();
 
5248
                                if (linenumbers != null)
 
5249
                                {
 
5250
                                        if (wrapper.lineNumberTables == null)
 
5251
                                        {
 
5252
                                                wrapper.lineNumberTables = new byte[methods.Length][];
 
5253
                                        }
 
5254
                                        wrapper.lineNumberTables[methodIndex] = linenumbers;
 
5255
                                }
 
5256
#endif // STATIC_COMPILER
 
5257
                        }
 
5258
 
 
5259
                        private static bool IsCompatibleArgList(TypeWrapper[] caller, TypeWrapper[] callee)
 
5260
                        {
 
5261
                                if (caller.Length == callee.Length)
 
5262
                                {
 
5263
                                        for (int i = 0; i < caller.Length; i++)
 
5264
                                        {
 
5265
                                                if (!caller[i].IsAssignableTo(callee[i]))
 
5266
                                                {
 
5267
                                                        return false;
 
5268
                                                }
 
5269
                                        }
 
5270
                                        return true;
 
5271
                                }
 
5272
                                return false;
 
5273
                        }
 
5274
 
 
5275
                        private void EmitCallerIDInitialization(CodeEmitter ilGenerator, FieldInfo callerIDField)
 
5276
                        {
 
5277
                                {
 
5278
                                        // we need to prohibit this optimization at runtime, because proxy classes may be injected into the boot class loader,
 
5279
                                        // but they don't actually have access to core library internals
 
5280
#if STATIC_COMPILER
 
5281
                                        TypeWrapper tw = CoreClasses.ikvm.@internal.CallerID.Wrapper;
 
5282
                                        if (tw.GetClassLoader() == wrapper.GetClassLoader())
 
5283
                                        {
 
5284
                                                MethodWrapper create = tw.GetMethodWrapper("create", "(Lcli.System.RuntimeTypeHandle;)Likvm.internal.CallerID;", false);
 
5285
                                                ilGenerator.Emit(OpCodes.Ldtoken, this.typeBuilder);
 
5286
                                                create.Link();
 
5287
                                                create.EmitCall(ilGenerator);
 
5288
                                        }
 
5289
                                        else
 
5290
#endif
 
5291
                                        {
 
5292
                                                RegisterNestedTypeBuilder(EmitCreateCallerID(typeBuilder, ilGenerator));
 
5293
                                        }
 
5294
                                        ilGenerator.Emit(OpCodes.Stsfld, callerIDField);
 
5295
                                }
 
5296
                        }
 
5297
 
 
5298
                        internal static TypeBuilder EmitCreateCallerID(TypeBuilder typeBuilder, CodeEmitter ilGenerator)
 
5299
                        {
 
5300
                                TypeWrapper tw = CoreClasses.ikvm.@internal.CallerID.Wrapper;
 
5301
                                TypeBuilder typeCallerID = typeBuilder.DefineNestedType("__<CallerID>", TypeAttributes.Sealed | TypeAttributes.NestedPrivate, tw.TypeAsBaseType);
 
5302
                                MethodBuilder cb = ReflectUtil.DefineConstructor(typeCallerID, MethodAttributes.Assembly, null);
 
5303
                                CodeEmitter ctorIlgen = CodeEmitter.Create(cb);
 
5304
                                ctorIlgen.Emit(OpCodes.Ldarg_0);
 
5305
                                MethodWrapper mw = tw.GetMethodWrapper("<init>", "()V", false);
 
5306
                                mw.Link();
 
5307
                                mw.EmitCall(ctorIlgen);
 
5308
                                ctorIlgen.Emit(OpCodes.Ret);
 
5309
                                ctorIlgen.DoEmit();
 
5310
                                ilGenerator.Emit(OpCodes.Newobj, cb);
 
5311
                                return typeCallerID;
 
5312
                        }
 
5313
 
 
5314
                        private void EmitConstantValueInitialization(FieldWrapper[] fields, CodeEmitter ilGenerator)
 
5315
                        {
 
5316
                                ClassFile.Field[] flds = classFile.Fields;
 
5317
                                for (int i = 0; i < flds.Length; i++)
 
5318
                                {
 
5319
                                        ClassFile.Field f = flds[i];
 
5320
                                        if (f.IsStatic && !f.IsFinal)
 
5321
                                        {
 
5322
                                                object constant = f.ConstantValue;
 
5323
                                                if (constant != null)
 
5324
                                                {
 
5325
                                                        if (constant is int)
 
5326
                                                        {
 
5327
                                                                ilGenerator.EmitLdc_I4((int)constant);
 
5328
                                                        }
 
5329
                                                        else if (constant is bool)
 
5330
                                                        {
 
5331
                                                                ilGenerator.EmitLdc_I4((bool)constant ? 1 : 0);
 
5332
                                                        }
 
5333
                                                        else if (constant is byte)
 
5334
                                                        {
 
5335
                                                                ilGenerator.EmitLdc_I4((byte)constant);
 
5336
                                                        }
 
5337
                                                        else if (constant is char)
 
5338
                                                        {
 
5339
                                                                ilGenerator.EmitLdc_I4((char)constant);
 
5340
                                                        }
 
5341
                                                        else if (constant is short)
 
5342
                                                        {
 
5343
                                                                ilGenerator.EmitLdc_I4((short)constant);
 
5344
                                                        }
 
5345
                                                        else if (constant is long)
 
5346
                                                        {
 
5347
                                                                ilGenerator.EmitLdc_I8((long)constant);
 
5348
                                                        }
 
5349
                                                        else if (constant is double)
 
5350
                                                        {
 
5351
                                                                ilGenerator.EmitLdc_R8((double)constant);
 
5352
                                                        }
 
5353
                                                        else if (constant is float)
 
5354
                                                        {
 
5355
                                                                ilGenerator.EmitLdc_R4((float)constant);
 
5356
                                                        }
 
5357
                                                        else if (constant is string)
 
5358
                                                        {
 
5359
                                                                ilGenerator.Emit(OpCodes.Ldstr, (string)constant);
 
5360
                                                        }
 
5361
                                                        else
 
5362
                                                        {
 
5363
                                                                throw new InvalidOperationException();
 
5364
                                                        }
 
5365
                                                        fields[i].EmitSet(ilGenerator);
 
5366
                                                }
 
5367
                                        }
 
5368
                                }
 
5369
                        }
 
5370
 
 
5371
                        internal MethodBuilder DefineThreadLocalType()
 
5372
                        {
 
5373
                                TypeWrapper threadLocal = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal");
 
5374
                                int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count;
 
5375
                                TypeBuilder tb = typeBuilder.DefineNestedType("__<tls>_" + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType);
 
5376
                                FieldBuilder fb = tb.DefineField("field", Types.Object, FieldAttributes.Private | FieldAttributes.Static);
 
5377
                                fb.SetCustomAttribute(new CustomAttributeBuilder(JVM.Import(typeof(ThreadStaticAttribute)).GetConstructor(Type.EmptyTypes), new object[0]));
 
5378
                                MethodBuilder mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, Types.Object, Type.EmptyTypes);
 
5379
                                ILGenerator ilgen = mbGet.GetILGenerator();
 
5380
                                ilgen.Emit(OpCodes.Ldsfld, fb);
 
5381
                                ilgen.Emit(OpCodes.Ret);
 
5382
                                MethodBuilder mbSet = tb.DefineMethod("set", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, new Type[] { Types.Object });
 
5383
                                ilgen = mbSet.GetILGenerator();
 
5384
                                ilgen.Emit(OpCodes.Ldarg_1);
 
5385
                                ilgen.Emit(OpCodes.Stsfld, fb);
 
5386
                                ilgen.Emit(OpCodes.Ret);
 
5387
                                MethodBuilder cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, Type.EmptyTypes);
 
5388
                                CodeEmitter ctorilgen = CodeEmitter.Create(cb);
 
5389
                                ctorilgen.Emit(OpCodes.Ldarg_0);
 
5390
                                MethodWrapper basector = threadLocal.GetMethodWrapper("<init>", "()V", false);
 
5391
                                basector.Link();
 
5392
                                basector.EmitCall(ctorilgen);
 
5393
                                ctorilgen.Emit(OpCodes.Ret);
 
5394
                                ctorilgen.DoEmit();
 
5395
                                RegisterNestedTypeBuilder(tb);
 
5396
                                return cb;
 
5397
                        }
 
5398
 
 
5399
                        internal MethodBuilder GetAtomicReferenceFieldUpdater(FieldWrapper field)
 
5400
                        {
 
5401
                                if (arfuMap == null)
 
5402
                                {
 
5403
                                        arfuMap = new Dictionary<FieldWrapper, MethodBuilder>();
 
5404
                                }
 
5405
                                MethodBuilder cb;
 
5406
                                if (!arfuMap.TryGetValue(field, out cb))
 
5407
                                {
 
5408
                                        TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater");
 
5409
                                        TypeBuilder tb = typeBuilder.DefineNestedType("__<ARFU>_" + arfuMap.Count, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType);
 
5410
                                        AtomicReferenceFieldUpdaterEmitter.EmitImpl(tb, field.GetField());
 
5411
                                        cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, Type.EmptyTypes);
 
5412
                                        arfuMap.Add(field, cb);
 
5413
                                        CodeEmitter ctorilgen = CodeEmitter.Create(cb);
 
5414
                                        ctorilgen.Emit(OpCodes.Ldarg_0);
 
5415
                                        MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false);
 
5416
                                        basector.Link();
 
5417
                                        basector.EmitCall(ctorilgen);
 
5418
                                        ctorilgen.Emit(OpCodes.Ret);
 
5419
                                        ctorilgen.DoEmit();
 
5420
                                        RegisterNestedTypeBuilder(tb);
 
5421
                                }
 
5422
                                return cb;
 
5423
                        }
 
5424
 
 
5425
                        internal TypeBuilder DefineIndyCallSiteType()
 
5426
                        {
 
5427
                                int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count;
 
5428
                                TypeBuilder tb = typeBuilder.DefineNestedType("__<>IndyCS" + id, TypeAttributes.NestedPrivate | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit);
 
5429
                                RegisterNestedTypeBuilder(tb);
 
5430
                                return tb;
 
5431
                        }
 
5432
 
 
5433
                        internal TypeBuilder DefineMethodHandleConstantType(int index)
 
5434
                        {
 
5435
                                TypeBuilder tb = typeBuilder.DefineNestedType("__<>MHC" + index, TypeAttributes.NestedPrivate | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit); ;
 
5436
                                RegisterNestedTypeBuilder(tb);
 
5437
                                return tb;
 
5438
                        }
 
5439
 
 
5440
                        internal MethodBuilder DefineMethodHandleDispatchStub(Type returnType, Type[] parameterTypes)
 
5441
                        {
 
5442
                                return typeBuilder.DefineMethod("__<>MHC", MethodAttributes.Static | MethodAttributes.PrivateScope, returnType, parameterTypes);
 
5443
                        }
 
5444
 
 
5445
                        internal FieldBuilder DefineMethodHandleInvokeCacheField(Type fieldType)
 
5446
                        {
 
5447
                                return typeBuilder.DefineField("__<>invokeCache", fieldType, FieldAttributes.Static | FieldAttributes.PrivateScope);
 
5448
                        }
 
5449
 
 
5450
                        internal MethodBuilder DefineInvokeSpecialStub(DefineMethodHelper sig)
 
5451
                        {
 
5452
                                return sig.DefineMethod(wrapper, typeBuilder, "__<>", MethodAttributes.PrivateScope);
 
5453
                        }
 
5454
 
 
5455
                        internal MethodBuilder DefineDelegateInvokeErrorStub(Type returnType, Type[] parameterTypes)
 
5456
                        {
 
5457
                                return typeBuilder.DefineMethod("__<>", MethodAttributes.PrivateScope | MethodAttributes.Static, returnType, parameterTypes);
 
5458
                        }
 
5459
                }
 
5460
 
 
5461
                private static bool CheckRequireOverrideStub(MethodWrapper mw1, MethodWrapper mw2)
 
5462
                {
 
5463
                        // TODO this is too late to generate LinkageErrors so we need to figure this out earlier
 
5464
                        if (!TypesMatchForOverride(mw1.ReturnType, mw2.ReturnType))
 
5465
                        {
 
5466
                                return true;
 
5467
                        }
 
5468
                        TypeWrapper[] args1 = mw1.GetParameters();
 
5469
                        TypeWrapper[] args2 = mw2.GetParameters();
 
5470
                        for (int i = 0; i < args1.Length; i++)
 
5471
                        {
 
5472
                                if (!TypesMatchForOverride(args1[i], args2[i]))
 
5473
                                {
 
5474
                                        return true;
 
5475
                                }
 
5476
                        }
 
5477
                        return false;
 
5478
                }
 
5479
 
 
5480
                private static bool TypesMatchForOverride(TypeWrapper tw1, TypeWrapper tw2)
 
5481
                {
 
5482
                        if (tw1 == tw2)
 
5483
                        {
 
5484
                                return true;
 
5485
                        }
 
5486
                        else if (tw1.IsUnloadable && tw2.IsUnloadable)
 
5487
                        {
 
5488
                                return ((UnloadableTypeWrapper)tw1).CustomModifier == ((UnloadableTypeWrapper)tw2).CustomModifier;
 
5489
                        }
 
5490
                        else
 
5491
                        {
 
5492
                                return false;
 
5493
                        }
 
5494
                }
 
5495
 
 
5496
                private void GenerateOverrideStub(TypeBuilder typeBuilder, MethodWrapper baseMethod, MethodInfo target, MethodWrapper targetMethod)
 
5497
                {
 
5498
                        Debug.Assert(!baseMethod.HasCallerID);
 
5499
 
 
5500
                        MethodBuilder overrideStub = baseMethod.GetDefineMethodHelper().DefineMethod(this, typeBuilder, "__<overridestub>" + baseMethod.Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
 
5501
                        typeBuilder.DefineMethodOverride(overrideStub, (MethodInfo)baseMethod.GetMethod());
 
5502
 
 
5503
                        Type stubret = baseMethod.ReturnTypeForDefineMethod;
 
5504
                        Type[] stubargs = baseMethod.GetParametersForDefineMethod();
 
5505
                        Type targetRet = targetMethod.ReturnTypeForDefineMethod;
 
5506
                        Type[] targetArgs = targetMethod.GetParametersForDefineMethod();
 
5507
                        CodeEmitter ilgen = CodeEmitter.Create(overrideStub);
 
5508
                        ilgen.Emit(OpCodes.Ldarg_0);
 
5509
                        for (int i = 0; i < targetArgs.Length; i++)
 
5510
                        {
 
5511
                                ilgen.EmitLdarg(i + 1);
 
5512
                                if (targetArgs[i] != stubargs[i])
 
5513
                                {
 
5514
                                        ilgen.Emit(OpCodes.Castclass, targetArgs[i]);
 
5515
                                }
 
5516
                        }
 
5517
                        ilgen.Emit(OpCodes.Callvirt, target);
 
5518
                        if (targetRet != stubret)
 
5519
                        {
 
5520
                                ilgen.Emit(OpCodes.Castclass, stubret);
 
5521
                        }
 
5522
                        ilgen.Emit(OpCodes.Ret);
 
5523
                        ilgen.DoEmit();
 
5524
                }
 
5525
 
 
5526
                protected static void GetParameterNamesFromLVT(ClassFile.Method m, string[] parameterNames)
 
5527
                {
 
5528
                        ClassFile.Method.LocalVariableTableEntry[] localVars = m.LocalVariableTableAttribute;
 
5529
                        if (localVars != null)
 
5530
                        {
 
5531
                                for (int i = m.IsStatic ? 0 : 1, pos = 0; i < m.ArgMap.Length; i++)
 
5532
                                {
 
5533
                                        // skip double & long fillers
 
5534
                                        if (m.ArgMap[i] != -1)
 
5535
                                        {
 
5536
                                                if (parameterNames[pos] == null)
 
5537
                                                {
 
5538
                                                        for (int j = 0; j < localVars.Length; j++)
 
5539
                                                        {
 
5540
                                                                if (localVars[j].index == i)
 
5541
                                                                {
 
5542
                                                                        parameterNames[pos] = localVars[j].name;
 
5543
                                                                        break;
 
5544
                                                                }
 
5545
                                                        }
 
5546
                                                }
 
5547
                                                pos++;
 
5548
                                        }
 
5549
                                }
 
5550
                        }
 
5551
                }
 
5552
 
 
5553
                protected static void GetParameterNamesFromSig(string sig, string[] parameterNames)
 
5554
                {
 
5555
                        List<string> names = new List<string>();
 
5556
                        for (int i = 1; sig[i] != ')'; i++)
 
5557
                        {
 
5558
                                if (sig[i] == 'L')
 
5559
                                {
 
5560
                                        i++;
 
5561
                                        int end = sig.IndexOf(';', i);
 
5562
                                        names.Add(GetParameterName(sig.Substring(i, end - i)));
 
5563
                                        i = end;
 
5564
                                }
 
5565
                                else if (sig[i] == '[')
 
5566
                                {
 
5567
                                        while (sig[++i] == '[') ;
 
5568
                                        if (sig[i] == 'L')
 
5569
                                        {
 
5570
                                                i++;
 
5571
                                                int end = sig.IndexOf(';', i);
 
5572
                                                names.Add(GetParameterName(sig.Substring(i, end - i)) + "arr");
 
5573
                                                i = end;
 
5574
                                        }
 
5575
                                        else
 
5576
                                        {
 
5577
                                                switch (sig[i])
 
5578
                                                {
 
5579
                                                        case 'B':
 
5580
                                                        case 'Z':
 
5581
                                                                names.Add("barr");
 
5582
                                                                break;
 
5583
                                                        case 'C':
 
5584
                                                                names.Add("charr");
 
5585
                                                                break;
 
5586
                                                        case 'S':
 
5587
                                                                names.Add("sarr");
 
5588
                                                                break;
 
5589
                                                        case 'I':
 
5590
                                                                names.Add("iarr");
 
5591
                                                                break;
 
5592
                                                        case 'J':
 
5593
                                                                names.Add("larr");
 
5594
                                                                break;
 
5595
                                                        case 'F':
 
5596
                                                                names.Add("farr");
 
5597
                                                                break;
 
5598
                                                        case 'D':
 
5599
                                                                names.Add("darr");
 
5600
                                                                break;
 
5601
                                                }
 
5602
                                        }
 
5603
                                }
 
5604
                                else
 
5605
                                {
 
5606
                                        switch (sig[i])
 
5607
                                        {
 
5608
                                                case 'B':
 
5609
                                                case 'Z':
 
5610
                                                        names.Add("b");
 
5611
                                                        break;
 
5612
                                                case 'C':
 
5613
                                                        names.Add("ch");
 
5614
                                                        break;
 
5615
                                                case 'S':
 
5616
                                                        names.Add("s");
 
5617
                                                        break;
 
5618
                                                case 'I':
 
5619
                                                        names.Add("i");
 
5620
                                                        break;
 
5621
                                                case 'J':
 
5622
                                                        names.Add("l");
 
5623
                                                        break;
 
5624
                                                case 'F':
 
5625
                                                        names.Add("f");
 
5626
                                                        break;
 
5627
                                                case 'D':
 
5628
                                                        names.Add("d");
 
5629
                                                        break;
 
5630
                                        }
 
5631
                                }
 
5632
                        }
 
5633
                        for (int i = 0; i < parameterNames.Length; i++)
 
5634
                        {
 
5635
                                if (parameterNames[i] == null)
 
5636
                                {
 
5637
                                        parameterNames[i] = (string)names[i];
 
5638
                                }
 
5639
                        }
 
5640
                }
 
5641
 
 
5642
                protected static ParameterBuilder[] GetParameterBuilders(MethodBuilder mb, int parameterCount, string[] parameterNames)
 
5643
                {
 
5644
                        ParameterBuilder[] parameterBuilders = new ParameterBuilder[parameterCount];
 
5645
                        Dictionary<string, int> clashes = null;
 
5646
                        for (int i = 0; i < parameterBuilders.Length; i++)
 
5647
                        {
 
5648
                                string name = null;
 
5649
                                if (parameterNames != null)
 
5650
                                {
 
5651
                                        name = parameterNames[i];
 
5652
                                        if (Array.IndexOf(parameterNames, name, i + 1) >= 0 || (clashes != null && clashes.ContainsKey(name)))
 
5653
                                        {
 
5654
                                                if (clashes == null)
 
5655
                                                {
 
5656
                                                        clashes = new Dictionary<string, int>();
 
5657
                                                }
 
5658
                                                int clash = 1;
 
5659
                                                if (clashes.ContainsKey(name))
 
5660
                                                {
 
5661
                                                        clash = clashes[name] + 1;
 
5662
                                                }
 
5663
                                                clashes[name] = clash;
 
5664
                                                name += clash;
 
5665
                                        }
 
5666
                                }
 
5667
                                parameterBuilders[i] = mb.DefineParameter(i + 1, ParameterAttributes.None, name);
 
5668
                        }
 
5669
                        return parameterBuilders;
 
5670
                }
 
5671
 
 
5672
                private static string GetParameterName(string type)
 
5673
                {
 
5674
                        if (type == "java.lang.String")
 
5675
                        {
 
5676
                                return "str";
 
5677
                        }
 
5678
                        else if (type == "java.lang.Object")
 
5679
                        {
 
5680
                                return "obj";
 
5681
                        }
 
5682
                        else
 
5683
                        {
 
5684
                                System.Text.StringBuilder sb = new System.Text.StringBuilder();
 
5685
                                for (int i = type.LastIndexOf('.') + 1; i < type.Length; i++)
 
5686
                                {
 
5687
                                        if (char.IsUpper(type, i))
 
5688
                                        {
 
5689
                                                sb.Append(char.ToLower(type[i]));
 
5690
                                        }
 
5691
                                }
 
5692
                                return sb.ToString();
 
5693
                        }
 
5694
                }
 
5695
 
 
5696
#if STATIC_COMPILER
 
5697
                protected abstract void AddMapXmlFields(ref FieldWrapper[] fields);
 
5698
                protected abstract bool EmitMapXmlMethodPrologueAndOrBody(CodeEmitter ilgen, ClassFile f, ClassFile.Method m);
 
5699
                protected abstract void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, FieldWrapper[] fields, MethodWrapper[] methods);
 
5700
                protected abstract MethodBuilder DefineGhostMethod(string name, MethodAttributes attribs, MethodWrapper mw);
 
5701
                protected abstract void FinishGhost(TypeBuilder typeBuilder, MethodWrapper[] methods);
 
5702
                protected abstract void FinishGhostStep2();
 
5703
                protected abstract TypeBuilder DefineGhostType(string mangledTypeName, TypeAttributes typeAttribs);
 
5704
#endif // STATIC_COMPILER
 
5705
 
 
5706
                protected virtual bool IsPInvokeMethod(ClassFile.Method m)
 
5707
                {
 
5708
#if CLASSGC
 
5709
                        // TODO PInvoke is not supported in RunAndCollect assemblies,
 
5710
                        if (JVM.classUnloading)
 
5711
                        {
 
5712
                                return false;
 
5713
                        }
 
5714
#endif
 
5715
                        if (m.Annotations != null)
 
5716
                        {
 
5717
                                foreach (object[] annot in m.Annotations)
 
5718
                                {
 
5719
                                        if ("Lcli/System/Runtime/InteropServices/DllImportAttribute$Annotation;".Equals(annot[1]))
 
5720
                                        {
 
5721
                                                return true;
 
5722
                                        }
 
5723
                                }
 
5724
                        }
 
5725
                        return false;
 
5726
                }
 
5727
 
 
5728
                internal override MethodBase LinkMethod(MethodWrapper mw)
 
5729
                {
 
5730
                        mw.AssertLinked();
 
5731
                        return impl.LinkMethod(mw);
 
5732
                }
 
5733
 
 
5734
                internal override FieldInfo LinkField(FieldWrapper fw)
 
5735
                {
 
5736
                        fw.AssertLinked();
 
5737
                        return impl.LinkField(fw);
 
5738
                }
 
5739
 
 
5740
                internal override void EmitRunClassConstructor(CodeEmitter ilgen)
 
5741
                {
 
5742
                        impl.EmitRunClassConstructor(ilgen);
 
5743
                }
 
5744
 
 
5745
                internal override string GetGenericSignature()
 
5746
                {
 
5747
                        return impl.GetGenericSignature();
 
5748
                }
 
5749
 
 
5750
                internal override string GetGenericMethodSignature(MethodWrapper mw)
 
5751
                {
 
5752
                        MethodWrapper[] methods = GetMethods();
 
5753
                        for (int i = 0; i < methods.Length; i++)
 
5754
                        {
 
5755
                                if (methods[i] == mw)
 
5756
                                {
 
5757
                                        return impl.GetGenericMethodSignature(i);
 
5758
                                }
 
5759
                        }
 
5760
                        Debug.Fail("Unreachable code");
 
5761
                        return null;
 
5762
                }
 
5763
 
 
5764
                internal override string GetGenericFieldSignature(FieldWrapper fw)
 
5765
                {
 
5766
                        FieldWrapper[] fields = GetFields();
 
5767
                        for (int i = 0; i < fields.Length; i++)
 
5768
                        {
 
5769
                                if (fields[i] == fw)
 
5770
                                {
 
5771
                                        return impl.GetGenericFieldSignature(i);
 
5772
                                }
 
5773
                        }
 
5774
                        Debug.Fail("Unreachable code");
 
5775
                        return null;
 
5776
                }
 
5777
 
 
5778
#if !STATIC_COMPILER
 
5779
                internal override string[] GetEnclosingMethod()
 
5780
                {
 
5781
                        return impl.GetEnclosingMethod();
 
5782
                }
 
5783
 
 
5784
                internal override string GetSourceFileName()
 
5785
                {
 
5786
                        return sourceFileName;
 
5787
                }
 
5788
 
 
5789
                private int GetMethodBaseToken(MethodBase mb)
 
5790
                {
 
5791
                        ConstructorInfo ci = mb as ConstructorInfo;
 
5792
                        if (ci != null)
 
5793
                        {
 
5794
                                return classLoader.GetTypeWrapperFactory().ModuleBuilder.GetConstructorToken(ci).Token;
 
5795
                        }
 
5796
                        else
 
5797
                        {
 
5798
                                return classLoader.GetTypeWrapperFactory().ModuleBuilder.GetMethodToken((MethodInfo)mb).Token;
 
5799
                        }
 
5800
                }
 
5801
 
 
5802
                internal override int GetSourceLineNumber(MethodBase mb, int ilOffset)
 
5803
                {
 
5804
                        if (lineNumberTables != null)
 
5805
                        {
 
5806
                                int token = GetMethodBaseToken(mb);
 
5807
                                MethodWrapper[] methods = GetMethods();
 
5808
                                for (int i = 0; i < methods.Length; i++)
 
5809
                                {
 
5810
                                        if (GetMethodBaseToken(methods[i].GetMethod()) == token)
 
5811
                                        {
 
5812
                                                if (lineNumberTables[i] != null)
 
5813
                                                {
 
5814
                                                        return new LineNumberTableAttribute(lineNumberTables[i]).GetLineNumber(ilOffset);
 
5815
                                                }
 
5816
                                                break;
 
5817
                                        }
 
5818
                                }
 
5819
                        }
 
5820
                        return -1;
 
5821
                }
 
5822
 
 
5823
                internal override object[] GetDeclaredAnnotations()
 
5824
                {
 
5825
                        object[] annotations = impl.GetDeclaredAnnotations();
 
5826
                        if (annotations != null)
 
5827
                        {
 
5828
                                object[] objs = new object[annotations.Length];
 
5829
                                for (int i = 0; i < annotations.Length; i++)
 
5830
                                {
 
5831
                                        objs[i] = JVM.NewAnnotation(GetClassLoader().GetJavaClassLoader(), annotations[i]);
 
5832
                                }
 
5833
                                return objs;
 
5834
                        }
 
5835
                        return null;
 
5836
                }
 
5837
 
 
5838
                internal override object[] GetMethodAnnotations(MethodWrapper mw)
 
5839
                {
 
5840
                        MethodWrapper[] methods = GetMethods();
 
5841
                        for (int i = 0; i < methods.Length; i++)
 
5842
                        {
 
5843
                                if (methods[i] == mw)
 
5844
                                {
 
5845
                                        object[] annotations = impl.GetMethodAnnotations(i);
 
5846
                                        if (annotations != null)
 
5847
                                        {
 
5848
                                                object[] objs = new object[annotations.Length];
 
5849
                                                for (int j = 0; j < annotations.Length; j++)
 
5850
                                                {
 
5851
                                                        objs[j] = JVM.NewAnnotation(GetClassLoader().GetJavaClassLoader(), annotations[j]);
 
5852
                                                }
 
5853
                                                return objs;
 
5854
                                        }
 
5855
                                        return null;
 
5856
                                }
 
5857
                        }
 
5858
                        Debug.Fail("Unreachable code");
 
5859
                        return null;
 
5860
                }
 
5861
 
 
5862
                internal override object[][] GetParameterAnnotations(MethodWrapper mw)
 
5863
                {
 
5864
                        MethodWrapper[] methods = GetMethods();
 
5865
                        for (int i = 0; i < methods.Length; i++)
 
5866
                        {
 
5867
                                if (methods[i] == mw)
 
5868
                                {
 
5869
                                        object[][] annotations = impl.GetParameterAnnotations(i);
 
5870
                                        if (annotations != null)
 
5871
                                        {
 
5872
                                                object[][] objs = new object[annotations.Length][];
 
5873
                                                for (int j = 0; j < annotations.Length; j++)
 
5874
                                                {
 
5875
                                                        objs[j] = new object[annotations[j].Length];
 
5876
                                                        for (int k = 0; k < annotations[j].Length; k++)
 
5877
                                                        {
 
5878
                                                                objs[j][k] = JVM.NewAnnotation(GetClassLoader().GetJavaClassLoader(), annotations[j][k]);
 
5879
                                                        }
 
5880
                                                }
 
5881
                                                return objs;
 
5882
                                        }
 
5883
                                        return null;
 
5884
                                }
 
5885
                        }
 
5886
                        Debug.Fail("Unreachable code");
 
5887
                        return null;
 
5888
                }
 
5889
 
 
5890
                internal override object[] GetFieldAnnotations(FieldWrapper fw)
 
5891
                {
 
5892
                        FieldWrapper[] fields = GetFields();
 
5893
                        for (int i = 0; i < fields.Length; i++)
 
5894
                        {
 
5895
                                if (fields[i] == fw)
 
5896
                                {
 
5897
                                        object[] annotations = impl.GetFieldAnnotations(i);
 
5898
                                        if (annotations != null)
 
5899
                                        {
 
5900
                                                object[] objs = new object[annotations.Length];
 
5901
                                                for (int j = 0; j < annotations.Length; j++)
 
5902
                                                {
 
5903
                                                        objs[j] = JVM.NewAnnotation(GetClassLoader().GetJavaClassLoader(), annotations[j]);
 
5904
                                                }
 
5905
                                                return objs;
 
5906
                                        }
 
5907
                                        return null;
 
5908
                                }
 
5909
                        }
 
5910
                        Debug.Fail("Unreachable code");
 
5911
                        return null;
 
5912
                }
 
5913
 
 
5914
                internal override object GetAnnotationDefault(MethodWrapper mw)
 
5915
                {
 
5916
                        MethodWrapper[] methods = GetMethods();
 
5917
                        for (int i = 0; i < methods.Length; i++)
 
5918
                        {
 
5919
                                if (methods[i] == mw)
 
5920
                                {
 
5921
                                        object defVal = impl.GetMethodDefaultValue(i);
 
5922
                                        if (defVal != null)
 
5923
                                        {
 
5924
                                                return JVM.NewAnnotationElementValue(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), mw.ReturnType.ClassObject, defVal);
 
5925
                                        }
 
5926
                                        return null;
 
5927
                                }
 
5928
                        }
 
5929
                        Debug.Fail("Unreachable code");
 
5930
                        return null;
 
5931
                }
 
5932
#endif
 
5933
 
 
5934
                protected virtual Type GetBaseTypeForDefineType()
 
5935
                {
 
5936
                        return BaseTypeWrapper.TypeAsBaseType;
 
5937
                }
 
5938
 
 
5939
#if STATIC_COMPILER
 
5940
                internal virtual MethodWrapper[] GetReplacedMethodsFor(MethodWrapper mw)
 
5941
                {
 
5942
                        return null;
 
5943
                }
 
5944
#endif // STATIC_COMPILER
 
5945
 
 
5946
                internal override MethodBase GetSerializationConstructor()
 
5947
                {
 
5948
                        return automagicSerializationCtor;
 
5949
                }
 
5950
 
 
5951
                private Type[] GetModOpt(TypeWrapper tw, bool mustBePublic)
 
5952
                {
 
5953
                        return GetModOpt(GetClassLoader().GetTypeWrapperFactory(), tw, mustBePublic);
 
5954
                }
 
5955
 
 
5956
                internal static Type[] GetModOpt(TypeWrapperFactory context, TypeWrapper tw, bool mustBePublic)
 
5957
                {
 
5958
                        Type[] modopt = Type.EmptyTypes;
 
5959
                        if (tw.IsUnloadable)
 
5960
                        {
 
5961
                                modopt = new Type[] { ((UnloadableTypeWrapper)tw).GetCustomModifier(context) };
 
5962
                        }
 
5963
                        else
 
5964
                        {
 
5965
                                TypeWrapper tw1 = tw.IsArray ? tw.GetUltimateElementTypeWrapper() : tw;
 
5966
                                if (tw1.IsErasedOrBoxedPrimitiveOrRemapped || tw.IsGhostArray || (mustBePublic && !tw1.IsPublic))
 
5967
                                {
 
5968
                                        // FXBUG Ref.Emit refuses arrays in custom modifiers, so we add an array type for each dimension
 
5969
                                        modopt = new Type[tw.ArrayRank + 1];
 
5970
                                        modopt[0] = GetModOptHelper(tw1);
 
5971
                                        for (int i = 1; i < modopt.Length; i++)
 
5972
                                        {
 
5973
                                                modopt[i] = Types.Array;
 
5974
                                        }
 
5975
                                }
 
5976
                        }
 
5977
                        return modopt;
 
5978
                }
 
5979
 
 
5980
                private static Type GetModOptHelper(TypeWrapper tw)
 
5981
                {
 
5982
                        Debug.Assert(!tw.IsUnloadable);
 
5983
                        if (tw.IsArray)
 
5984
                        {
 
5985
                                return ArrayTypeWrapper.MakeArrayType(GetModOptHelper(tw.GetUltimateElementTypeWrapper()), tw.ArrayRank);
 
5986
                        }
 
5987
                        else if (tw.IsGhost)
 
5988
                        {
 
5989
                                return tw.TypeAsTBD;
 
5990
                        }
 
5991
                        else
 
5992
                        {
 
5993
                                return tw.TypeAsBaseType;
 
5994
                        }
 
5995
                }
 
5996
 
 
5997
#if STATIC_COMPILER
 
5998
                private bool NeedsType2AccessStub(FieldWrapper fw)
 
5999
                {
 
6000
                        Debug.Assert(this.IsPublic && fw.DeclaringType == this);
 
6001
                        return fw.IsType2FinalField
 
6002
                                || (fw.HasNonPublicTypeInSignature
 
6003
                                        && (fw.IsPublic || (fw.IsProtected && !this.IsFinal))
 
6004
                                        && (fw.FieldTypeWrapper.IsUnloadable || fw.FieldTypeWrapper.IsAccessibleFrom(this) || fw.FieldTypeWrapper.InternalsVisibleTo(this)));
 
6005
                }
 
6006
#endif
 
6007
        }
 
6008
 
 
6009
        sealed class DefineMethodHelper
 
6010
        {
 
6011
                private readonly MethodWrapper mw;
 
6012
 
 
6013
                internal DefineMethodHelper(MethodWrapper mw)
 
6014
                {
 
6015
                        this.mw = mw;
 
6016
                }
 
6017
 
 
6018
                internal int ParameterCount
 
6019
                {
 
6020
                        get { return mw.GetParameters().Length + (mw.HasCallerID ? 1 : 0); }
 
6021
                }
 
6022
 
 
6023
                internal MethodBuilder DefineMethod(DynamicTypeWrapper context, TypeBuilder tb, string name, MethodAttributes attribs)
 
6024
                {
 
6025
                        return DefineMethod(context.GetClassLoader().GetTypeWrapperFactory(), tb, name, attribs);
 
6026
                }
 
6027
 
 
6028
                internal MethodBuilder DefineMethod(TypeWrapperFactory context, TypeBuilder tb, string name, MethodAttributes attribs)
 
6029
                {
 
6030
                        // we add optional modifiers to make the signature unique
 
6031
                        TypeWrapper[] parameters = mw.GetParameters();
 
6032
                        Type[] parameterTypes = new Type[parameters.Length + (mw.HasCallerID ? 1 : 0)];
 
6033
                        Type[][] modopt = new Type[parameterTypes.Length][];
 
6034
                        for (int i = 0; i < parameters.Length; i++)
 
6035
                        {
 
6036
                                parameterTypes[i] = parameters[i].TypeAsSignatureType;
 
6037
                                modopt[i] = DynamicTypeWrapper.GetModOpt(context, parameters[i], false);
 
6038
                        }
 
6039
                        if (mw.HasCallerID)
 
6040
                        {
 
6041
                                parameterTypes[parameterTypes.Length - 1] = CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType;
 
6042
                        }
 
6043
                        Type[] modoptReturnType = DynamicTypeWrapper.GetModOpt(context, mw.ReturnType, false);
 
6044
                        return tb.DefineMethod(name, attribs, CallingConventions.Standard, mw.ReturnType.TypeAsSignatureType, null, modoptReturnType, parameterTypes, null, modopt);
 
6045
                }
 
6046
 
 
6047
                internal MethodBuilder DefineConstructor(DynamicTypeWrapper context, TypeBuilder tb, MethodAttributes attribs)
 
6048
                {
 
6049
                        return DefineConstructor(context.GetClassLoader().GetTypeWrapperFactory(), tb, attribs);
 
6050
                }
 
6051
 
 
6052
                internal MethodBuilder DefineConstructor(TypeWrapperFactory context, TypeBuilder tb, MethodAttributes attribs)
 
6053
                {
 
6054
                        return DefineMethod(context, tb, ConstructorInfo.ConstructorName, attribs | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
 
6055
                }
 
6056
        }
 
6057
}