+ if (void *libandroid_runtime = dlopen("libandroid_runtime.so", RTLD_LAZY | RTLD_GLOBAL)) {
+ class AndroidRuntime$;
+ AndroidRuntime$ *(*AndroidRuntime$$init$)(AndroidRuntime$ *self, char *args, unsigned int size)(NULL);
+ int (*AndroidRuntime$startVm)(AndroidRuntime$ *self, JavaVM **jvm, JNIEnv **jni)(NULL);
+ int (*AndroidRuntime$startReg)(JNIEnv *jni)(NULL);
+ int (*AndroidRuntime$addOption)(AndroidRuntime$ *self, const char *option, void *extra)(NULL);
+ int (*AndroidRuntime$addVmArguments)(AndroidRuntime$ *self, int, const char *const argv[])(NULL);
+ AndroidRuntime$ *(*AndroidRuntime$finalize)(AndroidRuntime$ *self)(NULL);
+
+ dlset(AndroidRuntime$$init$, "_ZN7android14AndroidRuntimeC1EPcj", libandroid_runtime);
+ dlset(AndroidRuntime$startVm, "_ZN7android14AndroidRuntime7startVmEPP7_JavaVMPP7_JNIEnv", libandroid_runtime);
+ dlset(AndroidRuntime$startReg, "_ZN7android14AndroidRuntime8startRegEP7_JNIEnv", libandroid_runtime);
+ dlset(AndroidRuntime$addOption, "_ZN7android14AndroidRuntime9addOptionEPKcPv", libandroid_runtime);
+ dlset(AndroidRuntime$addVmArguments, "_ZN7android14AndroidRuntime14addVmArgumentsEiPKPKc", libandroid_runtime);
+ dlset(AndroidRuntime$finalize, "_ZN7android14AndroidRuntimeD1Ev", libandroid_runtime);
+
+ // XXX: it would also be interesting to attach this to a global pool
+ AndroidRuntime$ *runtime(pool.calloc<AndroidRuntime$>(1, 1024));
+
+ _assert(AndroidRuntime$$init$ != NULL);
+ AndroidRuntime$$init$(runtime, NULL, 0);
+
+ if (AndroidRuntime$addOption == NULL) {
+ _assert(AndroidRuntime$addVmArguments != NULL);
+ std::vector<const char *> arguments;
+ for (const auto &option : options)
+ arguments.push_back(option.optionString);
+ AndroidRuntime$addVmArguments(runtime, arguments.size(), arguments.data());
+ } else for (const auto &option : options)
+ AndroidRuntime$addOption(runtime, option.optionString, option.extraInfo);
+
+ int failure;
+
+ _assert(AndroidRuntime$startVm != NULL);
+ failure = AndroidRuntime$startVm(runtime, &jvm, &jni);
+ _assert(failure == 0);
+
+ _assert(AndroidRuntime$startReg != NULL);
+ failure = AndroidRuntime$startReg(jni);
+ _assert(failure == 0);
+
+ return jni;
+ }
+
+ jint (*$JNI_CreateJavaVM)(JavaVM **jvm, void **, void *);
+ dlset($JNI_CreateJavaVM, "JNI_CreateJavaVM", handle);
+
+ JavaVMInitArgs args;
+ memset(&args, 0, sizeof(args));
+ args.version = CYJavaVersion;
+ args.nOptions = options.size();
+ args.options = options.data();
+ _jnicall($JNI_CreateJavaVM(&jvm, reinterpret_cast<void **>(&jni), &args));
+ return jni;
+}