
jdk.internal.org.qbicc.runtime.Main Maven / Gradle / Ivy
package jdk.internal.org.qbicc.runtime;
import static org.qbicc.runtime.CNative.*;
import static org.qbicc.runtime.posix.PThread.pthread_exit;
import static org.qbicc.runtime.stdc.Stdio.*;
import static org.qbicc.runtime.stdc.Stdlib.*;
import static org.qbicc.runtime.stdc.String.strcmp;
import java.util.ArrayList;
import java.util.Arrays;
import org.qbicc.runtime.Build;
import org.qbicc.runtime.Hidden;
import org.qbicc.runtime.NotReachableException;
import org.qbicc.runtime.gc.heap.Heap;
/**
* Holds the native image main entry point.
*/
public final class Main {
/**
* A list of initialization actions deferred from build time to runtime.
* These will be executed in the order they were enqueued by #deferInitAction
* after the core JDK is fully booted but before the application main method is invoked.
*/
private static ArrayList deferredInits = new ArrayList<>();
private Main() {
}
/**
* Enqueue an initialization action at build time that will be performed
* at runtime before the application-level main method is invoked.
*/
public static void deferInitAction(Runnable r) {
if (!Build.isHost()) {
throw new IllegalStateException("init actions can only be deferrred at build time");
}
synchronized (deferredInits) {
deferredInits.add(r);
}
}
/**
* This is a stub that gets redirected to the real main method by the main method plugin.
*
* @param args the arguments to pass to the main program
*/
static native void userMain(String[] args);
static native ThreadGroup getSystemThreadGroup();
@export
@Hidden
public static c_int main(c_int argc, char_ptr[] argv) {
Heap.initHeap(argc.intValue(), addr_of(argv[0]).cast());
// first set up VM
if (! Heap.checkInit(true)) {
exit(word(1));
}
// next set up the initial thread
attachNewThread("main", getSystemThreadGroup());
Thread$_patch mainThread = (Thread$_patch)(Object)Thread.currentThread();
mainThread.initializeNativeFields();
mainThread.begin();
try {
// next initialize the JDK
System$_patch.rtinitPhase1();
System$_patch.rtinitPhase2();
System$_patch.rtinitPhase3();
// Parse the command line arguments and convert from C to Java
String[] userArgs = processArgs(argc, argv);
// TODO: We should process any non-Heap arguments in FlightRecorder.vmArgs here.
// next execute additional initialization actions deferred from build time
for (Runnable r: deferredInits) {
r.run();
}
// Initialization completed
FlightRecorder.initDoneTime = System.currentTimeMillis();
// now cause the initial thread to invoke main
userMain(userArgs);
} catch (Throwable t) {
Thread.UncaughtExceptionHandler handler = Thread.currentThread().getUncaughtExceptionHandler();
if (handler != null) {
try {
handler.uncaughtException(Thread.currentThread(), t);
} catch (Throwable t2) {
// exception handler threw an exception... just bail out then
fprintf(stderr, utf8z("The uncaught exception handler threw an exception or error\n"));
fflush(stderr);
}
}
System.exit(1);
}
mainThread.end(); // Will return only if mainThread is not the last non-dameon thread
if (Build.Target.isPosix()) {
pthread_exit(zero());
}
// todo: windows
throw new NotReachableException();
}
// Convert C args to Java Strings and separate the VM and user arguments
// Return the subset of argv that are arguments for the user main.
private static String[] processArgs(c_int argc, char_ptr[] argv) {
String[] userArgs = new String[argc.intValue() - 1];
String[] vmArgs = new String[0];
int userCount = 0;
boolean checkForVmArg = true;
for (int i=1; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy