More crap
This commit is contained in:
+471
-606
File diff suppressed because it is too large
Load Diff
+10
-4
@@ -1,4 +1,5 @@
|
|||||||
using System.Reflection;
|
using System.CodeDom.Compiler;
|
||||||
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using JCIL.Java.Class;
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
@@ -16,10 +17,10 @@ public class Program
|
|||||||
Console.WriteLine($"Load time: {(DateTime.Now - now).TotalMilliseconds}ms");
|
Console.WriteLine($"Load time: {(DateTime.Now - now).TotalMilliseconds}ms");
|
||||||
|
|
||||||
var builder = new AssemblyBuilder(new AssemblyName("Test"), false);
|
var builder = new AssemblyBuilder(new AssemblyName("Test"), false);
|
||||||
var dotnetClass = builder.Build(javaClass);
|
var dotnetClass = builder.MakeType(javaClass);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
builder.ForceBuildMethod(javaClass.Methods[1]);
|
dotnetClass.GetMethod(javaClass.Methods[1]);
|
||||||
}
|
}
|
||||||
catch (InvalidDataException e)
|
catch (InvalidDataException e)
|
||||||
{
|
{
|
||||||
@@ -35,4 +36,9 @@ public class Program
|
|||||||
assembly.Save("out.dll");
|
assembly.Save("out.dll");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static class Debug
|
||||||
|
{
|
||||||
|
public static readonly IndentedTextWriter Writer = new(Console.Error, "| ");
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Frozen;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types;
|
||||||
|
|
||||||
|
public sealed class NewClass : TypeSurrogate
|
||||||
|
{
|
||||||
|
public readonly Class Original;
|
||||||
|
public override TypeBuilder Type { get; }
|
||||||
|
|
||||||
|
private readonly AssemblyBuilder _builder;
|
||||||
|
|
||||||
|
private FrozenDictionary<string, FieldInfo> _fields = FrozenDictionary<string, FieldInfo>.Empty;
|
||||||
|
private readonly ConcurrentDictionary<(string, MethodSignature), MethodBase> _methods = [];
|
||||||
|
|
||||||
|
public NewClass(AssemblyBuilder builder, TypeBuilder type, Class original)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
_builder = builder;
|
||||||
|
Original = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
return _fields[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
Method? original = null;
|
||||||
|
var method = _methods.GetOrAdd((name, signature), _ =>
|
||||||
|
{
|
||||||
|
original = Original.GetMethod(name, signature);
|
||||||
|
if (original == null) throw new KeyNotFoundException($"Could not find method `{name}`");
|
||||||
|
|
||||||
|
MethodAttributes attributes = default;
|
||||||
|
if ((original.AccessFlags & MethodAccessFlags.Final) != 0) attributes |= MethodAttributes.Final;
|
||||||
|
if ((original.AccessFlags & MethodAccessFlags.Static) != 0) attributes |= MethodAttributes.Static;
|
||||||
|
if ((original.AccessFlags & MethodAccessFlags.Public) != 0) attributes |= MethodAttributes.Public;
|
||||||
|
if ((original.AccessFlags & MethodAccessFlags.Private) != 0) attributes |= MethodAttributes.Private;
|
||||||
|
if ((original.AccessFlags & MethodAccessFlags.Protected) != 0) attributes |= MethodAttributes.Family;
|
||||||
|
|
||||||
|
signature = (MethodSignature) original.Type.SpecialClassMetadata!;
|
||||||
|
if (original.Name == "<init>")
|
||||||
|
{
|
||||||
|
return Type.DefineConstructor(
|
||||||
|
attributes, CallingConventions.Standard,
|
||||||
|
signature.ParamTypes.Select(t => _builder.MakeType(t).Type).ToArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type.DefineMethod(
|
||||||
|
name, attributes, CallingConventions.Standard,
|
||||||
|
_builder.MakeType(signature.ReturnType).Type,
|
||||||
|
signature.ParamTypes.Select(t => _builder.MakeType(t).Type).ToArray()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (original is null)
|
||||||
|
return method;
|
||||||
|
|
||||||
|
if (!original.TryGetCode(out var code, out var reader))
|
||||||
|
return method;
|
||||||
|
|
||||||
|
if (method is MethodBuilder methodBuilder)
|
||||||
|
_builder.CompileOpCodes(Original, method, methodBuilder.GetILGenerator(), code, reader);
|
||||||
|
|
||||||
|
if (method is ConstructorBuilder constructorBuilder)
|
||||||
|
_builder.CompileOpCodes(Original, method, constructorBuilder.GetILGenerator(), code, reader);
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
var method = GetMethod(name, signature);
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case MethodInfo info when method.IsVirtual:
|
||||||
|
il.Emit(OpCodes.Callvirt, info);
|
||||||
|
return info.ReturnType;
|
||||||
|
|
||||||
|
case MethodInfo info:
|
||||||
|
il.Emit(OpCodes.Call, info);
|
||||||
|
return info.ReturnType;
|
||||||
|
|
||||||
|
case ConstructorInfo info:
|
||||||
|
il.Emit(OpCodes.Call, info);
|
||||||
|
return typeof(void);
|
||||||
|
|
||||||
|
default: throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void CreateFields()
|
||||||
|
{
|
||||||
|
var fields = new Dictionary<string, FieldInfo>();
|
||||||
|
foreach (var field in Original.Fields)
|
||||||
|
{
|
||||||
|
FieldAttributes attributes = default;
|
||||||
|
if ((field.AccessFlags & FieldAccessFlags.Static) != 0) attributes |= FieldAttributes.Static;
|
||||||
|
if ((field.AccessFlags & FieldAccessFlags.Final) != 0) attributes |= FieldAttributes.InitOnly;
|
||||||
|
if ((field.AccessFlags & FieldAccessFlags.Public) != 0) attributes |= FieldAttributes.Public;
|
||||||
|
if ((field.AccessFlags & FieldAccessFlags.Private) != 0) attributes |= FieldAttributes.Private;
|
||||||
|
if ((field.AccessFlags & FieldAccessFlags.Protected) != 0) attributes |= FieldAttributes.Family;
|
||||||
|
var type = _builder.MakeType(field.Type);
|
||||||
|
var fieldInfo = Type.DefineField(field.Name, type.Type, attributes);
|
||||||
|
fields.Add(field.Name, fieldInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
_fields = fields.ToFrozenDictionary();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types;
|
||||||
|
|
||||||
|
public abstract class TypeSurrogate
|
||||||
|
{
|
||||||
|
public abstract Type Type { get; }
|
||||||
|
public abstract FieldInfo GetField(string name);
|
||||||
|
public abstract MethodBase GetMethod(string name, MethodSignature signature);
|
||||||
|
public abstract Type CallMethod(string name, MethodSignature signature, ILGenerator il);
|
||||||
|
|
||||||
|
public MethodBase GetMethod(Method method)
|
||||||
|
{
|
||||||
|
return GetMethod(method.Name, (MethodSignature)method.Type.SpecialClassMetadata!);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.java.lang;
|
||||||
|
|
||||||
|
public class Array(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(System.Array);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ArrayOf(TypeSurrogate elementType, Class javaClass) : Array(javaClass)
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(System.Array);
|
||||||
|
public readonly TypeSurrogate ElementType = elementType;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Boolean(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(bool);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Byte(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(byte);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Char(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(char);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Double(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(double);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Float(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(float);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Integer(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(int);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Long(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(long);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class String(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(string);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using JCIL.Java.Class;
|
||||||
|
|
||||||
|
namespace JCIL.CLI.Types.Java.Lang;
|
||||||
|
|
||||||
|
public sealed class Void(Class javaClass) : TypeSurrogate
|
||||||
|
{
|
||||||
|
public override Type Type => typeof(void);
|
||||||
|
public readonly Class Original = javaClass;
|
||||||
|
|
||||||
|
public override FieldInfo GetField(string name)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MethodBase GetMethod(string name, MethodSignature signature)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type CallMethod(string name, MethodSignature signature, ILGenerator il)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -150,6 +150,11 @@ public sealed class Class
|
|||||||
{
|
{
|
||||||
return Constant.Resolve(Loader, _constants, i);
|
return Constant.Resolve(Loader, _constants, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T GetConstant<T>(ushort i)
|
||||||
|
{
|
||||||
|
return (T) Constant.Resolve(Loader, _constants, i)!;
|
||||||
|
}
|
||||||
|
|
||||||
public Method? GetMethod(string name, MethodSignature signature, bool exact = false)
|
public Method? GetMethod(string name, MethodSignature signature, bool exact = false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -308,6 +308,26 @@ public struct OpCode
|
|||||||
public OpCodeMnemonic Mnemonic;
|
public OpCodeMnemonic Mnemonic;
|
||||||
public OpCodeParameter P0;
|
public OpCodeParameter P0;
|
||||||
public OpCodeParameter P1;
|
public OpCodeParameter P1;
|
||||||
|
|
||||||
|
public string ToString(Class javaClass)
|
||||||
|
{
|
||||||
|
switch (Mnemonic)
|
||||||
|
{
|
||||||
|
case OpCodeMnemonic.GetStaticField:
|
||||||
|
{
|
||||||
|
var fieldRef = javaClass.GetConstant<FieldRef>(P0.UShort);
|
||||||
|
return $"{Mnemonic} {fieldRef.Class}.{fieldRef.Field.Name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
case OpCodeMnemonic.InvokeStatic:
|
||||||
|
{
|
||||||
|
var methodRef = javaClass.GetConstant<MethodRef>(P0.UShort);
|
||||||
|
return $"{Mnemonic} {methodRef.Class}.{methodRef.Method.Name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
default: return ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user