Skip to content

Commit

Permalink
Merge pull request #574 from ikvmnet/bc12
Browse files Browse the repository at this point in the history
IKVM.ByteCode Refactor
  • Loading branch information
wasabii committed Aug 12, 2024
2 parents b503ad9 + 3da3b53 commit c1a14d7
Show file tree
Hide file tree
Showing 50 changed files with 3,323 additions and 3,198 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
</PropertyGroup>

<PropertyGroup Label="Build Info">
<LangVersion Condition=" '$(LangVersion)' == '' ">10.0</LangVersion>
<LangVersion Condition=" '$(LangVersion)' == '' ">12.0</LangVersion>
<NoWarn>$(NoWarn);1591;1573;CS8002;NU5100;NU5118;NU5128;MSB3245;NETSDK1023</NoWarn>
<AutoGenerateBindingRedirects Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net461'))">true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net461'))">true</GenerateBindingRedirectsOutputType>
Expand Down
2 changes: 1 addition & 1 deletion IKVM.deps.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<ItemGroup>
<PackageReference Include="IKVM.ByteCode" Version="8.11.0" />
<PackageReference Include="IKVM.ByteCode" Version="8.12.0" />
</ItemGroup>

<Choose>
Expand Down
3 changes: 1 addition & 2 deletions nuget.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>

</packageSources>
</configuration>
5 changes: 4 additions & 1 deletion src/IKVM.Reflection/Emit/ModuleBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ public override int GetHashCode()
return type.GetHashCode() + name.GetHashCode() + signature.GetHashCode();
}

internal MethodBase LookupMethod() => type.FindMethod(name, (MethodSignature)signature);
internal MethodBase LookupMethod()
{
return type.FindMethod(name, (MethodSignature)signature);
}

}

Expand Down
78 changes: 35 additions & 43 deletions src/IKVM.Runtime/AttributeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ Jeroen Frijters
using System.Diagnostics;

using IKVM.ByteCode.Reading;
using IKVM.ByteCode.Parsing;

using System.Linq;
using System.ComponentModel;

#if IMPORTER || EXPORTER
Expand Down Expand Up @@ -122,9 +120,9 @@ class AttributeHelper

Type TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers));

Type TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(SourceFileAttribute));
Type TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute));

Type TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(LineNumberTableAttribute));
Type TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute));

#endif

Expand All @@ -140,7 +138,7 @@ class AttributeHelper

Type TypeOfJavaModuleAttribute => typeofJavaModuleAttribute ??= LoadType(typeof(JavaModuleAttribute));

Type TypeOfSignatureAttribute => typeofSignatureAttribute ??= LoadType(typeof(SignatureAttribute));
Type TypeOfSignatureAttribute => typeofSignatureAttribute ??= LoadType(typeof(IKVM.Attributes.SignatureAttribute));

Type TypeOfInnerClassAttribute => typeofInnerClassAttribute ??= LoadType(typeof(InnerClassAttribute));

Expand All @@ -164,11 +162,11 @@ class AttributeHelper

Type TypeOfNonNestedOuterClassAttribute => typeofNonNestedOuterClassAttribute ??= LoadType(typeof(NonNestedOuterClassAttribute));

Type TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= LoadType(typeof(EnclosingMethodAttribute));
Type TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= LoadType(typeof(IKVM.Attributes.EnclosingMethodAttribute));

Type TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= LoadType(typeof(MethodParametersAttribute));
Type TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= LoadType(typeof(IKVM.Attributes.MethodParametersAttribute));

Type TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= LoadType(typeof(RuntimeVisibleTypeAnnotationsAttribute));
Type TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= LoadType(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute));

Type TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= LoadType(typeof(ConstantPoolAttribute));

Expand Down Expand Up @@ -890,50 +888,44 @@ internal void SetSignatureAttribute(MethodBuilder mb, string signature)

internal void SetMethodParametersAttribute(MethodBuilder mb, Modifiers[] modifiers)
{
methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor(new Type[] { TypeOfModifiers.MakeArrayType() });
mb.SetCustomAttribute(new CustomAttributeBuilder(methodParametersAttribute, new object[] { modifiers }));
methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor(new[] { TypeOfModifiers.MakeArrayType() });
mb.SetCustomAttribute(new CustomAttributeBuilder(methodParametersAttribute, new[] { modifiers }));
}

internal void SetRuntimeVisibleTypeAnnotationsAttribute(TypeBuilder tb, IReadOnlyList<TypeAnnotationReader> data)
internal void SetRuntimeVisibleTypeAnnotationsAttribute(TypeBuilder tb, ref readonly TypeAnnotationTable table)
{
var builder = new BlobBuilder();
var encoder = new TypeAnnotationTableEncoder(builder);
table.WriteTo(ref encoder);

foreach (var i in data)
encoder.Encode(i.Record);

runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor(new Type[] { context.Types.Byte.MakeArrayType() });
tb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, new object[] { builder.ToArray() }));
runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]);
tb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()]));
}

internal void SetRuntimeVisibleTypeAnnotationsAttribute(FieldBuilder fb, IReadOnlyList<TypeAnnotationReader> data)
internal void SetRuntimeVisibleTypeAnnotationsAttribute(FieldBuilder fb, ref readonly TypeAnnotationTable table)
{
var builder = new BlobBuilder();
var encoder = new TypeAnnotationTableEncoder(builder);
table.WriteTo(ref encoder);

foreach (var i in data)
encoder.Encode(i.Record);

runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor(new Type[] { context.Types.Byte.MakeArrayType() });
fb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, new object[] { builder.ToArray() }));
runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]);
fb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()]));
}

internal void SetRuntimeVisibleTypeAnnotationsAttribute(MethodBuilder mb, IReadOnlyList<TypeAnnotationReader> data)
internal void SetRuntimeVisibleTypeAnnotationsAttribute(MethodBuilder mb, ref readonly TypeAnnotationTable table)
{
var builder = new BlobBuilder();
var encoder = new TypeAnnotationTableEncoder(builder);
table.WriteTo(ref encoder);

foreach (var i in data)
encoder.Encode(i.Record);

runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor(new Type[] { context.Types.Byte.MakeArrayType() });
mb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, new object[] { builder.ToArray() }));
runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]);
mb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()]));
}

internal void SetConstantPoolAttribute(TypeBuilder tb, object[] constantPool)
{
constantPoolAttribute ??= TypeOfConstantPoolAttribute.GetConstructor(new Type[] { context.Types.Object.MakeArrayType() });
tb.SetCustomAttribute(new CustomAttributeBuilder(constantPoolAttribute, new object[] { constantPool }));
tb.SetCustomAttribute(new CustomAttributeBuilder(constantPoolAttribute, [constantPool]));
}

internal void SetParamArrayAttribute(ParameterBuilder pb)
Expand Down Expand Up @@ -1049,32 +1041,32 @@ internal string GetNonNestedOuterClasses(Type t)
#endif
}

internal SignatureAttribute GetSignature(MemberInfo member)
internal IKVM.Attributes.SignatureAttribute GetSignature(MemberInfo member)
{
#if !IMPORTER && !EXPORTER
var attribs = member.GetCustomAttributes(typeof(SignatureAttribute), false);
return attribs.Length == 1 ? (SignatureAttribute)attribs[0] : null;
var attribs = member.GetCustomAttributes(typeof(IKVM.Attributes.SignatureAttribute), false);
return attribs.Length == 1 ? (IKVM.Attributes.SignatureAttribute)attribs[0] : null;
#else
foreach (var cad in CustomAttributeData.__GetCustomAttributes(member, TypeOfSignatureAttribute, false))
{
var args = cad.ConstructorArguments;
return new SignatureAttribute((string)args[0].Value);
return new IKVM.Attributes.SignatureAttribute((string)args[0].Value);
}

return null;
#endif
}

internal MethodParametersAttribute GetMethodParameters(MethodBase method)
internal IKVM.Attributes.MethodParametersAttribute GetMethodParameters(MethodBase method)
{
#if !IMPORTER && !EXPORTER
var attribs = method.GetCustomAttributes(typeof(MethodParametersAttribute), false);
return attribs.Length == 1 ? (MethodParametersAttribute)attribs[0] : null;
var attribs = method.GetCustomAttributes(typeof(IKVM.Attributes.MethodParametersAttribute), false);
return attribs.Length == 1 ? (IKVM.Attributes.MethodParametersAttribute)attribs[0] : null;
#else
foreach (var cad in CustomAttributeData.__GetCustomAttributes(method, TypeOfMethodParametersAttribute, false))
{
var args = cad.ConstructorArguments;
return new MethodParametersAttribute(DecodeArray<Modifiers>(args[0]));
return new IKVM.Attributes.MethodParametersAttribute(DecodeArray<Modifiers>(args[0]));
}
return null;
#endif
Expand All @@ -1096,8 +1088,8 @@ internal object[] GetConstantPool(Type type)
internal byte[] GetRuntimeVisibleTypeAnnotations(MemberInfo member)
{
#if !IMPORTER && !EXPORTER
object[] attribs = member.GetCustomAttributes(typeof(RuntimeVisibleTypeAnnotationsAttribute), false);
return attribs.Length == 1 ? ((RuntimeVisibleTypeAnnotationsAttribute)attribs[0]).data : null;
object[] attribs = member.GetCustomAttributes(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute), false);
return attribs.Length == 1 ? ((IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute)attribs[0]).data : null;
#else
foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, TypeOfRuntimeVisibleTypeAnnotationsAttribute, false))
{
Expand Down Expand Up @@ -1251,17 +1243,17 @@ internal bool HasEnclosingMethodAttribute(Type type)
return type.IsDefined(TypeOfEnclosingMethodAttribute, false);
}

internal EnclosingMethodAttribute GetEnclosingMethodAttribute(Type type)
internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(Type type)
{
#if !IMPORTER && !EXPORTER
var attr = type.GetCustomAttributes(typeof(EnclosingMethodAttribute), false);
var attr = type.GetCustomAttributes(typeof(IKVM.Attributes.EnclosingMethodAttribute), false);
if (attr.Length == 1)
return ((EnclosingMethodAttribute)attr[0]).SetClassName(context, type);
return ((IKVM.Attributes.EnclosingMethodAttribute)attr[0]).SetClassName(context, type);

return null;
#else
foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfEnclosingMethodAttribute, false))
return new EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type);
return new IKVM.Attributes.EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type);

return null;
#endif
Expand Down
164 changes: 82 additions & 82 deletions src/IKVM.Runtime/Attributes/ConstantPoolAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,87 +30,87 @@ namespace IKVM.Attributes
{

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public sealed class ConstantPoolAttribute : Attribute
{

internal readonly object[] constantPool;

public ConstantPoolAttribute(object[] constantPool)
{
this.constantPool = Decompress(constantPool);
}

internal static object[] Decompress(object[] constantPool)
{
List<object> list = new List<object>();
foreach (object obj in constantPool)
{
int emptySlots = obj as byte? ?? obj as ushort? ?? 0;
if (emptySlots == 0)
{
list.Add(Unescape(obj));
}
else
{
for (int i = 0; i < emptySlots; i++)
{
list.Add(null);
}
}
}
return list.ToArray();
}

private static object Unescape(object obj)
{
string str = obj as string;
if (str != null)
{
obj = UnicodeUtil.UnescapeInvalidSurrogates(str);
}
return obj;
}

internal static object[] Compress(object[] constantPool, bool[] inUse)
{
int length = constantPool.Length;
while (!inUse[length - 1])
{
length--;
}
int write = 0;
for (int read = 0; read < length; read++)
{
int start = read;
while (!inUse[read])
{
read++;
}
int emptySlots = read - start;
if (emptySlots > 255)
{
constantPool[write++] = (ushort)emptySlots;
}
else if (emptySlots > 0)
{
constantPool[write++] = (byte)emptySlots;
}
constantPool[write++] = Escape(constantPool[read]);
}
Array.Resize(ref constantPool, write);
return constantPool;
}

private static object Escape(object obj)
{
string str = obj as string;
if (str != null)
{
obj = UnicodeUtil.EscapeInvalidSurrogates(str);
}
return obj;
}

}
public sealed class ConstantPoolAttribute : Attribute
{

internal static object[] Decompress(object[] constantPool)
{
var list = new List<object>();

foreach (var obj in constantPool)
{
int emptySlots = obj as byte? ?? obj as ushort? ?? 0;
if (emptySlots == 0)
{
list.Add(Unescape(obj));
}
else
{
for (int i = 0; i < emptySlots; i++)
list.Add(null);
}
}

return list.ToArray();
}

static object Unescape(object obj)
{
if (obj is string str)
obj = UnicodeUtil.UnescapeInvalidSurrogates(str);

return obj;
}

internal static object[] Compress(object[] constantPool, bool[] inUse)
{
int length = constantPool.Length;
while (!inUse[length - 1])
length--;

int write = 0;
for (int read = 0; read < length; read++)
{
int start = read;
while (!inUse[read])
read++;

int emptySlots = read - start;
if (emptySlots > 255)
{
constantPool[write++] = (ushort)emptySlots;
}
else if (emptySlots > 0)
{
constantPool[write++] = (byte)emptySlots;
}

constantPool[write++] = Escape(constantPool[read]);
}

Array.Resize(ref constantPool, write);
return constantPool;
}

static object Escape(object obj)
{
if (obj is string str)
obj = UnicodeUtil.EscapeInvalidSurrogates(str);

return obj;
}

internal readonly object[] constantPool;

/// <summary>
/// Initializes a new instance.
/// </summary>
/// <param name="constantPool"></param>
public ConstantPoolAttribute(object[] constantPool)
{
this.constantPool = Decompress(constantPool);
}

}

}
Loading

0 comments on commit c1a14d7

Please sign in to comment.