31#if FIRST_PASS == false && IMPORTER == false && EXPORTER == false
33 static CallerIDAccessor callerIDAccessor;
34 static ClassAccessor classAccessor;
35 static MethodAccessor methodAccessor;
36 static SystemAccessor systemAccessor;
37 static ThreadAccessor threadAccessor;
38 static ThreadGroupAccessor threadGroupAccessor;
39 static LauncherHelperAccessor launcherHelperAccessor;
41 static CallerIDAccessor CallerIDAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref callerIDAccessor);
43 static ClassAccessor ClassAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref classAccessor);
45 static MethodAccessor MethodAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref methodAccessor);
47 static SystemAccessor SystemAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref systemAccessor);
49 static ThreadAccessor ThreadAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref threadAccessor);
51 static ThreadGroupAccessor ThreadGroupAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref threadGroupAccessor);
53 static LauncherHelperAccessor LauncherHelperAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref launcherHelperAccessor);
63 [JsonPropertyName(
"processId")]
64 public int ProcessId {
get;
set; }
74 static IEnumerable<string> Prepend(IEnumerable<string> source,
string value)
77 foreach (var i
in source)
86 static string[] Glob(
string path)
90 var dir = Path.GetDirectoryName(path);
94 var list =
new List<string>();
95 foreach (var fsi
in new DirectoryInfo(dir ?? Environment.CurrentDirectory).GetFileSystemInfos(Path.GetFileName(path)))
96 list.Add(dir !=
null ? Path.Combine(dir, fsi.Name) : fsi.Name);
101 return list.ToArray();
114 static string[] Glob(
string[] paths)
116 var list =
new List<string>();
117 for (var i = 0; i < paths.Length; i++)
120 if (path.Contains(
'*') || path.Contains(
'?'))
121 list.AddRange(Glob(path));
126 return list.ToArray();
133 static void SetUserProperties(IDictionary<string, string> properties)
135#if FIRST_PASS || IMPORTER
136 throw new NotImplementedException();
138 if (properties is
null)
139 throw new ArgumentNullException(nameof(properties));
141 foreach (var kvp
in properties)
149 static void EnterMainThread()
151#if FIRST_PASS || IMPORTER
152 throw new NotImplementedException();
154 if (Thread.CurrentThread.Name ==
null)
158 Thread.CurrentThread.Name =
"main";
160 catch (InvalidOperationException)
167 ThreadAccessor.InvokeCurrentThread();
172 sun.misc.Signal.handle(
new sun.misc.Signal(
"BREAK"), sun.misc.SignalHandler.SIG_DFL);
174 catch (
java.
lang.IllegalArgumentException)
184 static void ExitMainThread()
186#if FIRST_PASS || IMPORTER
187 throw new NotImplementedException();
194 ThreadAccessor.InvokeDie(ThreadAccessor.InvokeCurrentThread());
202 static string GetVersionAndCopyrightInfo()
204 var assembly = typeof(
Launcher).Assembly;
205 var copyright = assembly.GetCustomAttributes<AssemblyCopyrightAttribute>().FirstOrDefault();
206 if (copyright is not
null)
207 return $
"IKVM version {assembly.GetName().Version}{Environment.NewLine}{copyright.Copyright}";
215 static void PrintVersion()
217#if FIRST_PASS || IMPORTER
218 throw new NotImplementedException();
220 Console.WriteLine(GetVersionAndCopyrightInfo());
221 Console.WriteLine(
"CLR version: {0} ({1} bit)", Environment.Version, IntPtr.Size * 8);
222 var ver = SystemAccessor.InvokeGetProperty(
"openjdk.version");
224 Console.WriteLine(
"OpenJDK version: {0}", ver);
232 static void AddBootClassPathAssembly(
Assembly assembly)
234#if FIRST_PASS || IMPORTER
235 throw new NotImplementedException();
247 static bool ArgEquals(ReadOnlySpan<char> a,
string b)
249 return a.Equals(b.AsSpan(), StringComparison.Ordinal);
263 public static int Run(
Assembly assembly,
string main,
bool jar,
string[] args,
string rarg, IDictionary<string, string> properties)
266 throw new ArgumentNullException(nameof(args));
268#if FIRST_PASS || IMPORTER
269 throw new NotImplementedException();
274 var initialize = properties !=
null ?
new Dictionary<string, string>(properties) :
new Dictionary<string, string>();
275 var showversion =
false;
277 var hasMainArg =
false;
278 var jvmArgs = args.Where(i => rarg !=
null).Where(i => i.StartsWith(rarg)).Select(i => i.Substring(rarg.Length)).ToList();
279 var appArgs = args.Where(i => rarg ==
null || i.StartsWith(rarg) ==
false).ToList();
280 var appArgsReset =
false;
283 initialize[
"java.class.path"] =
".";
284 if (Environment.GetEnvironmentVariable(
"CLASSPATH") is
string cp && !
string.IsNullOrEmpty(cp))
285 initialize[
"java.class.path"] =
string.Join(Path.PathSeparator.ToString(), Glob(cp.Split(Path.PathSeparator)));
288 if (Environment.GetEnvironmentVariable(
"IKVM_HOME_ROOT") is
string ihr && !
string.IsNullOrEmpty(ihr))
289 initialize[
"ikvm.home.root"] = ihr;
292 if (Environment.GetEnvironmentVariable(
"IKVM_HOME") is
string ih && !
string.IsNullOrEmpty(ih))
293 initialize[
"ikvm.home"] = ih;
296 for (var jvmArg = jvmArgs.GetEnumerator(); jvmArg.MoveNext();)
298 var arg = jvmArg.Current.AsSpan();
299 if (hasMainArg ==
false && arg.StartsWith(
"-".AsSpan()))
302 if (arg.StartsWith(
"-D".AsSpan()))
304 var def = arg.Slice(2);
305 var sep = def.IndexOf(
'=');
306 var key = sep > -1 ? def.Slice(0, sep) : def;
307 var val = sep > -1 ? def.Slice(sep + 1) :
"".AsSpan();
308 initialize[key.ToString()] = val.ToString();
312 if (ArgEquals(arg,
"-ea") || ArgEquals(arg,
"-enableassertions"))
318 if (arg.StartsWith(
"-ea:".AsSpan()) || arg.StartsWith(
"-enableassertions:".AsSpan()))
320 if (arg.IndexOf(
':') is
int v && v > -1)
324 if (ArgEquals(arg,
"-da") || ArgEquals(arg,
"-disableassertions"))
330 if (arg.StartsWith(
"-da:".AsSpan()) || arg.StartsWith(
"-disableassertions:".AsSpan()))
332 if (arg.IndexOf(
':') is
int v && v > -1)
336 if (ArgEquals(arg,
"-esa") || ArgEquals(arg,
"-enablesystemassertions"))
342 if (ArgEquals(arg,
"-dsa") || ArgEquals(arg,
"-disablesystemassertions"))
348 if (ArgEquals(arg,
"-cp") || ArgEquals(arg,
"-classpath"))
350 if (jvmArg.MoveNext() ==
false)
352 Console.Error.WriteLine(
"Error: {0} requires class path specification", arg.ToString());
357 initialize[
"java.class.path"] =
string.Join(Path.PathSeparator.ToString(), Glob(jvmArg.Current.Split(Path.PathSeparator)));
361 if (ArgEquals(arg,
"-version"))
368 if (ArgEquals(arg,
"-showversion"))
374 if (ArgEquals(arg,
"-jar"))
380 if (ArgEquals(arg,
"-?") || ArgEquals(arg,
"-help"))
386 if (ArgEquals(arg,
"-X"))
392 if (ArgEquals(arg,
"-Xtime"))
394 Console.Error.WriteLine(
"Unrecognized option: {0}", arg.ToString());
398 if (ArgEquals(arg,
"-Xbreak"))
404 if (ArgEquals(arg,
"-Xverify"))
406 JVM.RelaxedVerification =
false;
410 if (arg.StartsWith(
"-Xreference:".AsSpan()))
412 if (arg.IndexOf(
':') is
int v && v > -1)
413 AddBootClassPathAssembly(
Assembly.LoadFrom(arg.Slice(v + 1).ToString()));
418 if (ArgEquals(arg,
"-XX:+AllowNonVirtualCalls"))
420 JVM.AllowNonVirtualCalls =
true;
424 if (arg.StartsWith(
"-Xms".AsSpan()) ||
425 arg.StartsWith(
"-Xmx".AsSpan()) ||
426 arg.StartsWith(
"-Xmn".AsSpan()) ||
427 arg.StartsWith(
"-Xss".AsSpan()) ||
428 arg.StartsWith(
"-XX:".AsSpan()) ||
429 arg.StartsWith(
"-mn".AsSpan()) ||
430 arg.StartsWith(
"-ms".AsSpan()) ||
431 arg.StartsWith(
"-mx".AsSpan()) ||
432 ArgEquals(arg,
"-Xmixed") ||
433 ArgEquals(arg,
"-Xint") ||
434 ArgEquals(arg,
"-Xincgc") ||
435 ArgEquals(arg,
"-Xbatch") ||
436 ArgEquals(arg,
"-Xfuture") ||
437 ArgEquals(arg,
"-Xrs") ||
438 ArgEquals(arg,
"-Xcheck:jni") ||
439 ArgEquals(arg,
"-Xshare:off") ||
440 ArgEquals(arg,
"-Xshare:auto") ||
441 ArgEquals(arg,
"-Xshare:on"))
443 Console.Error.WriteLine(
"Ignoring unrecognized option: {0}", arg.ToString());
447 Console.Error.WriteLine(
"Unrecognized option: {0}", arg.ToString());
450 else if (hasMainArg ==
false)
453 main = arg.ToString();
459 if (appArgsReset ==
false)
466 appArgs.Add(arg.ToString());
475 initialize[
"java.class.path"] = main;
478 initialize[
"sun.java.command"] =
string.Join(
" ", Prepend(appArgs, main));
479 initialize[
"sun.java.launcher"] =
"SUN_STANDARD";
482 SetUserProperties(initialize);
489 if (assembly !=
null)
490 AddBootClassPathAssembly(assembly);
511 var clazz = LauncherHelperAccessor.InvokeCheckAndLoadMain(
true, jar ? 2 : 1, main);
512 SystemAccessor.InvokeSetProperty(
"sun.java.command", initialize[
"sun.java.command"]);
515 var method = ClassAccessor.InvokeGetMethod(clazz,
"main", ClassAccessor.InitArray(
JVM.Context.
ClassLoaderFactory.GetJavaTypeFromType(typeof(
string[])).ClassObject), CallerIDAccessor.InvokeCreate(typeof(
Launcher).TypeHandle));
516 MethodAccessor.InvokeSetAccessible(method,
true);
521 MethodAccessor.InvokeInvoke(method,
null,
new[] { appArgs.ToArray() });
524 catch (
java.
lang.reflect.InvocationTargetException e)
527 ExceptionDispatchInfo.Capture(e.getCause()).Throw();
533 var thread = ThreadAccessor.InvokeCurrentThread();
534 ThreadGroupAccessor.InvokeUncaughtException(ThreadAccessor.InvokeGetThreadGroup(thread), thread, ikvm.runtime.Util.mapException(e));
548 static void HandleDebugTrace()
551 var debugUri = (Uri)
null;
554 if (Environment.GetEnvironmentVariable(
"IKVM_DEBUG_WAIT") is
string debugWait_)
555 if (
int.TryParse(debugWait_, out var i))
559 if (Environment.GetEnvironmentVariable(
"IKVM_DEBUG_URI") is
string debugUri_)
560 if (Uri.TryCreate(debugUri_, UriKind.Absolute, out var u))
564 if (debugUri !=
null)
566 if (debugUri.Scheme ==
"tcp" && IPAddress.TryParse(debugUri.Host, out var ip) && debugUri.Port > 0)
568 var message = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(
new IkvmStartEvent() { ProcessId = Process.GetCurrentProcess().Id, }));
569 using var c =
new TcpClient();
570 c.Connect(
new IPEndPoint(ip, debugUri.Port));
571 c.GetStream().Write(message, 0, message.Length);
572 c.GetStream().WriteByte(0);
573 c.GetStream().Flush();
578 Console.Error.WriteLine(
"Invalid debug URI: {0}", debugUri);
585 Console.Write(
"Waiting for debugger...");
588 var cts =
new CancellationTokenSource(TimeSpan.FromSeconds(debugWait));
589 while (Debugger.IsAttached ==
false && cts.IsCancellationRequested ==
false)
598 if (Debugger.IsAttached ==
false && cts.IsCancellationRequested)
599 Console.Error.WriteLine(
"Debugger wait timed out.");
606 static void PrintHelp()
608 var exe = Process.GetCurrentProcess().ProcessName;
609 Console.Error.WriteLine(
"Usage: {0} [-options] class [args...]", exe);
610 Console.Error.WriteLine(
" (to execute a class)");
611 Console.Error.WriteLine(
" or {0} [-options] -jar jarfile [args...]", exe);
612 Console.Error.WriteLine(
" (to execute a jar file)");
613 Console.Error.WriteLine();
614 Console.Error.WriteLine(
"where options include:");
615 Console.Error.WriteLine(
" -cp <class search path of directories and zip/jar files>");
616 Console.Error.WriteLine(
" -classpath <class search path of directories and zip/jar files>");
617 Console.Error.WriteLine(
" A {0} separated list of directories, JAR archives,",
System.IO.Path.PathSeparator);
618 Console.Error.WriteLine(
" and ZIP archives to search for class files.");
619 Console.Error.WriteLine(
" -D<name>=<value>");
620 Console.Error.WriteLine(
" set a system property");
621 Console.Error.WriteLine(
" -version print product version and exit");
622 Console.Error.WriteLine(
" -showversion print product version and continue");
623 Console.Error.WriteLine(
" -? -help Display this message");
624 Console.Error.WriteLine(
" -X Display non-standard options");
625 Console.Error.WriteLine(
" -ea[:<packagename>...|:<classname>]");
626 Console.Error.WriteLine(
" -enableassertions[:<packagename>...|:<classname>]");
627 Console.Error.WriteLine(
" enable assertions with specified granularity");
628 Console.Error.WriteLine(
" -da[:<packagename>...|:<classname>]");
629 Console.Error.WriteLine(
" -disableassertions[:<packagename>...|:<classname>]");
630 Console.Error.WriteLine(
" disable assertions with specified granularity");
631 Console.Error.WriteLine(
" -esa | -enablesystemassertions");
632 Console.Error.WriteLine(
" enable system assertions");
633 Console.Error.WriteLine(
" -dsa | -enablesystemassertions");
634 Console.Error.WriteLine(
" disable system assertions");
635 Console.Error.WriteLine(
" -agentlib:<libname>[=<options>]");
636 Console.Error.WriteLine(
" load native agent library <libname>, e.g. -agentlib:hprof");
637 Console.Error.WriteLine(
" see also, -agentlib:jdwp=help and -agentlib:hprof=help");
638 Console.Error.WriteLine(
" -agentpath:<pathname>[=<options>]");
639 Console.Error.WriteLine(
" load native agent library by full pathname");
640 Console.Error.WriteLine(
" -javaagent:<jarpath>[=<options>]");
641 Console.Error.WriteLine(
" load Java programming language agent, see java.lang.instrument");
642 Console.Error.WriteLine(
" -splash:<imagepath>");
643 Console.Error.WriteLine(
" show splash screen with specified image");
644 Console.Error.WriteLine(
"See http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details.");
645 Console.Error.WriteLine(
"");
651 static void PrintXHelp()
653 Console.Error.WriteLine(
" -Xnoclassgc disable class garbage collection");
654 Console.Error.WriteLine(
" -Xtime time the execution");
655 Console.Error.WriteLine(
" -Xwait keep process hanging around after exit");
656 Console.Error.WriteLine(
" -Xbreak trigger a user defined breakpoint at startup");
657 Console.Error.WriteLine(
" -Xnoglobbing Disable argument globbing");
658 Console.Error.WriteLine(
" -Xverify Enable strict class file verification");
659 Console.Error.WriteLine();
660 Console.Error.WriteLine(
"The -X options are non-standard and subject to change without notice.");
661 Console.Error.WriteLine();
RuntimeAssemblyClassLoaderFactory AssemblyClassLoaderFactory
Gets the RuntimeAssemblyClassLoaderFactory associated with this instance of the runtime.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.