IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
JVM.cs
Go to the documentation of this file.
1using System;
2using System.Diagnostics;
4using System.Runtime.ExceptionServices;
5using System.Security;
6using System.Text;
7using System.Threading;
8
11
12namespace IKVM.Runtime
13{
14
18 public static partial class JVM
19 {
20
21 static readonly object syncRoot = new object();
22 static bool initialized;
23
24#if EXPORTER == false
25 static int emitSymbols;
26 internal static bool RelaxedVerification = true;
27 internal static bool AllowNonVirtualCalls;
28 internal static readonly bool DisableEagerClassLoading = SafeGetEnvironmentVariable("IKVM_DISABLE_EAGER_CLASS_LOADING") != null;
29#endif
30
34 internal static void Init()
35 {
36#if FIRST_PASS || IMPORTER || EXPORTER
37 throw new NotImplementedException();
38#else
39 if (initialized == false)
40 {
41 lock (syncRoot)
42 {
43 if (initialized == false)
44 {
45 initialized = true;
46
47 // always required
48 RuntimeHelpers.RunClassConstructor(typeof(java.lang.String).TypeHandle);
49
50 // initialize java_lang.System (needed before creating the thread)
51 RuntimeHelpers.RunClassConstructor(typeof(java.lang.System).TypeHandle);
52
53 // initialize thread groups
54 RuntimeHelpers.RunClassConstructor(typeof(java.lang.ThreadGroup).TypeHandle);
55 RuntimeHelpers.RunClassConstructor(typeof(java.lang.Thread).TypeHandle);
56 GC.KeepAlive(SystemThreadGroup);
57 GC.KeepAlive(MainThreadGroup);
58
59 // the VM creates & returns objects of this class
60 RuntimeHelpers.RunClassConstructor(typeof(java.lang.Class).TypeHandle);
61
62 // the VM preresolves methods to these classes
63 RuntimeHelpers.RunClassConstructor(typeof(java.lang.reflect.Method).TypeHandle);
64
65 // ensure the System class is initialized
66 Internal.SystemAccessor.InvokeInitializeSystemClass();
67
68 // should be done before System, but that fails for now
69 RuntimeHelpers.RunClassConstructor(typeof(java.lang.@ref.Finalizer).TypeHandle);
70
71 // initialize certain classes after System properties are available
72 RuntimeHelpers.RunClassConstructor(typeof(java.lang.OutOfMemoryError).TypeHandle);
73 RuntimeHelpers.RunClassConstructor(typeof(java.lang.NullPointerException).TypeHandle);
74 RuntimeHelpers.RunClassConstructor(typeof(java.lang.ClassCastException).TypeHandle);
75 RuntimeHelpers.RunClassConstructor(typeof(java.lang.ArrayStoreException).TypeHandle);
76 RuntimeHelpers.RunClassConstructor(typeof(java.lang.ArithmeticException).TypeHandle);
77 RuntimeHelpers.RunClassConstructor(typeof(java.lang.StackOverflowError).TypeHandle);
78 RuntimeHelpers.RunClassConstructor(typeof(java.lang.IllegalMonitorStateException).TypeHandle);
79 RuntimeHelpers.RunClassConstructor(typeof(java.lang.IllegalArgumentException).TypeHandle);
80
81 // the static initializer of java.lang.Compiler tries to read property "java.compiler" and read & write property "java.vm.info"
82 RuntimeHelpers.RunClassConstructor(typeof(java.lang.Compiler).TypeHandle);
83
84 // initialize some JSR292 core classes to avoid deadlock during class loading
85 RuntimeHelpers.RunClassConstructor(typeof(java.lang.invoke.MemberName).TypeHandle);
86 RuntimeHelpers.RunClassConstructor(typeof(java.lang.invoke.MethodHandle).TypeHandle);
87 RuntimeHelpers.RunClassConstructor(typeof(java.lang.invoke.MethodHandleNatives).TypeHandle);
88 }
89 }
90 }
91#endif
92 }
93
94#if !IMPORTER && !EXPORTER
95
96 internal static bool EmitSymbols
97 {
98 get
99 {
100 if (emitSymbols == 0)
101 {
102 var state = 2;
103
104#if NETFRAMEWORK
105 // check app.config on Framework
106 if (string.Equals(System.Configuration.ConfigurationManager.AppSettings["ikvm-emit-symbols"] ?? "", "true", StringComparison.OrdinalIgnoreCase))
107 state = 1;
108#endif
109
110 // respect the IKVM_EMIT_SYMBOLs environmental variable
111 if (string.Equals(Environment.GetEnvironmentVariable("IKVM_EMIT_SYMBOLS") ?? "", "true", StringComparison.OrdinalIgnoreCase))
112 state = 1;
113
114 // by default enable symbols if a debugger is attached
115 if (state == 2 && Debugger.IsAttached)
116 state = 1;
117
118 // make sure we only set the value once, because it isn't allowed to changed as that could cause
119 // the compiler to try emitting symbols into a ModuleBuilder that doesn't accept them (and would
120 // throw an InvalidOperationException)
121 Interlocked.CompareExchange(ref emitSymbols, state, 0);
122 }
123
124 return emitSymbols == 1;
125 }
126 }
127
128#endif
129
130#if FIRST_PASS == false && IMPORTER == false && EXPORTER == false
131
135 internal static RuntimeContext Context => Internal.context;
136
140 internal static VfsTable Vfs => Internal.vfs;
141
145 internal static object SystemThreadGroup => Internal.systemThreadGroup.Value;
146
150 internal static object MainThreadGroup => Internal.mainThreadGroup.Value;
151
155 [ThreadStatic]
156 static Exception pendingException;
157
161 internal static Exception GetPendingException()
162 {
163 return pendingException;
164 }
165
170 internal static void SetPendingException(Exception e)
171 {
172 pendingException = e != null ? ikvm.runtime.Util.mapException(e) : null;
173 }
174
178 internal static void ThrowPendingException()
179 {
180 var e = GetPendingException();
181 if (e is not null)
182 {
183 pendingException = null;
184 ExceptionDispatchInfo.Capture(e).Throw();
185 throw null;
186 }
187 }
188
189#endif
190
196 internal static string SafeGetEnvironmentVariable(string name)
197 {
198 try
199 {
200 return Environment.GetEnvironmentVariable(name);
201 }
202 catch (SecurityException)
203 {
204 return null;
205 }
206 }
207
208 internal static string MangleResourceName(string name)
209 {
210 // FXBUG there really shouldn't be any need to mangle the resource names,
211 // but in order for ILDASM/ILASM round tripping to work reliably, we have
212 // to make sure that we don't produce resource names that'll cause ILDASM
213 // to generate invalid filenames.
214 var sb = new ValueStringBuilder(name.Length + 6);
215 sb.Append("ikvm__");
216
217 foreach (var c in name)
218 {
219 if ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+.()$#@~=&{}[]0123456789`".IndexOf(c) != -1)
220 {
221 sb.Append(c);
222 }
223 else if (c == '/')
224 {
225 sb.Append('!');
226 }
227 else
228 {
229 sb.Append('%');
230 sb.Append(string.Format("{0:X4}", (int)c));
231 }
232 }
233
234 return sb.ToString();
235 }
236
242 internal static int PersistableHash(string str)
243 {
244 var key = 1u;
245
246 foreach (char c in str)
247 {
248 key += c;
249 key += (key << 12);
250 key ^= (key >> 22);
251 key += (key << 4);
252 key ^= (key >> 9);
253 key += (key << 10);
254 key ^= (key >> 2);
255 key += (key << 7);
256 key ^= (key >> 12);
257 }
258
259 return (int)key;
260 }
261
262 internal static object Box(object val)
263 {
264#if IMPORTER || FIRST_PASS || EXPORTER
265 throw new NotImplementedException();
266#else
267 return val switch
268 {
269 byte => java.lang.Byte.valueOf((byte)val),
270 bool => java.lang.Boolean.valueOf((bool)val),
271 short => java.lang.Short.valueOf((short)val),
272 char => java.lang.Character.valueOf((char)val),
273 int => java.lang.Integer.valueOf((int)val),
274 float => java.lang.Float.valueOf((float)val),
275 long => java.lang.Long.valueOf((long)val),
276 double => java.lang.Double.valueOf((double)val),
277 _ => throw new java.lang.IllegalArgumentException()
278 };
279#endif
280 }
281
282 internal static object Unbox(object val)
283 {
284#if IMPORTER || FIRST_PASS || EXPORTER
285 throw new NotImplementedException();
286#else
287 return val switch
288 {
289 java.lang.Byte b => b.byteValue(),
290 java.lang.Boolean b1 => b1.booleanValue(),
291 java.lang.Short s => s.shortValue(),
292 java.lang.Character c => c.charValue(),
293 java.lang.Integer i => i.intValue(),
294 java.lang.Float f => f.floatValue(),
295 java.lang.Long l => l.longValue(),
296 java.lang.Double d => d.doubleValue(),
297 _ => throw new java.lang.IllegalArgumentException()
298 };
299#endif
300 }
301
302#if !IMPORTER && !EXPORTER
303
304 internal static object NewAnnotation(java.lang.ClassLoader classLoader, object definition)
305 {
306#if FIRST_PASS
307 throw new NotImplementedException();
308#else
309 java.lang.annotation.Annotation ann = null;
310 try
311 {
312 ann = (java.lang.annotation.Annotation)ikvm.@internal.AnnotationAttributeBase.newAnnotation(classLoader, definition);
313 }
314 catch (java.lang.TypeNotPresentException)
315 {
316
317 }
318
319 if (ann != null && sun.reflect.annotation.AnnotationType.getInstance(ann.annotationType()).retention() == java.lang.annotation.RetentionPolicy.RUNTIME)
320 return ann;
321
322 return null;
323#endif
324 }
325
326#endif
327
328#if !IMPORTER && !EXPORTER
329
330 internal static object NewAnnotationElementValue(java.lang.ClassLoader classLoader, java.lang.Class expectedClass, object definition)
331 {
332#if FIRST_PASS
333 throw new NotImplementedException();
334#else
335 try
336 {
337 return ikvm.@internal.AnnotationAttributeBase.decodeElementValue(definition, expectedClass, classLoader);
338 }
339 catch (java.lang.IllegalAccessException)
340 {
341 // TODO this shouldn't be here
342 return null;
343 }
344#endif
345 }
346
347#endif
348
349 }
350
351}
System.Threading.Interlocked Interlocked
Main state of the running JVM.
Maintains services relevant to an instane of the IKVM runtime.