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

« back to all changes in this revision

Viewing changes to external/ikvm/ikvmc/Proxy.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) 2011 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
using IKVM.Reflection;
 
27
using IKVM.Reflection.Emit;
 
28
using Type = IKVM.Reflection.Type;
 
29
 
 
30
namespace IKVM.Internal
 
31
{
 
32
        static class ProxyGenerator
 
33
        {
 
34
                private static readonly TypeWrapper proxyClass;
 
35
                private static readonly TypeWrapper errorClass;
 
36
                private static readonly TypeWrapper runtimeExceptionClass;
 
37
                private static readonly MethodWrapper undeclaredThrowableExceptionConstructor;
 
38
                private static readonly FieldWrapper invocationHandlerField;
 
39
                private static readonly TypeWrapper javaLangReflectMethod;
 
40
                private static readonly TypeWrapper javaLangNoSuchMethodException;
 
41
                private static readonly MethodWrapper javaLangNoClassDefFoundErrorConstructor;
 
42
                private static readonly MethodWrapper javaLangThrowable_getMessage;
 
43
                private static readonly MethodWrapper javaLangClass_getMethod;
 
44
                private static readonly TypeWrapper invocationHandlerClass;
 
45
                private static readonly MethodWrapper invokeMethod;
 
46
                private static readonly MethodWrapper proxyConstructor;
 
47
                private static readonly MethodWrapper hashCodeMethod;
 
48
                private static readonly MethodWrapper equalsMethod;
 
49
                private static readonly MethodWrapper toStringMethod;
 
50
 
 
51
                static ProxyGenerator()
 
52
                {
 
53
                        ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader();
 
54
                        proxyClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.Proxy");
 
55
                        errorClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.Error");
 
56
                        runtimeExceptionClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.RuntimeException");
 
57
                        undeclaredThrowableExceptionConstructor = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.UndeclaredThrowableException").GetMethodWrapper("<init>", "(Ljava.lang.Throwable;)V", false);
 
58
                        undeclaredThrowableExceptionConstructor.Link();
 
59
                        invocationHandlerField = proxyClass.GetFieldWrapper("h", "Ljava.lang.reflect.InvocationHandler;");
 
60
                        invocationHandlerField.Link();
 
61
                        javaLangReflectMethod = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.Method");
 
62
                        javaLangNoSuchMethodException = bootClassLoader.LoadClassByDottedNameFast("java.lang.NoSuchMethodException");
 
63
                        javaLangNoClassDefFoundErrorConstructor = bootClassLoader.LoadClassByDottedNameFast("java.lang.NoClassDefFoundError").GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false);
 
64
                        javaLangNoClassDefFoundErrorConstructor.Link();
 
65
                        javaLangThrowable_getMessage = bootClassLoader.LoadClassByDottedNameFast("java.lang.Throwable").GetMethodWrapper("getMessage", "()Ljava.lang.String;", false);
 
66
                        javaLangThrowable_getMessage.Link();
 
67
                        javaLangClass_getMethod = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("getMethod", "(Ljava.lang.String;[Ljava.lang.Class;)Ljava.lang.reflect.Method;", false);
 
68
                        javaLangClass_getMethod.Link();
 
69
                        invocationHandlerClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.InvocationHandler");
 
70
                        invokeMethod = invocationHandlerClass.GetMethodWrapper("invoke", "(Ljava.lang.Object;Ljava.lang.reflect.Method;[Ljava.lang.Object;)Ljava.lang.Object;", false);
 
71
                        proxyConstructor = proxyClass.GetMethodWrapper("<init>", "(Ljava.lang.reflect.InvocationHandler;)V", false);
 
72
                        proxyConstructor.Link();
 
73
                        hashCodeMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("hashCode", "()I", false);
 
74
                        equalsMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("equals", "(Ljava.lang.Object;)Z", false);
 
75
                        toStringMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("toString", "()Ljava.lang.String;", false);
 
76
                }
 
77
 
 
78
                internal static void Create(CompilerClassLoader loader, string proxy)
 
79
                {
 
80
                        string[] interfaces = proxy.Split(',');
 
81
                        TypeWrapper[] wrappers = new TypeWrapper[interfaces.Length];
 
82
                        for (int i = 0; i < interfaces.Length; i++)
 
83
                        {
 
84
                                try
 
85
                                {
 
86
                                        wrappers[i] = loader.LoadClassByDottedNameFast(interfaces[i]);
 
87
                                }
 
88
                                catch (RetargetableJavaException)
 
89
                                {
 
90
                                }
 
91
                                if (wrappers[i] == null)
 
92
                                {
 
93
                                        StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, "unable to load interface " + interfaces[i]);
 
94
                                        return;
 
95
                                }
 
96
                        }
 
97
                        Create(loader, proxy, wrappers);
 
98
                }
 
99
 
 
100
                private static void Create(CompilerClassLoader loader, string proxy, TypeWrapper[] interfaces)
 
101
                {
 
102
                        List<ProxyMethod> methods;
 
103
                        try
 
104
                        {
 
105
                                methods = CheckAndCollect(loader, interfaces);
 
106
                        }
 
107
                        catch (RetargetableJavaException x)
 
108
                        {
 
109
                                StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message);
 
110
                                return;
 
111
                        }
 
112
                        catch (ProxyException x)
 
113
                        {
 
114
                                StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message);
 
115
                                return;
 
116
                        }
 
117
                        CreateNoFail(loader, interfaces, methods);
 
118
                }
 
119
 
 
120
                private static List<ProxyMethod> CheckAndCollect(CompilerClassLoader loader, TypeWrapper[] interfaces)
 
121
                {
 
122
                        List<MethodWrapper> methods = new List<MethodWrapper>();
 
123
 
 
124
                        // The java.lang.Object methods precede any interface methods.
 
125
                        methods.Add(equalsMethod);
 
126
                        methods.Add(hashCodeMethod);
 
127
                        methods.Add(toStringMethod);
 
128
 
 
129
                        // Add the interfaces methods in order.
 
130
                        foreach (TypeWrapper tw in interfaces)
 
131
                        {
 
132
                                if (!tw.IsInterface)
 
133
                                {
 
134
                                        throw new ProxyException(tw.Name + " is not an interface");
 
135
                                }
 
136
                                if (tw.IsRemapped)
 
137
                                {
 
138
                                        // TODO handle java.lang.Comparable
 
139
                                        throw new ProxyException(tw.Name + " is a remapped interface (not currently supported)");
 
140
                                }
 
141
                                foreach (MethodWrapper mw in GetInterfaceMethods(tw))
 
142
                                {
 
143
                                        // Check for duplicates
 
144
                                        if (!MethodExists(methods, mw))
 
145
                                        {
 
146
                                                methods.Add(mw);
 
147
                                        }
 
148
                                }
 
149
                        }
 
150
 
 
151
                        // TODO verify restrictions
 
152
 
 
153
                        // Collect declared exceptions.
 
154
                        Dictionary<string, TypeWrapper[]> exceptions = new Dictionary<string, TypeWrapper[]>();
 
155
                        foreach (MethodWrapper mw in methods)
 
156
                        {
 
157
                                Add(loader, exceptions, mw);
 
158
                        }
 
159
 
 
160
                        // Build the definitive proxy method list.
 
161
                        List<ProxyMethod> proxyMethods = new List<ProxyMethod>();
 
162
                        foreach (MethodWrapper mw in methods)
 
163
                        {
 
164
                                proxyMethods.Add(new ProxyMethod(mw, exceptions[mw.Signature]));
 
165
                        }
 
166
                        return proxyMethods;
 
167
                }
 
168
 
 
169
                private static bool MethodExists(List<MethodWrapper> methods, MethodWrapper mw)
 
170
                {
 
171
                        foreach (MethodWrapper mw1 in methods)
 
172
                        {
 
173
                                // TODO what do we do with differing return types?
 
174
                                if (mw1.Name == mw.Name && mw1.Signature == mw.Signature)
 
175
                                {
 
176
                                        return true;
 
177
                                }
 
178
                        }
 
179
                        return false;
 
180
                }
 
181
 
 
182
                private static void Add(CompilerClassLoader loader, Dictionary<string, TypeWrapper[]> exceptions, MethodWrapper mw)
 
183
                {
 
184
                        string signature = mw.Signature;
 
185
                        TypeWrapper[] newExceptionTypes = LoadTypes(loader, mw.GetDeclaredExceptions());
 
186
                        TypeWrapper[] curExceptionTypes;
 
187
                        if (exceptions.TryGetValue(signature, out curExceptionTypes))
 
188
                        {
 
189
                                exceptions[signature] = Merge(newExceptionTypes, curExceptionTypes);
 
190
                        }
 
191
                        else
 
192
                        {
 
193
                                exceptions.Add(signature, newExceptionTypes);
 
194
                        }
 
195
                }
 
196
 
 
197
                private static TypeWrapper[] Merge(TypeWrapper[] newExceptionTypes, TypeWrapper[] curExceptionTypes)
 
198
                {
 
199
                        List<TypeWrapper> list = new List<TypeWrapper>();
 
200
                        foreach (TypeWrapper twNew in newExceptionTypes)
 
201
                        {
 
202
                                TypeWrapper match = null;
 
203
                                foreach (TypeWrapper twCur in curExceptionTypes)
 
204
                                {
 
205
                                        if (twNew.IsAssignableTo(twCur))
 
206
                                        {
 
207
                                                if (match == null || twCur.IsAssignableTo(match))
 
208
                                                {
 
209
                                                        match = twCur;
 
210
                                                }
 
211
                                        }
 
212
                                }
 
213
                                if (match != null && !list.Contains(match))
 
214
                                {
 
215
                                        list.Add(match);
 
216
                                }
 
217
                        }
 
218
                        return list.ToArray();
 
219
                }
 
220
 
 
221
                private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods)
 
222
                {
 
223
                        DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory();
 
224
                        TypeBuilder tb = factory.DefineProxy(proxyClass, interfaces);
 
225
                        AttributeHelper.SetImplementsAttribute(tb, interfaces);
 
226
                        CreateConstructor(tb);
 
227
                        for (int i = 0; i < methods.Count; i++)
 
228
                        {
 
229
                                methods[i].fb = tb.DefineField("m" + i, javaLangReflectMethod.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static);
 
230
                        }
 
231
                        foreach (ProxyMethod method in methods)
 
232
                        {
 
233
                                CreateMethod(loader, tb, method);
 
234
                        }
 
235
                        CreateStaticInitializer(tb, methods);
 
236
                }
 
237
 
 
238
                private static void CreateConstructor(TypeBuilder tb)
 
239
                {
 
240
                        CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Public, new Type[] { invocationHandlerClass.TypeAsSignatureType }));
 
241
                        ilgen.Emit(OpCodes.Ldarg_0);
 
242
                        ilgen.Emit(OpCodes.Ldarg_1);
 
243
                        proxyConstructor.EmitCall(ilgen);
 
244
                        ilgen.Emit(OpCodes.Ret);
 
245
                        ilgen.DoEmit();
 
246
                }
 
247
 
 
248
                private static void CreateMethod(CompilerClassLoader loader, TypeBuilder tb, ProxyMethod pm)
 
249
                {
 
250
                        MethodBuilder mb = pm.mw.GetDefineMethodHelper().DefineMethod(loader.GetTypeWrapperFactory(), tb, pm.mw.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final);
 
251
                        List<string> exceptions = new List<string>();
 
252
                        foreach (TypeWrapper tw in pm.exceptions)
 
253
                        {
 
254
                                exceptions.Add(tw.Name);
 
255
                        }
 
256
                        AttributeHelper.SetThrowsAttribute(mb, exceptions.ToArray());
 
257
                        CodeEmitter ilgen = CodeEmitter.Create(mb);
 
258
                        ilgen.BeginExceptionBlock();
 
259
                        ilgen.Emit(OpCodes.Ldarg_0);
 
260
                        invocationHandlerField.EmitGet(ilgen);
 
261
                        ilgen.Emit(OpCodes.Ldarg_0);
 
262
                        ilgen.Emit(OpCodes.Ldsfld, pm.fb);
 
263
                        TypeWrapper[] parameters = pm.mw.GetParameters();
 
264
                        if (parameters.Length == 0)
 
265
                        {
 
266
                                ilgen.Emit(OpCodes.Ldnull);
 
267
                        }
 
268
                        else
 
269
                        {
 
270
                                ilgen.EmitLdc_I4(parameters.Length);
 
271
                                ilgen.Emit(OpCodes.Newarr, Types.Object);
 
272
                                for (int i = 0; i < parameters.Length; i++)
 
273
                                {
 
274
                                        ilgen.Emit(OpCodes.Dup);
 
275
                                        ilgen.EmitLdc_I4(i);
 
276
                                        ilgen.EmitLdarg(i);
 
277
                                        if (parameters[i].IsNonPrimitiveValueType)
 
278
                                        {
 
279
                                                parameters[i].EmitBox(ilgen);
 
280
                                        }
 
281
                                        else if (parameters[i].IsPrimitive)
 
282
                                        {
 
283
                                                Boxer.EmitBox(ilgen, parameters[i]);
 
284
                                        }
 
285
                                        ilgen.Emit(OpCodes.Stelem_Ref);
 
286
                                }
 
287
                        }
 
288
                        invokeMethod.EmitCallvirt(ilgen);
 
289
                        TypeWrapper returnType = pm.mw.ReturnType;
 
290
                        CodeEmitterLocal returnValue = null;
 
291
                        if (returnType != PrimitiveTypeWrapper.VOID)
 
292
                        {
 
293
                                returnValue = ilgen.DeclareLocal(returnType.TypeAsSignatureType);
 
294
                                if (returnType.IsNonPrimitiveValueType)
 
295
                                {
 
296
                                        returnType.EmitUnbox(ilgen);
 
297
                                }
 
298
                                else if (returnType.IsPrimitive)
 
299
                                {
 
300
                                        Boxer.EmitUnbox(ilgen, returnType);
 
301
                                }
 
302
                                else if (returnType != CoreClasses.java.lang.Object.Wrapper)
 
303
                                {
 
304
                                        ilgen.EmitCastclass(returnType.TypeAsSignatureType);
 
305
                                }
 
306
                                ilgen.Emit(OpCodes.Stloc, returnValue);
 
307
                        }
 
308
                        CodeEmitterLabel returnLabel = ilgen.DefineLabel();
 
309
                        ilgen.EmitLeave(returnLabel);
 
310
                        // TODO consider using a filter here (but we would need to add filter support to CodeEmitter)
 
311
                        ilgen.BeginCatchBlock(Types.Exception);
 
312
                        ilgen.EmitLdc_I4(0);
 
313
                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.mapException.MakeGenericMethod(Types.Exception));
 
314
                        CodeEmitterLocal exception = ilgen.DeclareLocal(Types.Exception);
 
315
                        ilgen.Emit(OpCodes.Stloc, exception);
 
316
                        CodeEmitterLabel rethrow = ilgen.DefineLabel();
 
317
                        ilgen.Emit(OpCodes.Ldloc, exception);
 
318
                        errorClass.EmitInstanceOf(null, ilgen);
 
319
                        ilgen.EmitBrtrue(rethrow);
 
320
                        ilgen.Emit(OpCodes.Ldloc, exception);
 
321
                        runtimeExceptionClass.EmitInstanceOf(null, ilgen);
 
322
                        ilgen.EmitBrtrue(rethrow);
 
323
                        foreach (TypeWrapper tw in pm.exceptions)
 
324
                        {
 
325
                                ilgen.Emit(OpCodes.Ldloc, exception);
 
326
                                tw.EmitInstanceOf(null, ilgen);
 
327
                                ilgen.EmitBrtrue(rethrow);
 
328
                        }
 
329
                        ilgen.Emit(OpCodes.Ldloc, exception);
 
330
                        undeclaredThrowableExceptionConstructor.EmitNewobj(ilgen);
 
331
                        ilgen.Emit(OpCodes.Throw);
 
332
                        ilgen.MarkLabel(rethrow);
 
333
                        ilgen.Emit(OpCodes.Rethrow);
 
334
                        ilgen.EndExceptionBlock();
 
335
                        ilgen.MarkLabel(returnLabel);
 
336
                        if (returnValue != null)
 
337
                        {
 
338
                                ilgen.Emit(OpCodes.Ldloc, returnValue);
 
339
                        }
 
340
                        ilgen.Emit(OpCodes.Ret);
 
341
                        ilgen.DoEmit();
 
342
                }
 
343
 
 
344
                private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> methods)
 
345
                {
 
346
                        CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb));
 
347
                        CodeEmitterLocal callerID = ilgen.DeclareLocal(CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType);
 
348
                        TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen);
 
349
                        ilgen.Emit(OpCodes.Stloc, callerID);
 
350
                        // HACK we shouldn't create the nested type here (the outer type must be created first)
 
351
                        tbCallerID.CreateType();
 
352
                        ilgen.BeginExceptionBlock();
 
353
                        foreach (ProxyMethod method in methods)
 
354
                        {
 
355
                                method.mw.DeclaringType.EmitClassLiteral(ilgen);
 
356
                                ilgen.Emit(OpCodes.Ldstr, method.mw.Name);
 
357
                                TypeWrapper[] parameters = method.mw.GetParameters();
 
358
                                ilgen.EmitLdc_I4(parameters.Length);
 
359
                                ilgen.Emit(OpCodes.Newarr, CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
 
360
                                for (int i = 0; i < parameters.Length; i++)
 
361
                                {
 
362
                                        ilgen.Emit(OpCodes.Dup);
 
363
                                        ilgen.EmitLdc_I4(i);
 
364
                                        parameters[i].EmitClassLiteral(ilgen);
 
365
                                        ilgen.Emit(OpCodes.Stelem_Ref);
 
366
                                }
 
367
                                if (javaLangClass_getMethod.HasCallerID)
 
368
                                {
 
369
                                        ilgen.Emit(OpCodes.Ldloc, callerID);
 
370
                                }
 
371
                                javaLangClass_getMethod.EmitCallvirt(ilgen);
 
372
                                ilgen.Emit(OpCodes.Stsfld, method.fb);
 
373
                        }
 
374
                        CodeEmitterLabel label = ilgen.DefineLabel();
 
375
                        ilgen.EmitLeave(label);
 
376
                        ilgen.BeginCatchBlock(javaLangNoSuchMethodException.TypeAsExceptionType);
 
377
                        javaLangThrowable_getMessage.EmitCallvirt(ilgen);
 
378
                        javaLangNoClassDefFoundErrorConstructor.EmitNewobj(ilgen);
 
379
                        ilgen.Emit(OpCodes.Throw);
 
380
                        ilgen.EndExceptionBlock();
 
381
                        ilgen.MarkLabel(label);
 
382
                        ilgen.Emit(OpCodes.Ret);
 
383
                        ilgen.DoEmit();
 
384
                }
 
385
 
 
386
                private sealed class ProxyMethod
 
387
                {
 
388
                        internal readonly MethodWrapper mw;
 
389
                        internal readonly TypeWrapper[] exceptions;
 
390
                        internal FieldBuilder fb;
 
391
 
 
392
                        internal ProxyMethod(MethodWrapper mw, TypeWrapper[] exceptions)
 
393
                        {
 
394
                                this.mw = mw;
 
395
                                this.exceptions = exceptions;
 
396
                        }
 
397
                }
 
398
 
 
399
                private static IEnumerable<MethodWrapper> GetInterfaceMethods(TypeWrapper tw)
 
400
                {
 
401
                        Dictionary<string, MethodWrapper> methods = new Dictionary<string, MethodWrapper>();
 
402
                        foreach (MethodWrapper mw in tw.GetMethods())
 
403
                        {
 
404
                                methods.Add(mw.Name + mw.Signature, mw);
 
405
                        }
 
406
                        foreach (TypeWrapper iface in tw.Interfaces)
 
407
                        {
 
408
                                foreach (MethodWrapper mw in GetInterfaceMethods(iface))
 
409
                                {
 
410
                                        if (!methods.ContainsKey(mw.Name + mw.Signature))
 
411
                                        {
 
412
                                                methods.Add(mw.Name + mw.Signature, mw);
 
413
                                        }
 
414
                                }
 
415
                        }
 
416
                        return methods.Values;
 
417
                }
 
418
 
 
419
                private static TypeWrapper[] LoadTypes(ClassLoaderWrapper loader, string[] classes)
 
420
                {
 
421
                        if (classes == null || classes.Length == 0)
 
422
                        {
 
423
                                return TypeWrapper.EmptyArray;
 
424
                        }
 
425
                        TypeWrapper[] tw = new TypeWrapper[classes.Length];
 
426
                        for (int i = 0; i < tw.Length; i++)
 
427
                        {
 
428
                                tw[i] = loader.LoadClassByDottedName(classes[i]);
 
429
                        }
 
430
                        return tw;
 
431
                }
 
432
 
 
433
                private sealed class ProxyException : Exception
 
434
                {
 
435
                        internal ProxyException(string msg)
 
436
                                : base(msg)
 
437
                        {
 
438
                        }
 
439
                }
 
440
        }
 
441
 
 
442
        static class Boxer
 
443
        {
 
444
                private static readonly TypeWrapper javaLangByte;
 
445
                private static readonly MethodWrapper byteValue;
 
446
                private static readonly MethodWrapper valueOfByte;
 
447
                private static readonly TypeWrapper javaLangBoolean;
 
448
                private static readonly MethodWrapper booleanValue;
 
449
                private static readonly MethodWrapper valueOfBoolean;
 
450
                private static readonly TypeWrapper javaLangShort;
 
451
                private static readonly MethodWrapper shortValue;
 
452
                private static readonly MethodWrapper valueOfShort;
 
453
                private static readonly TypeWrapper javaLangCharacter;
 
454
                private static readonly MethodWrapper charValue;
 
455
                private static readonly MethodWrapper valueOfCharacter;
 
456
                private static readonly TypeWrapper javaLangInteger;
 
457
                private static readonly MethodWrapper intValue;
 
458
                private static readonly MethodWrapper valueOfInteger;
 
459
                private static readonly TypeWrapper javaLangFloat;
 
460
                private static readonly MethodWrapper floatValue;
 
461
                private static readonly MethodWrapper valueOfFloat;
 
462
                private static readonly TypeWrapper javaLangLong;
 
463
                private static readonly MethodWrapper longValue;
 
464
                private static readonly MethodWrapper valueOfLong;
 
465
                private static readonly TypeWrapper javaLangDouble;
 
466
                private static readonly MethodWrapper doubleValue;
 
467
                private static readonly MethodWrapper valueOfDouble;
 
468
 
 
469
                static Boxer()
 
470
                {
 
471
                        ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader();
 
472
                        javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte");
 
473
                        byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false);
 
474
                        byteValue.Link();
 
475
                        valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false);
 
476
                        valueOfByte.Link();
 
477
                        javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean");
 
478
                        booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false);
 
479
                        booleanValue.Link();
 
480
                        valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false);
 
481
                        valueOfBoolean.Link();
 
482
                        javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short");
 
483
                        shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false);
 
484
                        shortValue.Link();
 
485
                        valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false);
 
486
                        valueOfShort.Link();
 
487
                        javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character");
 
488
                        charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false);
 
489
                        charValue.Link();
 
490
                        valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false);
 
491
                        valueOfCharacter.Link();
 
492
                        javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer");
 
493
                        intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false);
 
494
                        intValue.Link();
 
495
                        valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false);
 
496
                        valueOfInteger.Link();
 
497
                        javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float");
 
498
                        floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false);
 
499
                        floatValue.Link();
 
500
                        valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false);
 
501
                        valueOfFloat.Link();
 
502
                        javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long");
 
503
                        longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false);
 
504
                        longValue.Link();
 
505
                        valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false);
 
506
                        valueOfLong.Link();
 
507
                        javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double");
 
508
                        doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false);
 
509
                        doubleValue.Link();
 
510
                        valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false);
 
511
                        valueOfDouble.Link();
 
512
                }
 
513
 
 
514
                internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw)
 
515
                {
 
516
                        if (tw == PrimitiveTypeWrapper.BYTE)
 
517
                        {
 
518
                                javaLangByte.EmitCheckcast(null, ilgen);
 
519
                                byteValue.EmitCall(ilgen);
 
520
                        }
 
521
                        else if (tw == PrimitiveTypeWrapper.BOOLEAN)
 
522
                        {
 
523
                                javaLangBoolean.EmitCheckcast(null, ilgen);
 
524
                                booleanValue.EmitCall(ilgen);
 
525
                        }
 
526
                        else if (tw == PrimitiveTypeWrapper.SHORT)
 
527
                        {
 
528
                                javaLangShort.EmitCheckcast(null, ilgen);
 
529
                                shortValue.EmitCall(ilgen);
 
530
                        }
 
531
                        else if (tw == PrimitiveTypeWrapper.CHAR)
 
532
                        {
 
533
                                javaLangCharacter.EmitCheckcast(null, ilgen);
 
534
                                charValue.EmitCall(ilgen);
 
535
                        }
 
536
                        else if (tw == PrimitiveTypeWrapper.INT)
 
537
                        {
 
538
                                javaLangInteger.EmitCheckcast(null, ilgen);
 
539
                                intValue.EmitCall(ilgen);
 
540
                        }
 
541
                        else if (tw == PrimitiveTypeWrapper.FLOAT)
 
542
                        {
 
543
                                javaLangFloat.EmitCheckcast(null, ilgen);
 
544
                                floatValue.EmitCall(ilgen);
 
545
                        }
 
546
                        else if (tw == PrimitiveTypeWrapper.LONG)
 
547
                        {
 
548
                                javaLangLong.EmitCheckcast(null, ilgen);
 
549
                                longValue.EmitCall(ilgen);
 
550
                        }
 
551
                        else if (tw == PrimitiveTypeWrapper.DOUBLE)
 
552
                        {
 
553
                                javaLangDouble.EmitCheckcast(null, ilgen);
 
554
                                doubleValue.EmitCall(ilgen);
 
555
                        }
 
556
                        else
 
557
                        {
 
558
                                throw new InvalidOperationException();
 
559
                        }
 
560
                }
 
561
 
 
562
                internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw)
 
563
                {
 
564
                        if (tw == PrimitiveTypeWrapper.BYTE)
 
565
                        {
 
566
                                valueOfByte.EmitCall(ilgen);
 
567
                        }
 
568
                        else if (tw == PrimitiveTypeWrapper.BOOLEAN)
 
569
                        {
 
570
                                valueOfBoolean.EmitCall(ilgen);
 
571
                        }
 
572
                        else if (tw == PrimitiveTypeWrapper.SHORT)
 
573
                        {
 
574
                                valueOfShort.EmitCall(ilgen);
 
575
                        }
 
576
                        else if (tw == PrimitiveTypeWrapper.CHAR)
 
577
                        {
 
578
                                valueOfCharacter.EmitCall(ilgen);
 
579
                        }
 
580
                        else if (tw == PrimitiveTypeWrapper.INT)
 
581
                        {
 
582
                                valueOfInteger.EmitCall(ilgen);
 
583
                        }
 
584
                        else if (tw == PrimitiveTypeWrapper.FLOAT)
 
585
                        {
 
586
                                valueOfFloat.EmitCall(ilgen);
 
587
                        }
 
588
                        else if (tw == PrimitiveTypeWrapper.LONG)
 
589
                        {
 
590
                                valueOfLong.EmitCall(ilgen);
 
591
                        }
 
592
                        else if (tw == PrimitiveTypeWrapper.DOUBLE)
 
593
                        {
 
594
                                valueOfDouble.EmitCall(ilgen);
 
595
                        }
 
596
                        else
 
597
                        {
 
598
                                throw new InvalidOperationException();
 
599
                        }
 
600
                }
 
601
        }
 
602
}