Created
November 10, 2020 07:14
-
-
Save jessiepathfinder/2a3596a20921d37ab66733690dd43b79 to your computer and use it in GitHub Desktop.
IKVM.NET AOT Compiler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Reflection; | |
using System.IO; | |
using IKVM.Internal; | |
using java.lang; | |
using java.util.zip; | |
using java.io; | |
using jessielesbian.IKVM; | |
using Console = System.Console; | |
using File = java.io.File; | |
using ikvm.runtime; | |
namespace ikvmaotc | |
{ | |
public static class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("IKVMAOTC v1.0.1: The IKVM.NET Dynamic Optimizing AOT Compiler"); | |
Console.WriteLine("Made by Jessie Lesbian"); | |
Console.WriteLine("Email: [email protected] Reddit: https://www.reddit.com/u/jessielesbian"); | |
Console.WriteLine(); | |
if(args.Length != 3) | |
{ | |
Console.WriteLine("USAGE: ikvmaotc <input jar> <output assemblies name> <classpath>"); | |
Console.WriteLine("Example: ikvmaotc libminecraft1.11.2-ikvmsafe.jar IKVM.libminecraft.1.11.2 authlib-1.5.24.jar;codecjorbis-20101023.jar;codecwav-20101023.jar;commons-codec-1.9.jar;commons-compress-1.8.1.jar;commons-io-2.4.jar;commons-lang3-3.3.2.jar;commons-logging-1.1.3.jar;fastutil-7.0.12_mojang.jar;gson-2.2.4.jar;guava-17.0.jar;httpclient-4.3.3.jar;httpcore-4.3.2.jar;icu4j-core-mojang-51.2.jar;jinput-2.0.5.jar;jna-3.4.0.jar;jopt-simple-4.6.jar;jutils-1.0.0.jar;libraryjavasound-20101123.jar;librarylwjglopenal-20100824.jar;log4j-api-2.0-beta9.jar;log4j-core-2.0-beta9.jar;lwjgl-2.9.4-nightly-20150209.jar;lwjgl_util-2.9.4-nightly-20150209.jar;netty-1.6.jar;netty-all-4.0.23.Final.jar;oshi-core-1.1.jar;platform-3.4.0.jar;realms-1.10.16.jar;soundsystem-20120107.jar"); | |
Console.WriteLine("NOTE: Assembly names are NOT file names, and don't end with .dll"); | |
return; | |
} | |
Console.WriteLine("Initializing..."); | |
string input = args[0]; | |
string output = args[1]; | |
string classpath = input + ";" + args[2]; | |
//The global constant pool is only meant to be used in "truly" dynamic mode. It is there just in case I decide to add a LLVM-based compiler known as IKVMfast or re-implement IKVMCI. | |
Helper.DisableGlobalConstantPool = true; | |
Helper.FirstDynamicAssemblyName = output; | |
Helper.UseSingleDynamicAssembly = true; | |
Console.WriteLine("Starting suspended JVM..."); | |
Hashtable hashtable = new Hashtable(); | |
hashtable["java.class.path"] = classpath; | |
hashtable["sun.java.launcher"] = "SUN_STANDARD"; | |
Startup.setProperties(hashtable); | |
Starter.PrepareForSaveDebugImage(); | |
Startup.enterMainThread(); | |
Console.WriteLine("Getting system class loader..."); | |
ClassLoader classloader = ClassLoader.getSystemClassLoader(); | |
Console.WriteLine("Opening input file..."); | |
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(new File(input))); | |
Console.WriteLine("Creating resources file..."); | |
string tempfile = Path.GetTempFileName(); | |
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(tempfile)); | |
zipOutputStream.setLevel(9); | |
while(true) { | |
ZipEntry ze = zipInputStream.getNextEntry(); | |
if(ze == null) | |
{ | |
break; | |
} | |
string filename = ze.name; | |
if(filename.EndsWith(".class")) | |
{ | |
string classname = filename.Substring(0, filename.Length - 6).Replace('/', '.'); | |
Console.WriteLine("Compiling class: " + classname + "..."); | |
try | |
{ | |
classloader.loadClass(classname); | |
} | |
catch(System.Exception e) | |
{ | |
Console.WriteLine("Unable to compile class: " + classname + "!"); | |
Console.WriteLine(e.Message); | |
} | |
} | |
else | |
{ | |
Console.WriteLine("Adding resource: " + filename + "..."); | |
InputStream IS = classloader.getResourceAsStream(filename); | |
zipOutputStream.putNextEntry(new ZipEntry(filename)); | |
if(!filename.EndsWith("/")) | |
{ | |
zipOutputStream.write(ExtractCurrentFile(IS)); | |
IS.close(); | |
} | |
} | |
} | |
Console.WriteLine("Shutting down suspended JVM..."); | |
Startup.exitMainThread(); | |
Console.WriteLine("Closing resources file..."); | |
zipOutputStream.flush(); | |
zipOutputStream.close(); | |
Console.WriteLine("Injecting resources..."); | |
FileStream fileStream = new FileStream(tempfile, FileMode.Open, FileAccess.Read); | |
Helper.FirstDynamicAssembly.GetDynamicModule(output).DefineManifestResource("resources.jar", fileStream, ResourceAttributes.Public); | |
Console.WriteLine("Saving assemblies..."); | |
Starter.SaveDebugImage(); | |
Console.WriteLine("Deleting resources file..."); | |
fileStream.Dispose(); | |
System.IO.File.Delete(tempfile); | |
} | |
private static byte[] ExtractCurrentFile(InputStream input) | |
{ | |
MemoryStream memoryStream = new MemoryStream(); | |
memoryStream.Capacity = 65536; | |
byte[] buffer = new byte[65536]; | |
while(true) | |
{ | |
int read = input.read(buffer, 0, buffer.Length); | |
if(read <= 0) | |
{ | |
byte[] bytes = memoryStream.ToArray(); | |
memoryStream.Dispose(); | |
return bytes; | |
} | |
else | |
{ | |
memoryStream.Capacity += 65536; | |
} | |
memoryStream.Write(buffer, 0, read); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment