~ubuntu-branches/ubuntu/dapper/ikvm/dapper

« back to all changes in this revision

Viewing changes to runtime/classpath.cs

  • Committer: Bazaar Package Importer
  • Author(s): John Goerzen
  • Date: 2004-08-26 10:18:19 UTC
  • Revision ID: james.westby@ubuntu.com-20040826101819-plz8au2mx4uk1cvc
Tags: upstream-0.8.0.0
ImportĀ upstreamĀ versionĀ 0.8.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2002, 2003, 2004 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;
 
26
using System.IO;
 
27
using System.Reflection;
 
28
using System.Runtime.InteropServices;
 
29
using System.Runtime.CompilerServices;
 
30
using System.Text;
 
31
using NetSystem = System;
 
32
 
 
33
namespace NativeCode.java
 
34
{
 
35
        namespace lang
 
36
        {
 
37
                namespace reflect
 
38
                {
 
39
                        public class Proxy
 
40
                        {
 
41
                                // NOTE not used, only here to shut up ikvmc during compilation of IKVM.GNU.Classpath.dll
 
42
                                public static object getProxyClass0(object o1, object o2)
 
43
                                {
 
44
                                        throw new InvalidOperationException();
 
45
                                }
 
46
                                
 
47
                                // NOTE not used, only here to shut up ikvmc during compilation of IKVM.GNU.Classpath.dll
 
48
                                public static object getProxyData0(object o1, object o2)
 
49
                                {
 
50
                                        throw new InvalidOperationException();
 
51
                                }
 
52
                                
 
53
                                // NOTE not used, only here to shut up ikvmc during compilation of IKVM.GNU.Classpath.dll
 
54
                                public static object generateProxyClass0(object o1, object o2)
 
55
                                {
 
56
                                        throw new InvalidOperationException();
 
57
                                }
 
58
                        }
 
59
 
 
60
                        public class Array
 
61
                        {
 
62
                                public static object createObjectArray(object clazz, int dim)
 
63
                                {
 
64
                                        if(dim >= 0)
 
65
                                        {
 
66
                                                // TODO handle ghost types
 
67
                                                return NetSystem.Array.CreateInstance(VMClass.getWrapperFromClass(clazz).TypeAsArrayType, dim);
 
68
                                        }
 
69
                                        throw JavaException.NegativeArraySizeException();
 
70
                                }
 
71
                        }
 
72
 
 
73
                        internal class JavaWrapper
 
74
                        {
 
75
                                private static Type java_lang_Byte = ClassLoaderWrapper.LoadClassCritical("java.lang.Byte").TypeAsTBD;
 
76
                                private static Type java_lang_Boolean = ClassLoaderWrapper.LoadClassCritical("java.lang.Boolean").TypeAsTBD;
 
77
                                private static Type java_lang_Short = ClassLoaderWrapper.LoadClassCritical("java.lang.Short").TypeAsTBD;
 
78
                                private static Type java_lang_Character = ClassLoaderWrapper.LoadClassCritical("java.lang.Character").TypeAsTBD;
 
79
                                private static Type java_lang_Integer = ClassLoaderWrapper.LoadClassCritical("java.lang.Integer").TypeAsTBD;
 
80
                                private static Type java_lang_Long = ClassLoaderWrapper.LoadClassCritical("java.lang.Long").TypeAsTBD;
 
81
                                private static Type java_lang_Float = ClassLoaderWrapper.LoadClassCritical("java.lang.Float").TypeAsTBD;
 
82
                                private static Type java_lang_Double = ClassLoaderWrapper.LoadClassCritical("java.lang.Double").TypeAsTBD;
 
83
 
 
84
                                internal static object Box(object o)
 
85
                                {
 
86
                                        if(o is sbyte)
 
87
                                        {
 
88
                                                return Activator.CreateInstance(java_lang_Byte, new object[] { o });
 
89
                                        }
 
90
                                        else if(o is byte)
 
91
                                        {
 
92
                                                return Activator.CreateInstance(java_lang_Byte, new object[] { (sbyte)(byte)o });
 
93
                                        }
 
94
                                        else if(o is bool)
 
95
                                        {
 
96
                                                return Activator.CreateInstance(java_lang_Boolean, new object[] { o });
 
97
                                        }
 
98
                                        else if(o is short)
 
99
                                        {
 
100
                                                return Activator.CreateInstance(java_lang_Short, new object[] { o });
 
101
                                        }
 
102
                                        else if(o is ushort)
 
103
                                        {
 
104
                                                return Activator.CreateInstance(java_lang_Short, new object[] { (short)(ushort)o });
 
105
                                        }
 
106
                                        else if(o is char)
 
107
                                        {
 
108
                                                return Activator.CreateInstance(java_lang_Character, new object[] { o });
 
109
                                        }
 
110
                                        else if(o is int)
 
111
                                        {
 
112
                                                return Activator.CreateInstance(java_lang_Integer, new object[] { o });
 
113
                                        }
 
114
                                        else if(o is uint)
 
115
                                        {
 
116
                                                return Activator.CreateInstance(java_lang_Integer, new object[] { (int)(uint)o });
 
117
                                        }
 
118
                                        else if(o is long)
 
119
                                        {
 
120
                                                return Activator.CreateInstance(java_lang_Long, new object[] { o });
 
121
                                        }
 
122
                                        else if(o is ulong)
 
123
                                        {
 
124
                                                return Activator.CreateInstance(java_lang_Long, new object[] { (long)(ulong)o });
 
125
                                        }
 
126
                                        else if(o is float)
 
127
                                        {
 
128
                                                return Activator.CreateInstance(java_lang_Float, new object[] { o });
 
129
                                        }
 
130
                                        else if(o is double)
 
131
                                        {
 
132
                                                return Activator.CreateInstance(java_lang_Double, new object[] { o });
 
133
                                        }
 
134
                                        else if(o is Enum)
 
135
                                        {
 
136
                                                Type enumType = Enum.GetUnderlyingType(o.GetType());
 
137
                                                if(enumType == typeof(byte) || enumType == typeof(sbyte))
 
138
                                                {
 
139
                                                        return JavaWrapper.Box((sbyte)((IConvertible)o).ToInt32(null));
 
140
                                                }
 
141
                                                else if(enumType == typeof(short) || enumType == typeof(ushort))
 
142
                                                {
 
143
                                                        return JavaWrapper.Box((short)((IConvertible)o).ToInt32(null));
 
144
                                                }
 
145
                                                else if(enumType == typeof(int))
 
146
                                                {
 
147
                                                        return JavaWrapper.Box(((IConvertible)o).ToInt32(null));
 
148
                                                }
 
149
                                                else if(enumType == typeof(uint))
 
150
                                                {
 
151
                                                        return JavaWrapper.Box(unchecked((int)((IConvertible)o).ToUInt32(null)));
 
152
                                                }
 
153
                                                else if(enumType == typeof(long))
 
154
                                                {
 
155
                                                        return JavaWrapper.Box(((IConvertible)o).ToInt64(null));
 
156
                                                }
 
157
                                                else if(enumType == typeof(ulong))
 
158
                                                {
 
159
                                                        return JavaWrapper.Box(unchecked((long)((IConvertible)o).ToUInt64(null)));
 
160
                                                }
 
161
                                                else
 
162
                                                {
 
163
                                                        throw new InvalidOperationException();
 
164
                                                }
 
165
                                        }
 
166
                                        else
 
167
                                        {
 
168
                                                throw new NotImplementedException(o.GetType().FullName);
 
169
                                        }
 
170
                                }
 
171
 
 
172
                                internal static object Unbox(object o)
 
173
                                {
 
174
                                        Type type = o.GetType();
 
175
                                        if(type == java_lang_Byte)
 
176
                                        {
 
177
                                                return java_lang_Byte.GetMethod("byteValue").Invoke(o, new object[0]);
 
178
                                        }
 
179
                                        else if(type == java_lang_Boolean)
 
180
                                        {
 
181
                                                return java_lang_Boolean.GetMethod("booleanValue").Invoke(o, new object[0]);
 
182
                                        }
 
183
                                        else if(type == java_lang_Short)
 
184
                                        {
 
185
                                                return java_lang_Short.GetMethod("shortValue").Invoke(o, new object[0]);
 
186
                                        }
 
187
                                        else if(type == java_lang_Character)
 
188
                                        {
 
189
                                                return java_lang_Character.GetMethod("charValue").Invoke(o, new object[0]);
 
190
                                        }
 
191
                                        else if(type == java_lang_Integer)
 
192
                                        {
 
193
                                                return java_lang_Integer.GetMethod("intValue").Invoke(o, new object[0]);
 
194
                                        }
 
195
                                        else if(type == java_lang_Long)
 
196
                                        {
 
197
                                                return java_lang_Long.GetMethod("longValue").Invoke(o, new object[0]);
 
198
                                        }
 
199
                                        else if(type == java_lang_Float)
 
200
                                        {
 
201
                                                return java_lang_Float.GetMethod("floatValue").Invoke(o, new object[0]);
 
202
                                        }
 
203
                                        else if(type == java_lang_Double)
 
204
                                        {
 
205
                                                return java_lang_Double.GetMethod("doubleValue").Invoke(o, new object[0]);
 
206
                                        }
 
207
                                        else
 
208
                                        {
 
209
                                                throw JavaException.IllegalArgumentException(type.FullName);
 
210
                                        }
 
211
                                }
 
212
                        }
 
213
 
 
214
                        public class Method
 
215
                        {
 
216
                                public static String GetName(object methodCookie)
 
217
                                {
 
218
                                        MethodWrapper wrapper = (MethodWrapper)methodCookie;
 
219
                                        return wrapper.Name;
 
220
                                }
 
221
                                
 
222
                                public static int GetModifiers(object methodCookie)
 
223
                                {
 
224
                                        MethodWrapper wrapper = (MethodWrapper)methodCookie;
 
225
                                        return (int)wrapper.Modifiers;
 
226
                                }
 
227
 
 
228
                                public static object GetReturnType(object methodCookie)
 
229
                                {
 
230
                                        MethodWrapper wrapper = (MethodWrapper)methodCookie;
 
231
                                        return VMClass.getClassFromWrapper(wrapper.ReturnType);
 
232
                                }
 
233
 
 
234
                                public static object[] GetParameterTypes(object methodCookie)
 
235
                                {
 
236
                                        MethodWrapper wrapper = (MethodWrapper)methodCookie;
 
237
                                        TypeWrapper[] parameters = wrapper.GetParameters();
 
238
                                        object[] parameterClasses = new object[parameters.Length];
 
239
                                        for(int i = 0; i < parameters.Length; i++)
 
240
                                        {
 
241
                                                parameterClasses[i] = VMClass.getClassFromWrapper(parameters[i]);
 
242
                                        }
 
243
                                        return parameterClasses;
 
244
                                }
 
245
 
 
246
                                public static string[] GetExceptionTypes(object methodCookie)
 
247
                                {
 
248
                                        MethodWrapper wrapper = (MethodWrapper)methodCookie;
 
249
                                        wrapper.DeclaringType.Finish();
 
250
                                        return wrapper.GetExceptions();
 
251
                                }
 
252
 
 
253
                                public static object Invoke(object methodCookie, object o, object[] args)
 
254
                                {
 
255
                                        object[] argsCopy = new Object[args != null ? args.Length : 0];
 
256
                                        MethodWrapper mw = (MethodWrapper)methodCookie;
 
257
                                        mw.DeclaringType.Finish();
 
258
                                        TypeWrapper[] argWrappers = mw.GetParameters();
 
259
                                        for(int i = 0; i < argWrappers.Length; i++)
 
260
                                        {
 
261
                                                if(argWrappers[i].IsPrimitive)
 
262
                                                {
 
263
                                                        if(args[i] == null)
 
264
                                                        {
 
265
                                                                throw JavaException.IllegalArgumentException("primitive wrapper null");
 
266
                                                        }
 
267
                                                        argsCopy[i] = JavaWrapper.Unbox(args[i]);
 
268
                                                }
 
269
                                                else
 
270
                                                {
 
271
                                                        argsCopy[i] = args[i];
 
272
                                                }
 
273
                                        }
 
274
                                        object retval = mw.Invoke(o, argsCopy, false);
 
275
                                        if(mw.ReturnType.IsPrimitive && mw.ReturnType != PrimitiveTypeWrapper.VOID)
 
276
                                        {
 
277
                                                retval = JavaWrapper.Box(retval);
 
278
                                        }
 
279
                                        return retval;
 
280
                                }
 
281
                        }
 
282
 
 
283
                        public class Field
 
284
                        {
 
285
                                // HACK this is used by netexp to query the constant value of a field
 
286
                                public static object getConstant(object field)
 
287
                                {
 
288
                                        // HACK we use reflection to extract the fieldCookie from the java.lang.reflect.Field object
 
289
                                        FieldWrapper wrapper = (FieldWrapper)field.GetType().GetField("fieldCookie", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(field);
 
290
                                        return wrapper.GetConstant();
 
291
                                }
 
292
 
 
293
                                public static string GetName(object fieldCookie)
 
294
                                {
 
295
                                        FieldWrapper wrapper = (FieldWrapper)fieldCookie;
 
296
                                        return wrapper.Name;
 
297
                                }
 
298
 
 
299
                                public static int GetModifiers(object fieldCookie)
 
300
                                {
 
301
                                        FieldWrapper wrapper = (FieldWrapper)fieldCookie;
 
302
                                        return (int)wrapper.Modifiers;
 
303
                                }
 
304
 
 
305
                                public static object GetFieldType(object fieldCookie)
 
306
                                {
 
307
                                        FieldWrapper wrapper = (FieldWrapper)fieldCookie;
 
308
                                        return VMClass.getClassFromWrapper(wrapper.FieldTypeWrapper);
 
309
                                }
 
310
 
 
311
                                public static bool isSamePackage(object a, object b)
 
312
                                {
 
313
                                        return VMClass.getWrapperFromClass(a).IsInSamePackageAs(VMClass.getWrapperFromClass(b));
 
314
                                }
 
315
 
 
316
                                public static object getClassFromFrame(NetSystem.Diagnostics.StackFrame frame)
 
317
                                {
 
318
                                        return VMClass.getClassFromType(frame.GetMethod().DeclaringType);
 
319
                                }
 
320
 
 
321
                                public static object GetValue(object fieldCookie, object o)
 
322
                                {
 
323
                                        Profiler.Enter("Field.GetValue");
 
324
                                        try
 
325
                                        {
 
326
                                                FieldWrapper wrapper = (FieldWrapper)fieldCookie;
 
327
                                                object val = wrapper.GetValue(o);
 
328
                                                if(wrapper.FieldTypeWrapper.IsPrimitive)
 
329
                                                {
 
330
                                                        val = JavaWrapper.Box(val);
 
331
                                                }
 
332
                                                return val;
 
333
                                        }
 
334
                                        finally
 
335
                                        {
 
336
                                                Profiler.Leave("Field.GetValue");
 
337
                                        }
 
338
                                }
 
339
 
 
340
                                public static void SetValue(object fieldCookie, object o, object v)
 
341
                                {
 
342
                                        Profiler.Enter("Field.SetValue");
 
343
                                        try
 
344
                                        {
 
345
                                                FieldWrapper wrapper = (FieldWrapper)fieldCookie;
 
346
                                                if(wrapper.IsFinal)
 
347
                                                {
 
348
                                                        // NOTE Java runs the class initializer when trying to set a final field
 
349
                                                        wrapper.DeclaringType.RunClassInit();
 
350
                                                        // NOTE even if the caller is the class itself, it still isn't legal
 
351
                                                        throw JavaException.IllegalAccessException("Field is final");
 
352
                                                }
 
353
                                                // TODO enforce accessibility (isAccessible() is false)
 
354
                                                if(wrapper.FieldTypeWrapper.IsPrimitive)
 
355
                                                {
 
356
                                                        v = JavaWrapper.Unbox(v);
 
357
                                                }
 
358
                                                wrapper.SetValue(o, v);
 
359
                                        }
 
360
                                        finally
 
361
                                        {
 
362
                                                Profiler.Leave("Field.SetValue");
 
363
                                        }
 
364
                                }
 
365
                        }
 
366
                }
 
367
 
 
368
                public class VMRuntime
 
369
                {
 
370
                        public static string getVersion()
 
371
                        {
 
372
                                return typeof(VMRuntime).Assembly.GetName().Version.ToString();
 
373
                        }
 
374
 
 
375
                        public static int nativeLoad(string filename)
 
376
                        {
 
377
                                // TODO native libraries somehow need to be scoped by class loader
 
378
                                return JVM.JniProvider.LoadNativeLibrary(filename);
 
379
                        }
 
380
                }
 
381
 
 
382
                public class Math
 
383
                {
 
384
                        public static double pow(double x, double y)
 
385
                        {
 
386
                                return NetSystem.Math.Pow(x, y);
 
387
                        }
 
388
 
 
389
                        public static double exp(double d)
 
390
                        {
 
391
                                return NetSystem.Math.Exp(d);
 
392
                        }
 
393
 
 
394
                        public static double rint(double d)
 
395
                        {
 
396
                                return NetSystem.Math.Round(d);
 
397
                        }
 
398
 
 
399
                        public static double IEEEremainder(double f1, double f2)
 
400
                        {
 
401
                                if(double.IsInfinity(f2) && !double.IsInfinity(f1))
 
402
                                {
 
403
                                        return f1;
 
404
                                }
 
405
                                return NetSystem.Math.IEEERemainder(f1, f2);
 
406
                        }
 
407
 
 
408
                        public static double sqrt(double d)
 
409
                        {
 
410
                                return NetSystem.Math.Sqrt(d);
 
411
                        }
 
412
 
 
413
                        public static double floor(double d)
 
414
                        {
 
415
                                return NetSystem.Math.Floor(d);
 
416
                        }
 
417
 
 
418
                        public static double ceil(double d)
 
419
                        {
 
420
                                return NetSystem.Math.Ceiling(d);
 
421
                        }
 
422
 
 
423
                        public static double log(double d)
 
424
                        {
 
425
                                return NetSystem.Math.Log(d);
 
426
                        }
 
427
 
 
428
                        public static double sin(double d)
 
429
                        {
 
430
                                return NetSystem.Math.Sin(d);
 
431
                        }
 
432
 
 
433
                        public static double asin(double d)
 
434
                        {
 
435
                                return NetSystem.Math.Asin(d);
 
436
                        }
 
437
 
 
438
                        public static double cos(double d)
 
439
                        {
 
440
                                return NetSystem.Math.Cos(d);
 
441
                        }
 
442
 
 
443
                        public static double acos(double d)
 
444
                        {
 
445
                                return NetSystem.Math.Acos(d);
 
446
                        }
 
447
 
 
448
                        public static double tan(double d)
 
449
                        {
 
450
                                return NetSystem.Math.Tan(d);
 
451
                        }
 
452
 
 
453
                        public static double atan(double d)
 
454
                        {
 
455
                                return NetSystem.Math.Atan(d);
 
456
                        }
 
457
 
 
458
                        public static double atan2(double y, double x)
 
459
                        {
 
460
                                if(double.IsInfinity(y) && double.IsInfinity(x))
 
461
                                {
 
462
                                        if(double.IsPositiveInfinity(y))
 
463
                                        {
 
464
                                                if(double.IsPositiveInfinity(x))
 
465
                                                {
 
466
                                                        return NetSystem.Math.PI / 4.0;
 
467
                                                }
 
468
                                                else
 
469
                                                {
 
470
                                                        return NetSystem.Math.PI * 3.0 / 4.0;
 
471
                                                }
 
472
                                        }
 
473
                                        else
 
474
                                        {
 
475
                                                if(double.IsPositiveInfinity(x))
 
476
                                                {
 
477
                                                        return - NetSystem.Math.PI / 4.0;
 
478
                                                }
 
479
                                                else
 
480
                                                {
 
481
                                                        return - NetSystem.Math.PI * 3.0 / 4.0;
 
482
                                                }
 
483
                                        }
 
484
                                }
 
485
                                return NetSystem.Math.Atan2(y, x);
 
486
                        }
 
487
                }
 
488
 
 
489
                public class Double
 
490
                {
 
491
                        public static void initIDs()
 
492
                        {
 
493
                        }
 
494
 
 
495
                        public static double parseDouble(string s)
 
496
                        {
 
497
                                try
 
498
                                {
 
499
                                        // TODO I doubt that this is correct
 
500
                                        return double.Parse(s);
 
501
                                }
 
502
                                catch(FormatException x)
 
503
                                {
 
504
                                        throw JavaException.NumberFormatException(x.Message);
 
505
                                }
 
506
                        }
 
507
 
 
508
                        public static string toString(double d, bool isFloat)
 
509
                        {
 
510
                                if(isFloat)
 
511
                                {
 
512
                                        float f = (float)d;
 
513
                                        // TODO this is not correct, we need to use the Java algorithm of converting a float to string
 
514
                                        if(float.IsNaN(f))
 
515
                                        {
 
516
                                                return "NaN";
 
517
                                        }
 
518
                                        if(float.IsNegativeInfinity(f))
 
519
                                        {
 
520
                                                return "-Infinity";
 
521
                                        }
 
522
                                        if(float.IsPositiveInfinity(f))
 
523
                                        {
 
524
                                                return "Infinity";
 
525
                                        }
 
526
                                        // HACK really lame hack to apprioximate the Java behavior a little bit
 
527
                                        string s = f.ToString(System.Globalization.CultureInfo.InvariantCulture);
 
528
                                        if(s.IndexOf('.') == -1)
 
529
                                        {
 
530
                                                s += ".0";
 
531
                                        }
 
532
                                        // make sure -0.0 renders correctly
 
533
                                        if(d == 0.0 && BitConverter.DoubleToInt64Bits(d) < 0)
 
534
                                        {
 
535
                                                return "-" + s;
 
536
                                        }
 
537
                                        return s;
 
538
                                }
 
539
                                else
 
540
                                {
 
541
                                        StringBuilder sb = new StringBuilder();
 
542
                                        DoubleToString.append(sb, d);
 
543
                                        return sb.ToString();
 
544
                                }
 
545
                        }
 
546
                }
 
547
 
 
548
                public class VMSecurityManager
 
549
                {
 
550
                        public static object getClassContext()
 
551
                        {
 
552
                                ArrayList ar = new ArrayList();
 
553
                                NetSystem.Diagnostics.StackTrace st = new NetSystem.Diagnostics.StackTrace();
 
554
                                for(int i = 0; i < st.FrameCount; i++)
 
555
                                {
 
556
                                        NetSystem.Diagnostics.StackFrame frame = st.GetFrame(i);
 
557
                                        // HACK very insecure
 
558
                                        // TODO handle reflection scenario
 
559
                                        if(frame.GetMethod().Name != "getClassContext")
 
560
                                        {
 
561
                                                ar.Add(VMClass.getClassFromType(frame.GetMethod().DeclaringType));
 
562
                                        }
 
563
                                }
 
564
                                return ar.ToArray(CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
 
565
                        }
 
566
 
 
567
                        public static object currentClassLoader()
 
568
                        {
 
569
                                // TODO handle PrivilegedAction
 
570
                                NetSystem.Diagnostics.StackTrace st = new NetSystem.Diagnostics.StackTrace();
 
571
                                for(int i = 0; i < st.FrameCount; i++)
 
572
                                {
 
573
                                        NetSystem.Diagnostics.StackFrame frame = st.GetFrame(i);
 
574
                                        TypeWrapper wrapper = ClassLoaderWrapper.GetWrapperFromTypeFast(frame.GetMethod().DeclaringType);
 
575
                                        if(wrapper != null && wrapper.GetClassLoader().GetJavaClassLoader() != null)
 
576
                                        {
 
577
                                                return wrapper.GetClassLoader().GetJavaClassLoader();
 
578
                                        }
 
579
                                }
 
580
                                return null;
 
581
                        }
 
582
                }
 
583
 
 
584
                public class VMSystem
 
585
                {
 
586
                        public static void arraycopy_primitive_8(Array src, int srcStart, Array dest, int destStart, int len)
 
587
                        {
 
588
                                try 
 
589
                                {
 
590
                                        checked
 
591
                                        {
 
592
                                                Buffer.BlockCopy(src, srcStart << 3, dest, destStart << 3, len << 3);
 
593
                                                return;
 
594
                                        }
 
595
                                }
 
596
                                catch(ArgumentNullException)
 
597
                                {
 
598
                                        throw JavaException.NullPointerException();
 
599
                                }
 
600
                                catch(OverflowException)
 
601
                                {
 
602
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
603
                                }
 
604
                                catch(ArgumentException) 
 
605
                                {
 
606
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
607
                                }
 
608
                        }
 
609
 
 
610
                        public static void arraycopy_primitive_4(Array src, int srcStart, Array dest, int destStart, int len)
 
611
                        {
 
612
                                try 
 
613
                                {
 
614
                                        checked
 
615
                                        {
 
616
                                                Buffer.BlockCopy(src, srcStart << 2, dest, destStart << 2, len << 2);
 
617
                                                return;
 
618
                                        }
 
619
                                }
 
620
                                catch(ArgumentNullException)
 
621
                                {
 
622
                                        throw JavaException.NullPointerException();
 
623
                                }
 
624
                                catch(OverflowException)
 
625
                                {
 
626
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
627
                                }
 
628
                                catch(ArgumentException) 
 
629
                                {
 
630
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
631
                                }
 
632
                        }
 
633
 
 
634
                        public static void arraycopy_primitive_2(Array src, int srcStart, Array dest, int destStart, int len)
 
635
                        {
 
636
                                try 
 
637
                                {
 
638
                                        checked
 
639
                                        {
 
640
                                                Buffer.BlockCopy(src, srcStart << 1, dest, destStart << 1, len << 1);
 
641
                                                return;
 
642
                                        }
 
643
                                }
 
644
                                catch(ArgumentNullException)
 
645
                                {
 
646
                                        throw JavaException.NullPointerException();
 
647
                                }
 
648
                                catch(OverflowException)
 
649
                                {
 
650
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
651
                                }
 
652
                                catch(ArgumentException) 
 
653
                                {
 
654
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
655
                                }
 
656
                        }
 
657
 
 
658
                        public static void arraycopy_primitive_1(Array src, int srcStart, Array dest, int destStart, int len)
 
659
                        {
 
660
                                try 
 
661
                                {
 
662
                                        Buffer.BlockCopy(src, srcStart, dest, destStart, len);
 
663
                                        return;
 
664
                                }
 
665
                                catch(ArgumentNullException)
 
666
                                {
 
667
                                        throw JavaException.NullPointerException();
 
668
                                }
 
669
                                catch(OverflowException)
 
670
                                {
 
671
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
672
                                }
 
673
                                catch(ArgumentException) 
 
674
                                {
 
675
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
676
                                }
 
677
                        }
 
678
 
 
679
                        public static void arraycopy(object src, int srcStart, object dest, int destStart, int len)
 
680
                        {
 
681
                                if(src != dest)
 
682
                                {
 
683
                                        // NOTE side effect of GetTypeHandle call is null check for src and dest (it
 
684
                                        // throws an ArgumentNullException)
 
685
                                        // Since constructing a Type object is expensive, we use Type.GetTypeHandle and
 
686
                                        // hope that it is implemented in a such a way that it is more efficient than
 
687
                                        // Object.GetType()
 
688
                                        try
 
689
                                        {
 
690
                                                RuntimeTypeHandle type_src = Type.GetTypeHandle(src);
 
691
                                                RuntimeTypeHandle type_dst = Type.GetTypeHandle(dest);
 
692
                                                if(type_src.Value != type_dst.Value)
 
693
                                                {
 
694
                                                        if(len >= 0)
 
695
                                                        {
 
696
                                                                try
 
697
                                                                {
 
698
                                                                        // since Java strictly defines what happens when an ArrayStoreException occurs during copying
 
699
                                                                        // and .NET doesn't, we have to do it by hand
 
700
                                                                        Object[] src1 = (Object[])src;
 
701
                                                                        Object[] dst1 = (Object[])dest;
 
702
                                                                        for(; len > 0; len--)
 
703
                                                                        {
 
704
                                                                                dst1[destStart++] = src1[srcStart++];
 
705
                                                                        }
 
706
                                                                        return;
 
707
                                                                }
 
708
                                                                catch(InvalidCastException)
 
709
                                                                {
 
710
                                                                        throw JavaException.ArrayStoreException("cast failed");
 
711
                                                                }
 
712
                                                        }
 
713
                                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
714
                                                }
 
715
                                        }
 
716
                                        catch(ArgumentNullException)
 
717
                                        {
 
718
                                                throw JavaException.NullPointerException();
 
719
                                        }
 
720
                                }
 
721
                                try 
 
722
                                {
 
723
                                        Array.Copy((Array)src, srcStart, (Array)dest, destStart, len);
 
724
                                }
 
725
                                catch(ArgumentNullException)
 
726
                                {
 
727
                                        throw JavaException.NullPointerException();
 
728
                                }
 
729
                                catch(ArgumentException) 
 
730
                                {
 
731
                                        throw JavaException.ArrayIndexOutOfBoundsException();
 
732
                                }
 
733
                                catch(InvalidCastException x)
 
734
                                {
 
735
                                        if(!src.GetType().IsArray)
 
736
                                        {
 
737
                                                throw JavaException.ArrayStoreException("source is not an array");
 
738
                                        }
 
739
                                        if(!dest.GetType().IsArray)
 
740
                                        {
 
741
                                                throw JavaException.ArrayStoreException("destination is not an array");
 
742
                                        }
 
743
                                        // this shouldn't happen
 
744
                                        throw JavaException.ArrayStoreException(x.Message);
 
745
                                }
 
746
                        }
 
747
 
 
748
                        public static bool isWordsBigEndian()
 
749
                        {
 
750
                                return !BitConverter.IsLittleEndian;
 
751
                        }
 
752
 
 
753
                        public static long currentTimeMillis()
 
754
                        {
 
755
                                const long january_1st_1970 = 62135596800000L;
 
756
                                return DateTime.UtcNow.Ticks / 10000L - january_1st_1970;
 
757
                        }
 
758
 
 
759
                        public static void setErr(object printStream)
 
760
                        {
 
761
                                TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.System");
 
762
                                FieldWrapper fw = tw.GetFieldWrapper("err", ClassLoaderWrapper.LoadClassCritical("java.io.PrintStream"));
 
763
                        }
 
764
 
 
765
                        public static void setIn(object inputStream)
 
766
                        {
 
767
                                TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.System");
 
768
                                FieldWrapper fw = tw.GetFieldWrapper("in", ClassLoaderWrapper.LoadClassCritical("java.io.InputStream"));
 
769
                                fw.SetValue(null, inputStream);
 
770
                        }
 
771
 
 
772
                        public static void setOut(object printStream)
 
773
                        {
 
774
                                TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.System");
 
775
                                FieldWrapper fw = tw.GetFieldWrapper("out", ClassLoaderWrapper.LoadClassCritical("java.io.PrintStream"));
 
776
                                fw.SetValue(null, printStream);
 
777
                        }
 
778
 
 
779
                        public static int identityHashCode(object o)
 
780
                        {
 
781
                                return RuntimeHelpers.GetHashCode(o);
 
782
                        }
 
783
                }
 
784
 
 
785
                public class VMClassLoader
 
786
                {
 
787
                        public static Assembly findResourceAssembly(string name)
 
788
                        {
 
789
                                Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
 
790
                                for(int i = 0; i < assemblies.Length; i++)
 
791
                                {
 
792
                                        if(!(assemblies[i] is NetSystem.Reflection.Emit.AssemblyBuilder))
 
793
                                        {
 
794
                                                if(assemblies[i].GetManifestResourceInfo("ikvm:" + name) != null)
 
795
                                                {
 
796
                                                        return assemblies[i];
 
797
                                                }
 
798
                                        }
 
799
                                }
 
800
                                return null;
 
801
                        }
 
802
 
 
803
                        public static object getBootstrapClassLoader()
 
804
                        {
 
805
                                return ClassLoaderWrapper.GetJavaBootstrapClassLoader();
 
806
                        }
 
807
 
 
808
                        public static object getPrimitiveClass(char type)
 
809
                        {
 
810
                                switch(type)
 
811
                                {
 
812
                                        case 'Z':
 
813
                                                return VMClass.getClassFromType(typeof(bool));
 
814
                                        case 'B':
 
815
                                                return VMClass.getClassFromType(typeof(sbyte));
 
816
                                        case 'C':
 
817
                                                return VMClass.getClassFromType(typeof(char));
 
818
                                        case 'D':
 
819
                                                return VMClass.getClassFromType(typeof(double));
 
820
                                        case 'F':
 
821
                                                return VMClass.getClassFromType(typeof(float));
 
822
                                        case 'I':
 
823
                                                return VMClass.getClassFromType(typeof(int));
 
824
                                        case 'J':
 
825
                                                return VMClass.getClassFromType(typeof(long));
 
826
                                        case 'S':
 
827
                                                return VMClass.getClassFromType(typeof(short));
 
828
                                        case 'V':
 
829
                                                return VMClass.getClassFromType(typeof(void));
 
830
                                        default:
 
831
                                                throw new InvalidOperationException();
 
832
                                }
 
833
                        }
 
834
 
 
835
                        public static object defineClass(object classLoader, string name, byte[] data, int offset, int length, object protectionDomain)
 
836
                        {
 
837
                                Profiler.Enter("ClassLoader.defineClass");
 
838
                                try
 
839
                                {
 
840
                                        try
 
841
                                        {
 
842
                                                ClassFile classFile = new ClassFile(data, offset, length, name);
 
843
                                                if(name != null && classFile.Name != name)
 
844
                                                {
 
845
                                                        throw JavaException.NoClassDefFoundError("{0} (wrong name: {1})", name, classFile.Name);
 
846
                                                }
 
847
                                                TypeWrapper type = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader).DefineClass(classFile);
 
848
                                                object clazz = VMClass.CreateClassInstance(type);
 
849
                                                if(protectionDomain != null)
 
850
                                                {
 
851
                                                        // TODO cache the FieldInfo
 
852
                                                        clazz.GetType().GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(clazz, protectionDomain);
 
853
                                                }
 
854
                                                return clazz;
 
855
                                        }
 
856
                                        catch(ClassFile.UnsupportedClassVersionError x)
 
857
                                        {
 
858
                                                throw JavaException.UnsupportedClassVersionError(x.Message);
 
859
                                        }
 
860
                                        catch(ClassFile.ClassFormatError x)
 
861
                                        {
 
862
                                                throw JavaException.ClassFormatError(x.Message);
 
863
                                        }
 
864
                                }
 
865
                                finally
 
866
                                {
 
867
                                        Profiler.Leave("ClassLoader.defineClass");
 
868
                                }
 
869
                        }
 
870
                }
 
871
 
 
872
                public class VMClass
 
873
                {
 
874
                        private static Hashtable map = new Hashtable();
 
875
                        private delegate object LookupDelegate(object o);
 
876
                        private static LookupDelegate createClass;
 
877
                        private static LookupDelegate getWrapper;
 
878
 
 
879
                        public static void throwException(Exception e)
 
880
                        {
 
881
                                throw e;
 
882
                        }
 
883
 
 
884
                        public static object loadArrayClass(string name, object classLoader)
 
885
                        {
 
886
                                ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader);
 
887
                                TypeWrapper type = classLoaderWrapper.LoadClassByDottedName(name);
 
888
                                return getClassFromWrapper(type);
 
889
                        }
 
890
 
 
891
                        public static object loadBootstrapClass(string name, bool initialize)
 
892
                        {
 
893
                                TypeWrapper type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast(name);
 
894
                                if(type != null)
 
895
                                {
 
896
                                        if(initialize)
 
897
                                        {
 
898
                                                type.Finish();
 
899
                                                type.RunClassInit();
 
900
                                        }
 
901
                                        return getClassFromWrapper(type);
 
902
                                }
 
903
                                return null;
 
904
                        }
 
905
 
 
906
                        internal static object CreateClassInstance(TypeWrapper wrapper)
 
907
                        {
 
908
                                if(createClass == null)
 
909
                                {
 
910
                                        TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.VMClass");
 
911
                                        tw.Finish();
 
912
                                        createClass = (LookupDelegate)Delegate.CreateDelegate(typeof(LookupDelegate), tw.TypeAsTBD.GetMethod("createClass", BindingFlags.Static | BindingFlags.Public));
 
913
                                        // HACK to make sure we don't run into any problems creating class objects for classes that
 
914
                                        // participate in the VMClass static initialization, we first do a bogus call to initialize
 
915
                                        // the machinery (I ran into this when running ikvmstub on IKVM.GNU.Classpath.dll)
 
916
                                        createClass(null);
 
917
                                        lock(map.SyncRoot)
 
918
                                        {
 
919
                                                object o = map[wrapper];
 
920
                                                if(o != null)
 
921
                                                {
 
922
                                                        return o;
 
923
                                                }
 
924
                                        }
 
925
                                }
 
926
                                object clazz = createClass(wrapper);
 
927
                                lock(map.SyncRoot)
 
928
                                {
 
929
                                        if(wrapper != null)
 
930
                                        {
 
931
                                                map.Add(wrapper, clazz);
 
932
                                        }
 
933
                                }
 
934
                                return clazz;
 
935
                        }
 
936
 
 
937
                        public static bool IsAssignableFrom(object w1, object w2)
 
938
                        {
 
939
                                return ((TypeWrapper)w2).IsAssignableTo((TypeWrapper)w1);
 
940
                        }
 
941
 
 
942
                        public static bool IsInterface(object wrapper)
 
943
                        {
 
944
                                return ((TypeWrapper)wrapper).IsInterface;
 
945
                        }
 
946
 
 
947
                        public static bool IsArray(object wrapper)
 
948
                        {
 
949
                                return ((TypeWrapper)wrapper).IsArray;
 
950
                        }
 
951
 
 
952
                        public static object GetSuperClassFromWrapper(object wrapper)
 
953
                        {
 
954
                                TypeWrapper baseWrapper = ((TypeWrapper)wrapper).BaseTypeWrapper;
 
955
                                if(baseWrapper != null)
 
956
                                {
 
957
                                        return getClassFromWrapper(baseWrapper);
 
958
                                }
 
959
                                return null;
 
960
                        }
 
961
 
 
962
                        public static object getComponentClassFromWrapper(object wrapper)
 
963
                        {
 
964
                                TypeWrapper typeWrapper = (TypeWrapper)wrapper;
 
965
                                if(typeWrapper.ArrayRank > 0)
 
966
                                {
 
967
                                        TypeWrapper elementWrapper = typeWrapper.ElementTypeWrapper;
 
968
                                        // TODO why are we finishing here? This shouldn't be necessary
 
969
                                        elementWrapper.Finish();
 
970
                                        return getClassFromWrapper(elementWrapper);
 
971
                                }
 
972
                                return null;
 
973
                        }
 
974
 
 
975
                        internal static TypeWrapper getWrapperFromClass(object clazz)
 
976
                        {
 
977
                                if(getWrapper == null)
 
978
                                {
 
979
                                        TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.VMClass");
 
980
                                        tw.Finish();
 
981
                                        getWrapper = (LookupDelegate)Delegate.CreateDelegate(typeof(LookupDelegate), tw.TypeAsTBD.GetMethod("getWrapperFromClass", BindingFlags.Static | BindingFlags.Public));
 
982
                                }
 
983
                                return (TypeWrapper)getWrapper(clazz);
 
984
                        }
 
985
 
 
986
                        internal static object getClassFromWrapper(TypeWrapper wrapper)
 
987
                        {
 
988
                                lock(map.SyncRoot)
 
989
                                {
 
990
                                        object clazz = map[wrapper];
 
991
                                        if(clazz == null)
 
992
                                        {
 
993
                                                clazz = CreateClassInstance(wrapper);
 
994
                                        }
 
995
                                        return clazz;
 
996
                                }
 
997
                        }
 
998
 
 
999
                        public static object getClassFromType(Type type)
 
1000
                        {
 
1001
                                TypeWrapper.AssertFinished(type);
 
1002
                                if(type == null)
 
1003
                                {
 
1004
                                        return null;
 
1005
                                }
 
1006
                                return getClassFromWrapper(ClassLoaderWrapper.GetWrapperFromType(type));
 
1007
                        }
 
1008
 
 
1009
                        public static string GetName(object wrapper)
 
1010
                        {
 
1011
                                TypeWrapper typeWrapper = (TypeWrapper)wrapper;
 
1012
                                if(typeWrapper.IsPrimitive)
 
1013
                                {
 
1014
                                        if(typeWrapper == PrimitiveTypeWrapper.VOID)
 
1015
                                        {
 
1016
                                                return "void";
 
1017
                                        }
 
1018
                                        else if(typeWrapper == PrimitiveTypeWrapper.BYTE)
 
1019
                                        {
 
1020
                                                return "byte";
 
1021
                                        }
 
1022
                                        else if(typeWrapper == PrimitiveTypeWrapper.BOOLEAN)
 
1023
                                        {
 
1024
                                                return "boolean";
 
1025
                                        }
 
1026
                                        else if(typeWrapper == PrimitiveTypeWrapper.SHORT)
 
1027
                                        {
 
1028
                                                return "short";
 
1029
                                        }
 
1030
                                        else if(typeWrapper == PrimitiveTypeWrapper.CHAR)
 
1031
                                        {
 
1032
                                                return "char";
 
1033
                                        }
 
1034
                                        else if(typeWrapper == PrimitiveTypeWrapper.INT)
 
1035
                                        {
 
1036
                                                return "int";
 
1037
                                        }
 
1038
                                        else if(typeWrapper == PrimitiveTypeWrapper.LONG)
 
1039
                                        {
 
1040
                                                return "long";
 
1041
                                        }
 
1042
                                        else if(typeWrapper == PrimitiveTypeWrapper.FLOAT)
 
1043
                                        {
 
1044
                                                return "float";
 
1045
                                        }
 
1046
                                        else if(typeWrapper == PrimitiveTypeWrapper.DOUBLE)
 
1047
                                        {
 
1048
                                                return "double";
 
1049
                                        }
 
1050
                                        else
 
1051
                                        {
 
1052
                                                throw new InvalidOperationException();
 
1053
                                        }
 
1054
                                }
 
1055
                                return typeWrapper.Name;
 
1056
                        }
 
1057
        
 
1058
                        public static void initialize(object cwrapper)
 
1059
                        {
 
1060
                                TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1061
                                wrapper.Finish();
 
1062
                                wrapper.RunClassInit();
 
1063
                        }
 
1064
 
 
1065
                        public static object getClassLoader0(object wrapper)
 
1066
                        {
 
1067
                                return ((TypeWrapper)wrapper).GetClassLoader().GetJavaClassLoader();
 
1068
                        }
 
1069
 
 
1070
                        public static object getClassLoaderFromType(Type type)
 
1071
                        {
 
1072
                                return ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader().GetJavaClassLoader();
 
1073
                        }
 
1074
 
 
1075
                        public static object[] GetDeclaredMethods(object cwrapper, bool getMethods, bool publicOnly)
 
1076
                        {
 
1077
                                Profiler.Enter("VMClass.GetDeclaredMethods");
 
1078
                                try
 
1079
                                {
 
1080
                                        TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1081
                                        // we need to finish the type otherwise all methods will not be in the method map yet
 
1082
                                        wrapper.Finish();
 
1083
                                        // we need to look through the array for unloadable types, because we may not let them
 
1084
                                        // escape into the 'wild'
 
1085
                                        MethodWrapper[] methods = wrapper.GetMethods();
 
1086
                                        ArrayList list = new ArrayList();
 
1087
                                        for(int i = 0; i < methods.Length; i++)
 
1088
                                        {
 
1089
                                                // we don't want to expose "hideFromReflection" methods (one reason is that it would
 
1090
                                                // mess up the serialVersionUID computation)
 
1091
                                                if(!methods[i].IsHideFromReflection)
 
1092
                                                {
 
1093
                                                        if(methods[i].Name == "<clinit>")
 
1094
                                                        {
 
1095
                                                                // not reported back
 
1096
                                                        }
 
1097
                                                        else if(publicOnly && !methods[i].IsPublic)
 
1098
                                                        {
 
1099
                                                                // caller is only asking for public methods, so we don't return this non-public method
 
1100
                                                        }
 
1101
                                                        else if((methods[i].Name == "<init>") != getMethods)
 
1102
                                                        {
 
1103
                                                                if(methods[i].ReturnType.IsUnloadable)
 
1104
                                                                {
 
1105
                                                                        throw JavaException.NoClassDefFoundError(methods[i].ReturnType.Name);
 
1106
                                                                }
 
1107
                                                                TypeWrapper[] args = methods[i].GetParameters();
 
1108
                                                                for(int j = 0; j < args.Length; j++)
 
1109
                                                                {
 
1110
                                                                        if(args[j].IsUnloadable)
 
1111
                                                                        {
 
1112
                                                                                throw JavaException.NoClassDefFoundError(args[j].Name);
 
1113
                                                                        }
 
1114
                                                                }
 
1115
                                                                list.Add(methods[i]);
 
1116
                                                        }
 
1117
                                                }
 
1118
                                        }
 
1119
                                        return (MethodWrapper[])list.ToArray(typeof(MethodWrapper));
 
1120
                                }
 
1121
                                finally
 
1122
                                {
 
1123
                                        Profiler.Leave("VMClass.GetDeclaredMethods");
 
1124
                                }
 
1125
                        }
 
1126
 
 
1127
                        public static object[] GetDeclaredFields(object cwrapper, bool publicOnly)
 
1128
                        {
 
1129
                                Profiler.Enter("VMClass.GetDeclaredFields");
 
1130
                                try
 
1131
                                {
 
1132
                                        TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1133
                                        // we need to finish the type otherwise all fields will not be in the field map yet
 
1134
                                        wrapper.Finish();
 
1135
                                        // we need to look through the array for unloadable types, because we may not let them
 
1136
                                        // escape into the 'wild'
 
1137
                                        FieldWrapper[] fields = wrapper.GetFields();
 
1138
                                        if(publicOnly)
 
1139
                                        {
 
1140
                                                ArrayList list = new ArrayList();
 
1141
                                                for(int i = 0; i < fields.Length; i++)
 
1142
                                                {
 
1143
                                                        if(fields[i].IsPublic)
 
1144
                                                        {
 
1145
                                                                list.Add(fields[i]);
 
1146
                                                        }
 
1147
                                                }
 
1148
                                                fields = (FieldWrapper[])list.ToArray(typeof(FieldWrapper));
 
1149
                                        }
 
1150
                                        for(int i = 0; i < fields.Length; i++)
 
1151
                                        {
 
1152
                                                if(fields[i].FieldTypeWrapper.IsUnloadable)
 
1153
                                                {
 
1154
                                                        throw JavaException.NoClassDefFoundError(fields[i].FieldTypeWrapper.Name);
 
1155
                                                }
 
1156
                                        }
 
1157
                                        return fields;
 
1158
                                }
 
1159
                                finally
 
1160
                                {
 
1161
                                        Profiler.Leave("VMClass.GetDeclaredFields");
 
1162
                                }
 
1163
                        }
 
1164
 
 
1165
                        public static object[] GetDeclaredClasses(object cwrapper, bool publicOnly)
 
1166
                        {
 
1167
                                TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1168
                                // NOTE to get at the InnerClasses we need to finish the type
 
1169
                                wrapper.Finish();
 
1170
                                TypeWrapper[] wrappers = wrapper.InnerClasses;
 
1171
                                if(publicOnly)
 
1172
                                {
 
1173
                                        ArrayList list = new ArrayList();
 
1174
                                        for(int i = 0; i < wrappers.Length; i++)
 
1175
                                        {
 
1176
                                                if(wrappers[i].IsUnloadable)
 
1177
                                                {
 
1178
                                                        throw JavaException.NoClassDefFoundError(wrappers[i].Name);
 
1179
                                                }
 
1180
                                                // because the VM lacks any support for nested visibility control, we
 
1181
                                                // cannot rely on the publicness of the type here, but instead we have
 
1182
                                                // to look at the reflective modifiers
 
1183
                                                wrappers[i].Finish();
 
1184
                                                if((wrappers[i].ReflectiveModifiers & Modifiers.Public) != 0)
 
1185
                                                {
 
1186
                                                        list.Add(wrappers[i]);
 
1187
                                                }
 
1188
                                        }
 
1189
                                        wrappers = (TypeWrapper[])list.ToArray(typeof(TypeWrapper));
 
1190
                                }
 
1191
                                object[] innerclasses = new object[wrappers.Length];
 
1192
                                for(int i = 0; i < innerclasses.Length; i++)
 
1193
                                {
 
1194
                                        if(wrappers[i].IsUnloadable)
 
1195
                                        {
 
1196
                                                throw JavaException.NoClassDefFoundError(wrappers[i].Name);
 
1197
                                        }
 
1198
                                        innerclasses[i] = getClassFromWrapper(wrappers[i]);
 
1199
                                }
 
1200
                                return innerclasses;
 
1201
                        }
 
1202
 
 
1203
                        public static object GetDeclaringClass(object cwrapper)
 
1204
                        {
 
1205
                                TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1206
                                // before we can call DeclaringTypeWrapper, we need to finish the type
 
1207
                                wrapper.Finish();
 
1208
                                TypeWrapper declaring = wrapper.DeclaringTypeWrapper;
 
1209
                                if(declaring == null)
 
1210
                                {
 
1211
                                        return null;
 
1212
                                }
 
1213
                                if(declaring.IsUnloadable)
 
1214
                                {
 
1215
                                        throw JavaException.NoClassDefFoundError(declaring.Name);
 
1216
                                }
 
1217
                                return getClassFromWrapper(declaring);
 
1218
                        }
 
1219
 
 
1220
                        public static object[] GetInterfaces(object cwrapper)
 
1221
                        {
 
1222
                                TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1223
                                // we need to finish the type otherwise all fields will not be in the field map yet
 
1224
                                // TODO this should not be needed (make sure it isn't and remove)
 
1225
                                wrapper.Finish();
 
1226
                                TypeWrapper[] interfaceWrappers = wrapper.Interfaces;
 
1227
                                object[] interfaces = new object[interfaceWrappers.Length];
 
1228
                                for(int i = 0; i < interfaces.Length; i++)
 
1229
                                {
 
1230
                                        interfaces[i] = getClassFromWrapper(interfaceWrappers[i]);
 
1231
                                }
 
1232
                                return interfaces;
 
1233
                        }
 
1234
 
 
1235
                        public static int GetModifiers(Object cwrapper)
 
1236
                        {
 
1237
                                TypeWrapper wrapper = (TypeWrapper)cwrapper;
 
1238
                                // NOTE ReflectiveModifiers is only available for finished types
 
1239
                                wrapper.Finish();
 
1240
                                // NOTE we don't return the modifiers from the TypeWrapper, because for inner classes
 
1241
                                // the reflected modifiers are different from the physical ones
 
1242
                                Modifiers modifiers = wrapper.ReflectiveModifiers;
 
1243
                                // only returns public, protected, private, final, static, abstract and interface (as per
 
1244
                                // the documentation of Class.getModifiers())
 
1245
                                Modifiers mask = Modifiers.Public | Modifiers.Protected | Modifiers.Private | Modifiers.Final |
 
1246
                                        Modifiers.Static | Modifiers.Abstract | Modifiers.Interface;
 
1247
                                return (int)(modifiers & mask);
 
1248
                        }
 
1249
                }
 
1250
        }
 
1251
 
 
1252
        namespace io
 
1253
        {
 
1254
                public class VMObjectStreamClass
 
1255
                {
 
1256
                        public static bool hasClassInitializer(object clazz)
 
1257
                        {
 
1258
                                TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz);
 
1259
                                wrapper.Finish();
 
1260
                                Type type = wrapper.TypeAsTBD;
 
1261
                                try
 
1262
                                {
 
1263
                                        if(!type.IsArray && type.TypeInitializer != null)
 
1264
                                        {
 
1265
                                                return !AttributeHelper.IsHideFromReflection(type.TypeInitializer);
 
1266
                                        }
 
1267
                                        return false;
 
1268
                                }
 
1269
                                catch(Exception x)
 
1270
                                {
 
1271
                                        Console.WriteLine(type.FullName);
 
1272
                                        Console.WriteLine(x);
 
1273
                                        return false;
 
1274
                                }
 
1275
                        }
 
1276
 
 
1277
                        private static FieldWrapper GetFieldWrapperFromField(object field)
 
1278
                        {
 
1279
                                // TODO optimize this
 
1280
                                return (FieldWrapper)field.GetType().GetField("fieldCookie", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(field);
 
1281
                        }
 
1282
 
 
1283
                        public static void setDoubleNative(object field, object obj, double val)
 
1284
                        {
 
1285
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1286
                        }
 
1287
 
 
1288
                        public static void setFloatNative(object field, object obj, float val)
 
1289
                        {
 
1290
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1291
                        }
 
1292
 
 
1293
                        public static void setLongNative(object field, object obj, long val)
 
1294
                        {
 
1295
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1296
                        }
 
1297
 
 
1298
                        public static void setIntNative(object field, object obj, int val)
 
1299
                        {
 
1300
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1301
                        }
 
1302
 
 
1303
                        public static void setShortNative(object field, object obj, short val)
 
1304
                        {
 
1305
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1306
                        }
 
1307
 
 
1308
                        public static void setCharNative(object field, object obj, char val)
 
1309
                        {
 
1310
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1311
                        }
 
1312
 
 
1313
                        public static void setByteNative(object field, object obj, sbyte val)
 
1314
                        {
 
1315
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1316
                        }
 
1317
 
 
1318
                        public static void setBooleanNative(object field, object obj, bool val)
 
1319
                        {
 
1320
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1321
                        }
 
1322
 
 
1323
                        public static void setObjectNative(object field, object obj, object val)
 
1324
                        {
 
1325
                                GetFieldWrapperFromField(field).SetValue(obj, val);
 
1326
                        }
 
1327
                }
 
1328
 
 
1329
                public class ObjectInputStream
 
1330
                {
 
1331
                        public static object currentClassLoader(object sm)
 
1332
                        {
 
1333
                                // TODO calling currentClassLoader in SecurityManager results in null being returned, so we use our own
 
1334
                                // version for now, don't know what the security implications of this are
 
1335
                                // SECURITY
 
1336
                                return NativeCode.java.lang.VMSecurityManager.currentClassLoader();
 
1337
                        }
 
1338
 
 
1339
                        public static object allocateObject(object ois, object clazz)
 
1340
                        {
 
1341
                                Profiler.Enter("ObjectInputStream.allocateObject");
 
1342
                                try
 
1343
                                {
 
1344
                                        return JniHelper.AllocObject(clazz);
 
1345
                                }
 
1346
                                finally
 
1347
                                {
 
1348
                                        Profiler.Leave("ObjectInputStream.allocateObject");
 
1349
                                }
 
1350
                        }
 
1351
 
 
1352
                        public static void callConstructor(object ois, object clazz, object obj)
 
1353
                        {
 
1354
                                Profiler.Enter("ObjectInputStream.callConstructor");
 
1355
                                try
 
1356
                                {
 
1357
                                        TypeWrapper type = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz);
 
1358
                                        type.Finish();
 
1359
                                        MethodWrapper mw = type.GetMethodWrapper(MethodDescriptor.FromNameSig(type.GetClassLoader(), "<init>", "()V"), false);
 
1360
                                        if(mw == null)
 
1361
                                        {
 
1362
                                                // TODO what should we do here?
 
1363
                                                throw new NotImplementedException();
 
1364
                                        }
 
1365
                                        // TODO what about exceptions? (should they be unwrapped?)
 
1366
                                        mw.Invoke(obj, null, true);
 
1367
                                }
 
1368
                                finally
 
1369
                                {
 
1370
                                        Profiler.Leave("ObjectInputStream.callConstructor");
 
1371
                                }
 
1372
                        }
 
1373
                }
 
1374
        }
 
1375
 
 
1376
        namespace util
 
1377
        {
 
1378
                public class TimeZone
 
1379
                {
 
1380
                        public static string getDefaultTimeZoneId()
 
1381
                        {
 
1382
                                NetSystem.TimeZone currentTimeZone = NetSystem.TimeZone.CurrentTimeZone;
 
1383
                                NetSystem.TimeSpan timeSpan = currentTimeZone.GetUtcOffset(DateTime.Now);
 
1384
 
 
1385
                                int hours = timeSpan.Hours;
 
1386
                                int mins = timeSpan.Minutes;
 
1387
 
 
1388
                                return "GMT" + hours + ":" + mins;
 
1389
                        }
 
1390
                }
 
1391
        }
 
1392
 
 
1393
        namespace net
 
1394
        {
 
1395
                public class InetAddress
 
1396
                {
 
1397
                        public static sbyte[] lookupInaddrAny()
 
1398
                        {
 
1399
                                return new sbyte[] { 0, 0, 0, 0 };
 
1400
                        }
 
1401
 
 
1402
                        public static string getLocalHostname()
 
1403
                        {
 
1404
                                // TODO error handling
 
1405
                                return NetSystem.Net.Dns.GetHostName();
 
1406
                        }
 
1407
 
 
1408
                        public static sbyte[][] getHostByName(string name)
 
1409
                        {
 
1410
                                // TODO error handling
 
1411
                                try
 
1412
                                {
 
1413
                                        NetSystem.Net.IPHostEntry he = NetSystem.Net.Dns.GetHostByName(name);
 
1414
                                        NetSystem.Net.IPAddress[] addresses = he.AddressList;
 
1415
                                        sbyte[][] list = new sbyte[addresses.Length][];
 
1416
                                        for(int i = 0; i < addresses.Length; i++)
 
1417
                                        {
 
1418
                                                byte[] address = addresses[i].GetAddressBytes();
 
1419
                                                sbyte[] sb = new sbyte[address.Length];
 
1420
                                                for(int j = 0; j < sb.Length; j++)
 
1421
                                                {
 
1422
                                                        sb[j] = (sbyte)address[j];
 
1423
                                                }
 
1424
                                                list[i] = sb;
 
1425
                                        }
 
1426
                                        return list;
 
1427
                                }
 
1428
                                catch(Exception x)
 
1429
                                {
 
1430
                                        throw JavaException.UnknownHostException(x.Message);
 
1431
                                }
 
1432
                        }
 
1433
 
 
1434
                        public static string getHostByAddr(byte[] address)
 
1435
                        {
 
1436
                                string s;
 
1437
                                try
 
1438
                                {
 
1439
                                        s = NetSystem.Net.Dns.GetHostByAddress(string.Format("{0}.{1}.{2}.{3}", address[0], address[1], address[2], address[3])).HostName;
 
1440
                                }
 
1441
                                catch(NetSystem.Net.Sockets.SocketException x)
 
1442
                                {
 
1443
                                        throw JavaException.UnknownHostException(x.Message);
 
1444
                                }
 
1445
                                try
 
1446
                                {
 
1447
                                        NetSystem.Net.Dns.GetHostByName(s);
 
1448
                                }
 
1449
                                catch(NetSystem.Net.Sockets.SocketException)
 
1450
                                {
 
1451
                                        // FXBUG .NET framework bug
 
1452
                                        // HACK if GetHostByAddress returns a netbios name, it appends the default DNS suffix, but if the
 
1453
                                        // machine's netbios name isn't the same as the DNS hostname, this might result in an unresolvable
 
1454
                                        // name, if that happens we chop of the DNS suffix.
 
1455
                                        int idx = s.IndexOf('.');
 
1456
                                        if(idx > 0)
 
1457
                                        {
 
1458
                                                return s.Substring(0, idx);
 
1459
                                        }
 
1460
                                }
 
1461
                                return s;
 
1462
                        }
 
1463
                }
 
1464
        }
 
1465
}