264 {
265 if (args is null)
266 throw new ArgumentNullException(nameof(args));
267
268#if FIRST_PASS || IMPORTER
269 throw new NotImplementedException();
270#else
271 HandleDebugTrace();
272
273
274 var initialize = properties != null ? new Dictionary<string, string>(properties) : new Dictionary<string, string>();
275 var showversion = false;
276 var exit = 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;
281
282
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)));
286
287
288 if (Environment.GetEnvironmentVariable("IKVM_HOME_ROOT") is string ihr && !string.IsNullOrEmpty(ihr))
289 initialize["ikvm.home.root"] = ihr;
290
291
292 if (Environment.GetEnvironmentVariable("IKVM_HOME") is string ih && !string.IsNullOrEmpty(ih))
293 initialize["ikvm.home"] = ih;
294
295
296 for (var jvmArg = jvmArgs.GetEnumerator(); jvmArg.MoveNext();)
297 {
298 var arg = jvmArg.Current.AsSpan();
299 if (hasMainArg == false && arg.StartsWith("-".AsSpan()))
300 {
301
302 if (arg.StartsWith("-D".AsSpan()))
303 {
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();
309 continue;
310 }
311
312 if (ArgEquals(arg, "-ea") || ArgEquals(arg, "-enableassertions"))
313 {
314 Assertions.EnableAssertions();
315 continue;
316 }
317
318 if (arg.StartsWith("-ea:".AsSpan()) || arg.StartsWith("-enableassertions:".AsSpan()))
319 {
320 if (arg.IndexOf(':') is int v && v > -1)
321 Assertions.EnableAssertions(arg.Slice(v + 1).ToString());
322 }
323
324 if (ArgEquals(arg, "-da") || ArgEquals(arg, "-disableassertions"))
325 {
326 Assertions.DisableAssertions();
327 continue;
328 }
329
330 if (arg.StartsWith("-da:".AsSpan()) || arg.StartsWith("-disableassertions:".AsSpan()))
331 {
332 if (arg.IndexOf(':') is int v && v > -1)
333 Assertions.DisableAssertions(arg.Slice(v + 1).ToString());
334 }
335
336 if (ArgEquals(arg, "-esa") || ArgEquals(arg, "-enablesystemassertions"))
337 {
338 Assertions.EnableSystemAssertions();
339 continue;
340 }
341
342 if (ArgEquals(arg, "-dsa") || ArgEquals(arg, "-disablesystemassertions"))
343 {
344 Assertions.DisableSystemAssertions();
345 continue;
346 }
347
348 if (ArgEquals(arg, "-cp") || ArgEquals(arg, "-classpath"))
349 {
350 if (jvmArg.MoveNext() == false)
351 {
352 Console.Error.WriteLine("Error: {0} requires class path specification", arg.ToString());
353 PrintHelp();
354 return 1;
355 }
356
357 initialize["java.class.path"] = string.Join(Path.PathSeparator.ToString(), Glob(jvmArg.Current.Split(Path.PathSeparator)));
358 continue;
359 }
360
361 if (ArgEquals(arg, "-version"))
362 {
363 showversion = true;
364 exit = true;
365 continue;
366 }
367
368 if (ArgEquals(arg, "-showversion"))
369 {
370 showversion = true;
371 continue;
372 }
373
374 if (ArgEquals(arg, "-jar"))
375 {
376 jar = true;
377 continue;
378 }
379
380 if (ArgEquals(arg, "-?") || ArgEquals(arg, "-help"))
381 {
382 PrintHelp();
383 return 1;
384 }
385
386 if (ArgEquals(arg, "-X"))
387 {
388 PrintXHelp();
389 return 1;
390 }
391
392 if (ArgEquals(arg, "-Xtime"))
393 {
394 Console.Error.WriteLine("Unrecognized option: {0}", arg.ToString());
395 return 1;
396 }
397
398 if (ArgEquals(arg, "-Xbreak"))
399 {
400 Debugger.Break();
401 continue;
402 }
403
404 if (ArgEquals(arg, "-Xverify"))
405 {
406 JVM.RelaxedVerification = false;
407 continue;
408 }
409
410 if (arg.StartsWith("-Xreference:".AsSpan()))
411 {
412 if (arg.IndexOf(':') is int v && v > -1)
413 AddBootClassPathAssembly(Assembly.LoadFrom(arg.Slice(v + 1).ToString()));
414
415 continue;
416 }
417
418 if (ArgEquals(arg, "-XX:+AllowNonVirtualCalls"))
419 {
420 JVM.AllowNonVirtualCalls = true;
421 continue;
422 }
423
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"))
442 {
443 Console.Error.WriteLine("Ignoring unrecognized option: {0}", arg.ToString());
444 continue;
445 }
446
447 Console.Error.WriteLine("Unrecognized option: {0}", arg.ToString());
448 return 1;
449 }
450 else if (hasMainArg == false)
451 {
452 hasMainArg = true;
453 main = arg.ToString();
454 continue;
455 }
456 else
457 {
458
459 if (appArgsReset == false)
460 {
461 appArgsReset = true;
462 appArgs.Clear();
463 }
464
465
466 appArgs.Add(arg.ToString());
467 continue;
468 }
469 }
470
471 try
472 {
473
474 if (jar)
475 initialize["java.class.path"] = main;
476
477
478 initialize["sun.java.command"] = string.Join(" ", Prepend(appArgs, main));
479 initialize["sun.java.launcher"] = "SUN_STANDARD";
480
481
482 SetUserProperties(initialize);
483
484
485 JVM.Init();
486
487
488
489 if (assembly != null)
490 AddBootClassPathAssembly(assembly);
491
492
493 EnterMainThread();
494
495
496 if (showversion)
497 PrintVersion();
498
499
500 if (exit)
501 return 0;
502
503
504 if (main == null)
505 {
506 PrintHelp();
507 return 1;
508 }
509
510
511 var clazz = LauncherHelperAccessor.InvokeCheckAndLoadMain(true, jar ? 2 : 1, main);
512 SystemAccessor.InvokeSetProperty("sun.java.command", initialize["sun.java.command"]);
513
514
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);
517
518 try
519 {
520
521 MethodAccessor.InvokeInvoke(method, null, new[] { appArgs.ToArray() });
522 return 0;
523 }
524 catch (
java.
lang.reflect.InvocationTargetException e)
525 {
526
527 ExceptionDispatchInfo.Capture(e.getCause()).Throw();
528 throw null;
529 }
530 }
531 catch (Exception e)
532 {
533 var thread = ThreadAccessor.InvokeCurrentThread();
534 ThreadGroupAccessor.InvokeUncaughtException(ThreadAccessor.InvokeGetThreadGroup(thread), thread, ikvm.runtime.Util.mapException(e));
535 }
536 finally
537 {
538 ExitMainThread();
539 }
540
541 return 1;
542#endif
543 }