Cosmos/source2/IL2PCU/Cosmos.IL2CPU/MethodInfoLabelGenerator.cs
2009-08-23 20:30:02 +00:00

214 lines
7 KiB
C#

using System;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Security.Cryptography;
using Indy.IL2CPU.Assembler;
using System.Diagnostics;
namespace Cosmos.IL2CPU
{
public static class MethodInfoLabelGenerator
{
public static string GenerateLabelName( MethodBase aMethod )
{
string xResult = DataMember.FilterStringForIncorrectChars( GenerateFullName( aMethod ) );
xResult = GenerateLabelFromFullName( xResult );
return xResult;
}
public static string GenerateLabelFromFullName( string xResult )
{
if( xResult.Length > 245 )
{
using( var xHash = MD5.Create() )
{
xResult = xHash.ComputeHash(
Encoding.Default.GetBytes( xResult ) ).Aggregate( "_", ( r, x ) => r + x.ToString( "X2" ) );
}
}
return xResult;
}
//public static string GenerateLabelName(MethodBase aMethod)
//{
// return GenerateLabelNameInt(aMethod).ToString();
//}
//TODO Unicode support
public static ulong GenerateLabelNameInt( MethodBase aMethod )
{
string xResult = DataMember.FilterStringForIncorrectChars( GenerateFullName( aMethod ) );
var encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes( xResult );
var hash = Elf64.Compute( 0, 0, bytes );
// Debug.WriteLine(" hash: " + hash.ToString() + " Output : " + xResult );
return hash;
//ulong result , g = 0 ;
//foreach ( char ch in xResult.ToCharArray())
//{
// result = (result << 4) + (byte)ch;
// result++;
// g = result & 0xF0000000;
// if (g > 0 ) // wrap
// result = g >> 24;
// result &= ~g;
}
// unsigned long hash(char *name)
//{
// unsigned long h = 0, g;
// while ( *name ) {
// h = ( h << 4 ) + *name++;
// if ( g = h & 0xF0000000 )
// h ^= g >> 24;
// h &= ~g;
// }
// return h;
//}
public static string GetFullName( Type aType )
{
if( aType.IsGenericParameter )
{
return aType.Name;
}
var xSB = new StringBuilder();
if( aType.IsArray )
{
xSB.Append( GetFullName( aType.GetElementType() ) );
xSB.Append( "[" );
int xRank = aType.GetArrayRank();
while( xRank > 1 )
{
xSB.Append( "," );
xRank--;
}
xSB.Append( "]" );
return xSB.ToString();
}
if( aType.IsByRef && aType.HasElementType )
{
return "&" + GetFullName( aType.GetElementType() );
}
if( aType.IsGenericType )
{
xSB.Append( aType.GetGenericTypeDefinition().FullName );
}
else
{
xSB.Append( aType.FullName );
}
if( aType.IsGenericType )
{
xSB.Append( "<" );
var xArgs = aType.GetGenericArguments();
for( int i = 0; i < xArgs.Length - 1; i++ )
{
xSB.Append( GetFullName( xArgs[ i ] ) );
xSB.Append( ", " );
} if( xArgs.Length == 0 ) { Console.Write( "" ); }
xSB.Append( GetFullName( xArgs.Last() ) );
xSB.Append( ">" );
}
//xSB.Append(", ");
//xSB.Append(aType.Assembly.FullName);
return xSB.ToString();
}
private static string GenerateFullName( MethodBase aMethod )
{
if( aMethod == null )
{
throw new ArgumentNullException( "aMethod" );
}
var xBuilder = new StringBuilder( 256 );
var xParts = aMethod.ToString().Split( ' ' );
var xParts2 = xParts.Skip( 1 ).ToArray();
var xMethodInfo = aMethod as System.Reflection.MethodInfo;
if( xMethodInfo != null )
{
xBuilder.Append( GetFullName( xMethodInfo.ReturnType ) );
}
else
{
var xCtor = aMethod as ConstructorInfo;
if( xCtor != null )
{
xBuilder.Append( typeof( void ).FullName );
}
else
{
xBuilder.Append( xParts[ 0 ] );
}
}
xBuilder.Append( " " );
xBuilder.Append( GetFullName( aMethod.DeclaringType ) );
xBuilder.Append( "." );
xBuilder.Append( aMethod.Name );
if( aMethod.IsGenericMethod || aMethod.IsGenericMethodDefinition )
{
var xGenArgs = aMethod.GetGenericArguments();
if( xGenArgs.Length > 0 )
{
xBuilder.Append( "<" );
for( int i = 0; i < xGenArgs.Length - 1; i++ )
{
xBuilder.Append( GetFullName( xGenArgs[ i ] ) );
xBuilder.Append( ", " );
}
xBuilder.Append( GetFullName( xGenArgs.Last() ) );
xBuilder.Append( ">" );
}
}
xBuilder.Append( "(" );
var xParams = aMethod.GetParameters();
for( var i = 0; i < xParams.Length; i++ )
{
if( xParams[ i ].Name == "aThis" && i == 0 )
{
continue;
}
xBuilder.Append( GetFullName( xParams[ i ].ParameterType ) );
if( i < ( xParams.Length - 1 ) )
{
xBuilder.Append( ", " );
}
}
xBuilder.Append( ")" );
return String.Intern( xBuilder.ToString() );
}
public static string GetFullName( FieldInfo aField )
{
return GetFullName( aField.FieldType ) + " " + GetFullName( aField.DeclaringType ) + "." + aField.Name;
//var xSB = new StringBuilder(aField.FieldType.FullName.Length + 1 + aField.DeclaringType.FullName.Length + 1 + aField.Name);
//xSB.Append(aField.FieldType.FullName);
//xSB.Append(" ");
//xSB.Append(aField.DeclaringType.FullName);
//xSB.Append(".");
//xSB.Append(aField.Name);
//return String.Intern(xSB.ToString());
}
}
}