2
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Threading;
26
#if STATIC_COMPILER || STUB_GENERATOR
27
using IKVM.Reflection;
28
using Type = IKVM.Reflection.Type;
30
using System.Reflection;
33
using System.Diagnostics;
35
using System.Security;
36
using System.Security.Permissions;
39
#if !STATIC_COMPILER && !STUB_GENERATOR
40
namespace IKVM.Internal
42
public static class Starter
44
public static void PrepareForSaveDebugImage()
46
JVM.IsSaveDebugImage = true;
49
public static void SaveDebugImage()
51
DynamicClassLoader.SaveDebugImages();
55
public static java.lang.reflect.Method FindMainMethod(java.lang.Class clazz)
57
// This method exists because we don't use Class.getDeclaredMethods(),
58
// since that could cause us to run into NoClassDefFoundError if any of the
59
// method signatures references a missing class.
60
TypeWrapper tw = TypeWrapper.FromClass(clazz);
61
MethodWrapper mw = tw.GetMethodWrapper("main", "([Ljava.lang.String;)V", true);
62
if (mw != null && mw.IsStatic)
64
return (java.lang.reflect.Method)mw.ToMethodOrConstructor(true);
70
public static bool ClassUnloading
73
get { return JVM.classUnloading; }
74
set { JVM.classUnloading = value; }
81
public static bool RelaxedVerification
83
get { return JVM.relaxedVerification; }
84
set { JVM.relaxedVerification = value; }
88
#endif // !STATIC_COMPILER && !STUB_GENERATOR
90
namespace IKVM.Internal
95
internal const bool FinishingForDebugSave = false;
96
internal const bool IsSaveDebugImage = false;
98
private static bool finishingForDebugSave;
99
private static int emitSymbols;
100
internal static bool IsSaveDebugImage;
102
internal static bool classUnloading = true;
104
#endif // STATIC_COMPILER
105
private static Assembly coreAssembly;
106
internal static bool relaxedVerification = true;
108
internal static Version SafeGetAssemblyVersion(System.Reflection.Assembly asm)
110
// Assembly.GetName().Version requires FileIOPermission,
111
// so we parse the FullName manually :-(
112
string name = asm.FullName;
113
int start = name.IndexOf(", Version=");
117
int end = name.IndexOf(',', start);
120
return new Version(name.Substring(start, end - start));
123
return new Version();
126
internal static string SafeGetEnvironmentVariable(string name)
130
return Environment.GetEnvironmentVariable(name);
132
catch(SecurityException)
138
internal static Assembly CoreAssembly
142
#if !STATIC_COMPILER && !STUB_GENERATOR
143
if(coreAssembly == null)
146
throw new InvalidOperationException("This version of IKVM.Runtime.dll was compiled with FIRST_PASS defined.");
148
coreAssembly = typeof(java.lang.Object).Assembly;
151
#endif // !STATIC_COMPILER
156
coreAssembly = value;
160
#if !STATIC_COMPILER && !STUB_GENERATOR
161
internal static bool FinishingForDebugSave
165
return finishingForDebugSave;
169
finishingForDebugSave = value;
173
internal static bool EmitSymbols
177
if (emitSymbols == 0)
180
string debug = System.Configuration.ConfigurationManager.AppSettings["ikvm-emit-symbols"];
183
state = Debugger.IsAttached ? 1 : 2;
187
state = debug.Equals("True", StringComparison.OrdinalIgnoreCase) ? 1 : 2;
189
// make sure we only set the value once, because it isn't allowed to changed as that could cause
190
// the compiler to try emitting symbols into a ModuleBuilder that doesn't accept them (and would
191
// throw an InvalidOperationException)
192
Interlocked.CompareExchange(ref emitSymbols, state, 0);
194
return emitSymbols == 1;
197
#endif // !STATIC_COMPILER && !STUB_GENERATOR
199
internal static bool IsUnix
203
return Environment.OSVersion.Platform == PlatformID.Unix;
207
internal static string MangleResourceName(string name)
209
// FXBUG there really shouldn't be any need to mangle the resource names,
210
// but in order for ILDASM/ILASM round tripping to work reliably, we have
211
// to make sure that we don't produce resource names that'll cause ILDASM
212
// to generate invalid filenames.
213
StringBuilder sb = new StringBuilder("ikvm__", name.Length + 6);
214
foreach(char c in name)
216
if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+.()$#@~=&{}[]0123456789`".IndexOf(c) != -1)
227
sb.Append(string.Format("{0:X4}", (int)c));
230
return sb.ToString();
233
// based on Bret Mulvey's C# port of Jenkins32
234
// note that this algorithm cannot be changed, because we persist these hashcodes in the metadata of shared class loader assemblies
235
internal static int PersistableHash(string str)
238
foreach (char c in str)
254
internal static void CriticalFailure(string message, Exception x)
258
Tracer.Error(Tracer.Runtime, "CRITICAL FAILURE: {0}", message);
259
System.Type messageBox = null;
261
// NOTE we use reflection to invoke MessageBox.Show, to make sure we run in environments where WinForms isn't available
262
Assembly winForms = IsUnix ? null : Assembly.Load("System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
265
messageBox = winForms.GetType("System.Windows.Forms.MessageBox");
268
message = String.Format("****** Critical Failure: {1} ******{0}{0}" +
269
"PLEASE FILE A BUG REPORT FOR IKVM.NET WHEN YOU SEE THIS MESSAGE{0}{0}" +
270
(messageBox != null ? "(on Windows you can use Ctrl+C to copy the contents of this message to the clipboard){0}{0}" : "") +
277
x != null ? new StackTrace(x, true).ToString() : "",
278
new StackTrace(true));
279
if(messageBox != null)
283
Version ver = SafeGetAssemblyVersion(typeof(JVM).Assembly);
284
messageBox.InvokeMember("Show", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, null, new object[] { message, "IKVM.NET " + ver + " Critical Failure" });
288
Console.Error.WriteLine(message);
293
Console.Error.WriteLine(message);
298
Console.Error.WriteLine(ex);
302
Environment.Exit(666);
305
#endif // !STATIC_COMPILER
307
#if STATIC_COMPILER || STUB_GENERATOR
308
internal static Type LoadType(System.Type type)
310
return StaticCompiler.GetRuntimeType(type.FullName);
314
// this method resolves types in IKVM.Runtime.dll
315
// (the version of IKVM.Runtime.dll that we're running
316
// with can be different from the one we're compiling against.)
317
internal static Type LoadType(Type type)
319
#if STATIC_COMPILER || STUB_GENERATOR
320
return StaticCompiler.GetRuntimeType(type.FullName);
326
internal static object Box(object val)
328
#if STATIC_COMPILER || FIRST_PASS || STUB_GENERATOR
333
return java.lang.Byte.valueOf((byte)val);
337
return java.lang.Boolean.valueOf((bool)val);
339
else if(val is short)
341
return java.lang.Short.valueOf((short)val);
345
return java.lang.Character.valueOf((char)val);
349
return java.lang.Integer.valueOf((int)val);
351
else if(val is float)
353
return java.lang.Float.valueOf((float)val);
357
return java.lang.Long.valueOf((long)val);
359
else if(val is double)
361
return java.lang.Double.valueOf((double)val);
365
throw new java.lang.IllegalArgumentException();
370
internal static object Unbox(object val)
372
#if STATIC_COMPILER || FIRST_PASS || STUB_GENERATOR
375
java.lang.Byte b = val as java.lang.Byte;
378
return b.byteValue();
380
java.lang.Boolean b1 = val as java.lang.Boolean;
383
return b1.booleanValue();
385
java.lang.Short s = val as java.lang.Short;
388
return s.shortValue();
390
java.lang.Character c = val as java.lang.Character;
393
return c.charValue();
395
java.lang.Integer i = val as java.lang.Integer;
400
java.lang.Float f = val as java.lang.Float;
403
return f.floatValue();
405
java.lang.Long l = val as java.lang.Long;
408
return l.longValue();
410
java.lang.Double d = val as java.lang.Double;
413
return d.doubleValue();
417
throw new java.lang.IllegalArgumentException();
422
#if !STATIC_COMPILER && !STUB_GENERATOR
423
internal static object NewAnnotation(object classLoader, object definition)
428
return ikvm.@internal.AnnotationAttributeBase.newAnnotation((java.lang.ClassLoader)classLoader, definition);
433
#if !STATIC_COMPILER && !STUB_GENERATOR
434
internal static object NewAnnotationElementValue(object classLoader, object expectedClass, object definition)
441
return ikvm.@internal.AnnotationAttributeBase.decodeElementValue(definition, (java.lang.Class)expectedClass, (java.lang.ClassLoader)classLoader);
443
catch(java.lang.IllegalAccessException)
445
// TODO this shouldn't be here
452
#if !STATIC_COMPILER && !STUB_GENERATOR
453
// helper for JNI (which doesn't have access to core library internals)
454
internal static object NewDirectByteBuffer(long address, int capacity)
459
return java.nio.DirectByteBuffer.__new(address, capacity);
464
internal static Type Import(System.Type type)
466
#if STATIC_COMPILER || STUB_GENERATOR
467
return StaticCompiler.Universe.Import(type);