incremental changes
This commit is contained in:
parent
9181b2ab62
commit
5aa43c15ee
@ -16,9 +16,12 @@ System.ArithmeticException
|
|||||||
System.ArrayTypeMismatchException
|
System.ArrayTypeMismatchException
|
||||||
System.ApplicationException
|
System.ApplicationException
|
||||||
System.Comparison`*
|
System.Comparison`*
|
||||||
|
System.Convert
|
||||||
System.Converter`*
|
System.Converter`*
|
||||||
System.DateTime
|
System.DateTime
|
||||||
|
System.DBNull
|
||||||
System.DllNotFoundException
|
System.DllNotFoundException
|
||||||
|
System.Empty
|
||||||
System.EventArgs
|
System.EventArgs
|
||||||
System.EventHandler
|
System.EventHandler
|
||||||
System.EventHandler`*
|
System.EventHandler`*
|
||||||
@ -49,6 +52,7 @@ System.Nullable`*
|
|||||||
System.SystemException
|
System.SystemException
|
||||||
System.OverflowException
|
System.OverflowException
|
||||||
|
|
||||||
|
System.Collections.Comparer
|
||||||
System.Collections.ICollection
|
System.Collections.ICollection
|
||||||
System.Collections.IDictionary
|
System.Collections.IDictionary
|
||||||
System.Collections.IDictionaryEnumerator
|
System.Collections.IDictionaryEnumerator
|
||||||
@ -147,6 +151,7 @@ System.Reflection.Assembly
|
|||||||
System.Reflection.AssemblyName
|
System.Reflection.AssemblyName
|
||||||
System.Reflection.AssemblyNameFlags
|
System.Reflection.AssemblyNameFlags
|
||||||
System.Reflection.AssemblyProductAttribute
|
System.Reflection.AssemblyProductAttribute
|
||||||
|
System.Reflection.Binder
|
||||||
System.Reflection.BindingFlags
|
System.Reflection.BindingFlags
|
||||||
System.Reflection.CallingConventions
|
System.Reflection.CallingConventions
|
||||||
System.Reflection.IReflect
|
System.Reflection.IReflect
|
||||||
@ -160,9 +165,12 @@ System.Reflection.TypeInfo
|
|||||||
System.Reflection.MemberFilter
|
System.Reflection.MemberFilter
|
||||||
System.Reflection.Missing
|
System.Reflection.Missing
|
||||||
System.Reflection.ICustomAttributeProvider
|
System.Reflection.ICustomAttributeProvider
|
||||||
|
System.Reflection.InterfaceMapping
|
||||||
System.Reflection.InvalidFilterCriteriaException
|
System.Reflection.InvalidFilterCriteriaException
|
||||||
System.Reflection.IReflectableType
|
System.Reflection.IReflectableType
|
||||||
|
System.Reflection.ParameterModifier
|
||||||
System.Reflection.TypeAttributes
|
System.Reflection.TypeAttributes
|
||||||
|
System.Reflection.TypeFilter
|
||||||
System.Reflection.TargetParameterCountException
|
System.Reflection.TargetParameterCountException
|
||||||
System.Reflection.TargetInvocationException
|
System.Reflection.TargetInvocationException
|
||||||
System.IRuntimeMethodInfo
|
System.IRuntimeMethodInfo
|
||||||
|
@ -5,6 +5,8 @@ namespace system.collections
|
|||||||
[java.attr.AsInterface]
|
[java.attr.AsInterface]
|
||||||
public abstract class IComparer : java.lang.Comparable, java.util.Comparator
|
public abstract class IComparer : java.lang.Comparable, java.util.Comparator
|
||||||
{
|
{
|
||||||
|
public abstract int Compare(object x, object y);
|
||||||
|
|
||||||
[java.attr.RetainName]
|
[java.attr.RetainName]
|
||||||
public int compareTo(object obj)
|
public int compareTo(object obj)
|
||||||
=> ((System.Collections.IComparer) this).Compare(this, obj);
|
=> ((System.Collections.IComparer) this).Compare(this, obj);
|
||||||
@ -26,6 +28,11 @@ namespace system.collections.generic
|
|||||||
[java.attr.AsInterface]
|
[java.attr.AsInterface]
|
||||||
public abstract class IComparer<T> : java.lang.Comparable, java.util.Comparator
|
public abstract class IComparer<T> : java.lang.Comparable, java.util.Comparator
|
||||||
{
|
{
|
||||||
|
// a generic variance field is created for this abstract class,
|
||||||
|
// see also GenericUtil::CreateGenericVarianceField()
|
||||||
|
|
||||||
|
public abstract int Compare(T x, T y);
|
||||||
|
|
||||||
[java.attr.RetainName]
|
[java.attr.RetainName]
|
||||||
public int compareTo(object obj)
|
public int compareTo(object obj)
|
||||||
=> ((System.Collections.Generic.IComparer<T>) this).Compare((T) (object) this, (T) obj);
|
=> ((System.Collections.Generic.IComparer<T>) this).Compare((T) (object) this, (T) obj);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace system
|
namespace system
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +8,12 @@ namespace system
|
|||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public abstract class Enum : system.ValueType, system.ValueMethod, System.IComparable,
|
public abstract class Enum : system.ValueType, system.ValueMethod, System.IComparable,
|
||||||
System.IFormattable //System.IConvertible
|
System.IFormattable, System.IConvertible
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// warning, do not add fields in this class.
|
||||||
|
// doing so will interfere with enumeration of constants.
|
||||||
|
|
||||||
//
|
//
|
||||||
// getters and setters
|
// getters and setters
|
||||||
//
|
//
|
||||||
@ -80,31 +85,105 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// GetUnderlyingType
|
// ToObject
|
||||||
|
//
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, long value)
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
|
if (! enumType.IsEnum)
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
var enumRuntimeType = enumType as RuntimeType;
|
||||||
|
if (enumRuntimeType == null)
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
return Box(value, enumRuntimeType.JavaClassForArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, ulong value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, uint value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, int value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, ushort value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, short value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, char value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, byte value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, sbyte value)
|
||||||
|
=> ToObject(enumType, (long) value);
|
||||||
|
|
||||||
|
public static object ToObject(System.Type enumType, bool value)
|
||||||
|
=> ToObject(enumType, value ? 1L : 0L);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// HasFlag
|
||||||
|
//
|
||||||
|
|
||||||
|
public bool HasFlag(Enum flag)
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowIfNull(flag);
|
||||||
|
if (! this.GetType().IsEquivalentTo(flag.GetType()))
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
var v = flag.GetLong();
|
||||||
|
return (GetLong() & v) == v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// implemented via System.Type: GetUnderlyingType, GetTypeCode,
|
||||||
|
// IsDefined, GetName, GetNames, GetValues
|
||||||
//
|
//
|
||||||
|
|
||||||
public static System.Type GetUnderlyingType(System.Type enumType)
|
public static System.Type GetUnderlyingType(System.Type enumType)
|
||||||
{
|
{
|
||||||
ThrowHelper.ThrowIfNull(enumType);
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
return enumType.GetEnumUnderlyingType();
|
return enumType.GetEnumUnderlyingType();
|
||||||
#if false
|
}
|
||||||
if (enumType.IsEnum && enumType is RuntimeType enumRuntimeType)
|
|
||||||
{
|
public System.TypeCode GetTypeCode()
|
||||||
var fields = enumRuntimeType.JavaClassForArray().getDeclaredFields();
|
{
|
||||||
if (fields.Length > 1)
|
var typeCode = System.Type.GetTypeCode(GetType().GetEnumUnderlyingType());
|
||||||
{
|
if ((int) typeCode >= 3 && (int) typeCode <= 12) // boolean .. uint64
|
||||||
var f = fields[0];
|
return typeCode;
|
||||||
if ((f.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)
|
throw new System.InvalidOperationException();
|
||||||
{
|
}
|
||||||
var fldType = system.RuntimeType.GetType(f.getType());
|
|
||||||
var typeCode = (int) System.Type.GetTypeCode(fldType);
|
public static bool IsDefined(System.Type enumType, object value)
|
||||||
if (typeCode >= 4 && typeCode <= 12)
|
{
|
||||||
return fldType;
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
}
|
return enumType.IsEnumDefined(value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
throw new System.ArgumentException();
|
public static string GetName(System.Type enumType, object value)
|
||||||
#endif
|
{
|
||||||
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
|
return enumType.GetEnumName(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] GetNames(System.Type enumType)
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
|
return enumType.GetEnumNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static System.Array GetValues(System.Type enumType)
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowIfNull(enumType);
|
||||||
|
return enumType.GetEnumValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,33 +245,21 @@ namespace system
|
|||||||
{
|
{
|
||||||
if (format.Length == 1)
|
if (format.Length == 1)
|
||||||
{
|
{
|
||||||
bool asFlags = false;
|
switch (Char.ToUpperInvariant(format[0]))
|
||||||
switch (format[0])
|
|
||||||
{
|
{
|
||||||
case 'f': case 'F':
|
case 'F': return FormatNames(cls, value, true);
|
||||||
asFlags = true;
|
case 'G': return FormatNames(cls, value,
|
||||||
goto case 'G';
|
((java.lang.Class) typeof (EnumFlags))
|
||||||
|
.isAssignableFrom(cls));
|
||||||
case 'g': case 'G':
|
case 'D': return java.lang.Long.toString(value);
|
||||||
if (! asFlags)
|
case 'X': return FormatHex(cls, value);
|
||||||
{
|
};
|
||||||
asFlags = ((java.lang.Class) typeof (EnumFlags))
|
|
||||||
.isAssignableFrom(cls);
|
|
||||||
}
|
|
||||||
return FormatNames(cls, asFlags, value);
|
|
||||||
|
|
||||||
case 'd': case 'D':
|
|
||||||
return java.lang.Long.toString(value);
|
|
||||||
|
|
||||||
case 'x': case 'X':
|
|
||||||
return java.lang.Long.toHexString(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new System.FormatException();
|
throw new System.FormatException();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static string FormatNames(java.lang.Class cls, bool asFlags, long v)
|
static string FormatNames(java.lang.Class cls, long v, bool asFlags)
|
||||||
{
|
{
|
||||||
var fields = cls.getDeclaredFields();
|
var fields = cls.getDeclaredFields();
|
||||||
int n = fields.Length;
|
int n = fields.Length;
|
||||||
@ -252,10 +319,85 @@ namespace system
|
|||||||
|
|
||||||
return (v == 0) ? sb.ToString() : null;
|
return (v == 0) ? sb.ToString() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string FormatHex(java.lang.Class cls, long v)
|
||||||
|
{
|
||||||
|
var typeCode = System.Type.GetTypeCode(
|
||||||
|
system.RuntimeType.GetType(cls).GetEnumUnderlyingType());
|
||||||
|
var hexfmt = typeCode switch
|
||||||
|
{
|
||||||
|
System.TypeCode.Boolean => "%02X",
|
||||||
|
System.TypeCode.Char => "%04X",
|
||||||
|
System.TypeCode.SByte => "%02X",
|
||||||
|
System.TypeCode.Byte => "%02X",
|
||||||
|
System.TypeCode.Int16 => "%04X",
|
||||||
|
System.TypeCode.UInt16 => "%04X",
|
||||||
|
System.TypeCode.Int32 => "%08X",
|
||||||
|
System.TypeCode.UInt32 => "%08X",
|
||||||
|
System.TypeCode.Int64 => "%016X",
|
||||||
|
System.TypeCode.UInt64 => "%016X",
|
||||||
|
_ => throw new System.InvalidOperationException()
|
||||||
|
};
|
||||||
|
return java.lang.String.format(
|
||||||
|
hexfmt, new object[] { java.lang.Long.valueOf(v) });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// IConvertible
|
||||||
|
//
|
||||||
|
|
||||||
|
bool System.IConvertible.ToBoolean(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToBoolean(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
char System.IConvertible.ToChar(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToChar(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
sbyte System.IConvertible.ToSByte(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToSByte(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
byte System.IConvertible.ToByte(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToByte(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
short System.IConvertible.ToInt16(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt16(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
ushort System.IConvertible.ToUInt16(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt16(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
int System.IConvertible.ToInt32(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt32(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
uint System.IConvertible.ToUInt32(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt32(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
long System.IConvertible.ToInt64(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt64(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
ulong System.IConvertible.ToUInt64(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt64(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
float System.IConvertible.ToSingle(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToSingle(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
double System.IConvertible.ToDouble(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToDouble(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToDecimal(GetLong(), CultureInfo.CurrentCulture);
|
||||||
|
|
||||||
|
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
||||||
|
=> throw new System.InvalidCastException();
|
||||||
|
|
||||||
|
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
||||||
|
=> system.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
||||||
|
|
||||||
|
//
|
||||||
|
// value methods
|
||||||
|
//
|
||||||
|
|
||||||
void ValueMethod.Clear() => SetLong(0L);
|
void ValueMethod.Clear() => SetLong(0L);
|
||||||
void ValueMethod.CopyTo(ValueType into) => ((Enum) into).SetLong(GetLong());
|
void ValueMethod.CopyTo(ValueType into) => ((Enum) into).SetLong(GetLong());
|
||||||
ValueType ValueMethod.Clone() => (ValueType) this.MemberwiseClone();
|
ValueType ValueMethod.Clone() => (ValueType) this.MemberwiseClone();
|
||||||
|
@ -120,6 +120,12 @@ namespace system
|
|||||||
{
|
{
|
||||||
if (genericObject.TryCast(castToType) != null)
|
if (genericObject.TryCast(castToType) != null)
|
||||||
return obj;
|
return obj;
|
||||||
|
if (obj is system.Array.ProxySyncRoot objArray)
|
||||||
|
{
|
||||||
|
var proxy = Array.GetProxy(objArray.SyncRoot, castToType, false);
|
||||||
|
if (proxy != null)
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,9 @@ namespace system.globalization {
|
|||||||
|
|
||||||
public virtual CompareInfo CompareInfo => CompareInfoRef;
|
public virtual CompareInfo CompareInfo => CompareInfoRef;
|
||||||
|
|
||||||
|
public static CultureInfo CurrentCulture
|
||||||
|
=> system.threading.Thread.CurrentThread.CurrentCulture;
|
||||||
|
|
||||||
public static CultureInfo InvariantCulture => s_InvariantCultureInfo;
|
public static CultureInfo InvariantCulture => s_InvariantCultureInfo;
|
||||||
|
|
||||||
public virtual object Clone() => throw new System.NotImplementedException();
|
public virtual object Clone() => throw new System.NotImplementedException();
|
||||||
|
@ -3,6 +3,7 @@ namespace system
|
|||||||
{
|
{
|
||||||
|
|
||||||
public class Int16 : system.ValueType, system.ValueMethod,
|
public class Int16 : system.ValueType, system.ValueMethod,
|
||||||
|
System.IComparable, System.IComparable<short>,
|
||||||
System.IConvertible, System.IEquatable<short>, System.IFormattable
|
System.IConvertible, System.IEquatable<short>, System.IFormattable
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -46,10 +47,32 @@ namespace system
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(format))
|
if (string.IsNullOrEmpty(format))
|
||||||
return ToString();
|
return ToString();
|
||||||
return ParseNumbers.FormatNumber(
|
return ParseNumbers.FormatNumber((java.lang.String) (object) format, provider,
|
||||||
(java.lang.String) (object) format, provider, java.lang.Integer.valueOf(Get()));
|
java.lang.Short.valueOf((short) Get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ToString(string format) => ToString(format, null);
|
||||||
|
|
||||||
|
public string ToString(System.IFormatProvider provider) => ToString();
|
||||||
|
|
||||||
|
// System.IComparable
|
||||||
|
public virtual int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals(obj, null))
|
||||||
|
return 1;
|
||||||
|
if (obj is Int16 objInt16)
|
||||||
|
return CompareTo((short) objInt16.Get());
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.IComparable<short>
|
||||||
|
public int CompareTo(short b)
|
||||||
|
{
|
||||||
|
int a = Get();
|
||||||
|
return (a < b ? -1 : a > b ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ValueMethod.Clear() => Set(0);
|
void ValueMethod.Clear() => Set(0);
|
||||||
@ -134,11 +157,9 @@ namespace system
|
|||||||
System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
||||||
=> System.Convert.ToDecimal(Get());
|
=> System.Convert.ToDecimal(Get());
|
||||||
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
||||||
=> throw new System.InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo_Int32_DateTime"));
|
=> throw new System.InvalidCastException();
|
||||||
string System.IConvertible.ToString(System.IFormatProvider provider)
|
|
||||||
=> ToString();
|
|
||||||
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
||||||
=> null;//System.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
=> system.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -171,7 +192,7 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
#pragma warning disable 0659
|
#pragma warning disable 0659
|
||||||
public class UInt16 : Int16, System.IEquatable<ushort>
|
public class UInt16 : Int16, System.IComparable<ushort>, System.IEquatable<ushort>
|
||||||
{
|
{
|
||||||
|
|
||||||
new public static UInt16 Box(int v) => new UInt16() { v = (short) v };
|
new public static UInt16 Box(int v) => new UInt16() { v = (short) v };
|
||||||
@ -191,6 +212,17 @@ namespace system
|
|||||||
|
|
||||||
public override System.TypeCode GetTypeCode() => System.TypeCode.UInt16;
|
public override System.TypeCode GetTypeCode() => System.TypeCode.UInt16;
|
||||||
|
|
||||||
|
// System.IComparable
|
||||||
|
public override int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals(obj, null))
|
||||||
|
return 1;
|
||||||
|
if (obj is UInt16 objUInt16)
|
||||||
|
return CompareTo((ushort) objUInt16.Get());
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.IComparable<ushort>
|
||||||
public int CompareTo(ushort v) => CompareTo((short) Get(), (short) v);
|
public int CompareTo(ushort v) => CompareTo((short) Get(), (short) v);
|
||||||
|
|
||||||
public static int CompareTo(short a, short b)
|
public static int CompareTo(short a, short b)
|
||||||
|
@ -3,6 +3,7 @@ namespace system
|
|||||||
{
|
{
|
||||||
|
|
||||||
public class Int32 : system.ValueType, system.ValueMethod,
|
public class Int32 : system.ValueType, system.ValueMethod,
|
||||||
|
System.IComparable, System.IComparable<int>,
|
||||||
System.IConvertible, System.IEquatable<int>, System.IFormattable
|
System.IConvertible, System.IEquatable<int>, System.IFormattable
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -49,14 +50,31 @@ namespace system
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(format))
|
if (string.IsNullOrEmpty(format))
|
||||||
return ToString();
|
return ToString();
|
||||||
return ParseNumbers.FormatNumber(
|
return ParseNumbers.FormatNumber((java.lang.String) (object) format, provider,
|
||||||
(java.lang.String) (object) format, provider, java.lang.Integer.valueOf(Get()));
|
java.lang.Integer.valueOf(Get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ToString(string format) => ToString(format, null);
|
public string ToString(string format) => ToString(format, null);
|
||||||
|
|
||||||
public string ToString(System.IFormatProvider provider) => ToString();
|
public string ToString(System.IFormatProvider provider) => ToString();
|
||||||
|
|
||||||
|
// System.IComparable
|
||||||
|
public virtual int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals(obj, null))
|
||||||
|
return 1;
|
||||||
|
if (obj is Int32 objInt32)
|
||||||
|
return CompareTo((int) objInt32.Get());
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.IComparable<int>
|
||||||
|
public int CompareTo(int b)
|
||||||
|
{
|
||||||
|
int a = Get();
|
||||||
|
return (a < b ? -1 : a > b ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int OverflowAdd(int a, int b)
|
public static int OverflowAdd(int a, int b)
|
||||||
@ -189,11 +207,9 @@ namespace system
|
|||||||
System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
||||||
=> System.Convert.ToDecimal(Get());
|
=> System.Convert.ToDecimal(Get());
|
||||||
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
||||||
=> throw new System.InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo_Int32_DateTime"));
|
=> throw new System.InvalidCastException();
|
||||||
string System.IConvertible.ToString(System.IFormatProvider provider)
|
|
||||||
=> ToString();
|
|
||||||
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
||||||
=> null;//System.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
=> system.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -231,7 +247,7 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
#pragma warning disable 0659
|
#pragma warning disable 0659
|
||||||
public class UInt32 : Int32, System.IEquatable<uint>
|
public class UInt32 : Int32, System.IComparable<uint>, System.IEquatable<uint>
|
||||||
{
|
{
|
||||||
|
|
||||||
new public static UInt32 Box(int v) => new UInt32() { v = v };
|
new public static UInt32 Box(int v) => new UInt32() { v = v };
|
||||||
@ -254,8 +270,17 @@ namespace system
|
|||||||
|
|
||||||
public override System.TypeCode GetTypeCode() => System.TypeCode.UInt32;
|
public override System.TypeCode GetTypeCode() => System.TypeCode.UInt32;
|
||||||
|
|
||||||
//public int CompareTo(uint v) => java.lang.Integer.compareUnsigned(Get(), (int) v);
|
// System.IComparable
|
||||||
|
public override int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals(obj, null))
|
||||||
|
return 1;
|
||||||
|
if (obj is UInt32 objUInt32)
|
||||||
|
return CompareTo((uint) objUInt32.Get());
|
||||||
|
throw new System.ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.IComparable<uint>
|
||||||
public int CompareTo(uint v) => CompareTo(Get(), (int) v);
|
public int CompareTo(uint v) => CompareTo(Get(), (int) v);
|
||||||
|
|
||||||
public static int CompareTo(int a, int b)
|
public static int CompareTo(int a, int b)
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
namespace system
|
namespace system
|
||||||
{
|
{
|
||||||
|
|
||||||
public class Int64 : system.ValueType, system.ValueMethod, java.lang.Cloneable
|
public class Int64 : system.ValueType, system.ValueMethod,
|
||||||
|
System.IConvertible, System.IEquatable<long>, System.IFormattable
|
||||||
{
|
{
|
||||||
|
|
||||||
[java.attr.RetainType] protected long v;
|
[java.attr.RetainType] protected long v;
|
||||||
@ -23,6 +24,9 @@ namespace system
|
|||||||
public static void Set(long v, Int64 o) => o.Set(v);
|
public static void Set(long v, Int64 o) => o.Set(v);
|
||||||
public static void VolatileSet(long v, Int64 o) => o.VolatileSet(v);
|
public static void VolatileSet(long v, Int64 o) => o.VolatileSet(v);
|
||||||
|
|
||||||
|
public virtual bool CompareAndSwap(long expect, long update) =>
|
||||||
|
Util.JavaUnsafe.compareAndSwapLong(this, ValueOffset, expect, update);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
@ -37,11 +41,28 @@ namespace system
|
|||||||
return ((int) v) ^ (int) (v >> 32);
|
return ((int) v) ^ (int) (v >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString() => java.lang.Long.toString(Get());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.IEquatable<long>
|
||||||
|
public bool Equals(long v) => v == Get();
|
||||||
|
|
||||||
|
// System.IFormattable
|
||||||
|
public string ToString(string format, System.IFormatProvider provider)
|
||||||
{
|
{
|
||||||
return java.lang.Long.toString(Get());
|
if (string.IsNullOrEmpty(format))
|
||||||
|
return ToString();
|
||||||
|
return ParseNumbers.FormatNumber((java.lang.String) (object) format, provider,
|
||||||
|
java.lang.Long.valueOf(Get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ToString(string format) => ToString(format, null);
|
||||||
|
|
||||||
|
public string ToString(System.IFormatProvider provider) => ToString();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static long OverflowAdd(long a, long b)
|
public static long OverflowAdd(long a, long b)
|
||||||
{
|
{
|
||||||
long c = a + b;
|
long c = a + b;
|
||||||
@ -123,6 +144,47 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// IConvertible
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public virtual System.TypeCode GetTypeCode() => System.TypeCode.Int64;
|
||||||
|
|
||||||
|
bool System.IConvertible.ToBoolean(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToBoolean(Get());
|
||||||
|
char System.IConvertible.ToChar(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToChar(Get());
|
||||||
|
sbyte System.IConvertible.ToSByte(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToSByte(Get());
|
||||||
|
byte System.IConvertible.ToByte(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToByte(Get());
|
||||||
|
short System.IConvertible.ToInt16(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt16(Get());
|
||||||
|
ushort System.IConvertible.ToUInt16(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt16(Get());
|
||||||
|
int System.IConvertible.ToInt32(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt32(Get());
|
||||||
|
uint System.IConvertible.ToUInt32(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt32(Get());
|
||||||
|
long System.IConvertible.ToInt64(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToInt64(Get());
|
||||||
|
ulong System.IConvertible.ToUInt64(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToUInt64(Get());
|
||||||
|
float System.IConvertible.ToSingle(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToSingle(Get());
|
||||||
|
double System.IConvertible.ToDouble(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToDouble(Get());
|
||||||
|
System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider)
|
||||||
|
=> System.Convert.ToDecimal(Get());
|
||||||
|
System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider)
|
||||||
|
=> throw new System.InvalidCastException();
|
||||||
|
object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider)
|
||||||
|
=> system.Convert.DefaultToType((System.IConvertible) this, type, provider);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// InArray
|
// InArray
|
||||||
//
|
//
|
||||||
@ -147,6 +209,9 @@ namespace system
|
|||||||
public override void Set(long v) => a[i] = v;
|
public override void Set(long v) => a[i] = v;
|
||||||
public override void VolatileSet(long v) =>
|
public override void VolatileSet(long v) =>
|
||||||
Util.JavaUnsafe.putLongVolatile(a, Util.ElementOffset64(i), v);
|
Util.JavaUnsafe.putLongVolatile(a, Util.ElementOffset64(i), v);
|
||||||
|
|
||||||
|
public override bool CompareAndSwap(long expect, long update) =>
|
||||||
|
Util.JavaUnsafe.compareAndSwapLong(a, Util.ElementOffset64(i), expect, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -167,7 +232,7 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
#pragma warning disable 0659
|
#pragma warning disable 0659
|
||||||
public class UInt64 : Int64
|
public class UInt64 : Int64, System.IEquatable<ulong>
|
||||||
{
|
{
|
||||||
|
|
||||||
new public static UInt64 Box(long v) => new UInt64() { v = v };
|
new public static UInt64 Box(long v) => new UInt64() { v = v };
|
||||||
@ -176,12 +241,20 @@ namespace system
|
|||||||
public static void Set(long v, UInt64 o) => o.Set(v);
|
public static void Set(long v, UInt64 o) => o.Set(v);
|
||||||
public static void VolatileSet(long v, UInt64 o) => o.VolatileSet(v);
|
public static void VolatileSet(long v, UInt64 o) => o.VolatileSet(v);
|
||||||
|
|
||||||
|
public override bool CompareAndSwap(long expect, long update) =>
|
||||||
|
throw new System.NotSupportedException();
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
var objUInt64 = obj as UInt64;
|
var objUInt64 = obj as UInt64;
|
||||||
return (objUInt64 != null && objUInt64.Get() == Get());
|
return (objUInt64 != null && objUInt64.Get() == Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System.IEquatable<ulong>
|
||||||
|
public bool Equals(ulong v) => v == (ulong) Get();
|
||||||
|
|
||||||
|
public override System.TypeCode GetTypeCode() => System.TypeCode.UInt64;
|
||||||
|
|
||||||
//public int CompareTo(ulong v) => java.lang.Long.compareUnsigned(Get(), (long) v);
|
//public int CompareTo(ulong v) => java.lang.Long.compareUnsigned(Get(), (long) v);
|
||||||
|
|
||||||
public int CompareTo(ulong v) => CompareTo(Get(), (long) v);
|
public int CompareTo(ulong v) => CompareTo(Get(), (long) v);
|
||||||
|
@ -14,6 +14,10 @@ namespace system.reflection
|
|||||||
MemberTypes memberType,
|
MemberTypes memberType,
|
||||||
System.Predicate<java.lang.reflect.AccessibleObject> callback)
|
System.Predicate<java.lang.reflect.AccessibleObject> callback)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// calculate modifier AND mask and result for matches
|
||||||
|
//
|
||||||
|
|
||||||
int modifierMask = 0;
|
int modifierMask = 0;
|
||||||
int modifierValue = 0;
|
int modifierValue = 0;
|
||||||
|
|
||||||
@ -43,6 +47,10 @@ namespace system.reflection
|
|||||||
}
|
}
|
||||||
bindingAttr &= ~chk;
|
bindingAttr &= ~chk;
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if iteration is required on base hierarchy
|
||||||
|
//
|
||||||
|
|
||||||
RuntimeType stopAtType = null;
|
RuntimeType stopAtType = null;
|
||||||
if ((bindingAttr & BindingFlags.DeclaredOnly) != 0)
|
if ((bindingAttr & BindingFlags.DeclaredOnly) != 0)
|
||||||
{
|
{
|
||||||
@ -50,6 +58,10 @@ namespace system.reflection
|
|||||||
bindingAttr &= ~BindingFlags.DeclaredOnly;
|
bindingAttr &= ~BindingFlags.DeclaredOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// run iteration
|
||||||
|
//
|
||||||
|
|
||||||
if (bindingAttr != 0)
|
if (bindingAttr != 0)
|
||||||
{
|
{
|
||||||
throw new System.PlatformNotSupportedException(
|
throw new System.PlatformNotSupportedException(
|
||||||
|
@ -25,7 +25,7 @@ namespace system.reflection
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// GetFields (called by system.RuntimeType.GetFields(GetFields)
|
// GetFields (called by system.RuntimeType.GetFields()
|
||||||
//
|
//
|
||||||
|
|
||||||
public static FieldInfo[] GetFields(BindingFlags bindingAttr, RuntimeType initialType)
|
public static FieldInfo[] GetFields(BindingFlags bindingAttr, RuntimeType initialType)
|
||||||
@ -35,8 +35,9 @@ namespace system.reflection
|
|||||||
BindingFlagsIterator.Run(bindingAttr, initialType, MemberTypes.Field,
|
BindingFlagsIterator.Run(bindingAttr, initialType, MemberTypes.Field,
|
||||||
(javaAccessibleObject) =>
|
(javaAccessibleObject) =>
|
||||||
{
|
{
|
||||||
list.Add(new RuntimeFieldInfo((java.lang.reflect.Field) javaAccessibleObject,
|
var javaField = (java.lang.reflect.Field) javaAccessibleObject;
|
||||||
initialType));
|
javaField.setAccessible(true);
|
||||||
|
list.Add(new RuntimeFieldInfo(javaField, initialType));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -66,8 +67,35 @@ namespace system.reflection
|
|||||||
public override System.Type ReflectedType
|
public override System.Type ReflectedType
|
||||||
=> throw new PlatformNotSupportedException();
|
=> throw new PlatformNotSupportedException();
|
||||||
|
|
||||||
public override string Name
|
public override string Name => JavaField.getName();
|
||||||
=> throw new PlatformNotSupportedException();
|
|
||||||
|
public override object GetRawConstantValue()
|
||||||
|
{
|
||||||
|
if ((JavaField.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
|
||||||
|
{
|
||||||
|
var value = JavaField.get(null);
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case java.lang.Boolean boolBox:
|
||||||
|
return system.Boolean.Box(boolBox.booleanValue() ? 1 : 0);
|
||||||
|
case java.lang.Byte byteBox:
|
||||||
|
return system.SByte.Box(byteBox.byteValue());
|
||||||
|
case java.lang.Character charBox:
|
||||||
|
return system.Char.Box(charBox.charValue());
|
||||||
|
case java.lang.Short shortBox:
|
||||||
|
return system.Int16.Box(shortBox.shortValue());
|
||||||
|
case java.lang.Integer intBox:
|
||||||
|
return system.Int32.Box(intBox.intValue());
|
||||||
|
case java.lang.Long longBox:
|
||||||
|
return system.Int64.Box(longBox.longValue());
|
||||||
|
case java.lang.Float floatBox:
|
||||||
|
return system.Single.Box(floatBox.floatValue());
|
||||||
|
case java.lang.Double doubleBox:
|
||||||
|
return system.Double.Box(doubleBox.doubleValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new System.NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override System.RuntimeFieldHandle FieldHandle
|
public override System.RuntimeFieldHandle FieldHandle
|
||||||
=> throw new PlatformNotSupportedException();
|
=> throw new PlatformNotSupportedException();
|
||||||
|
@ -52,92 +52,42 @@ namespace system.reflection
|
|||||||
// calculate modifier AND mask and result for matches
|
// calculate modifier AND mask and result for matches
|
||||||
//
|
//
|
||||||
|
|
||||||
int modifierMask = 0;
|
RuntimeMethodInfo foundMethod = null;
|
||||||
int modifierValue = 0;
|
|
||||||
|
|
||||||
BindingFlags chk = bindingAttr & (BindingFlags.Public | BindingFlags.NonPublic);
|
BindingFlagsIterator.Run(bindingAttr, initialType, MemberTypes.Method,
|
||||||
if (chk != (BindingFlags.Public | BindingFlags.NonPublic))
|
(javaAccessibleObject) =>
|
||||||
{
|
|
||||||
if (chk == 0) // if neither, no methods will match
|
|
||||||
return null;
|
|
||||||
// methods with internal access are converted to public access,
|
|
||||||
// so we cannot honor the distinction between Public and NonPublic
|
|
||||||
/*
|
|
||||||
modifierMask |= java.lang.reflect.Modifier.PUBLIC;
|
|
||||||
if (chk == BindingFlags.Public)
|
|
||||||
modifierValue |= java.lang.reflect.Modifier.PUBLIC;
|
|
||||||
*/
|
|
||||||
bindingAttr &= ~chk;
|
|
||||||
}
|
|
||||||
|
|
||||||
chk = bindingAttr & (BindingFlags.Static | BindingFlags.Instance);
|
|
||||||
if (chk != (BindingFlags.Static | BindingFlags.Instance))
|
|
||||||
{
|
|
||||||
if (chk == 0) // if neither, no methods will match
|
|
||||||
return null;
|
|
||||||
modifierMask |= java.lang.reflect.Modifier.STATIC;
|
|
||||||
if (chk == BindingFlags.Static)
|
|
||||||
modifierValue |= java.lang.reflect.Modifier.STATIC;
|
|
||||||
bindingAttr &= ~chk;
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeType stopAtType = null;
|
|
||||||
if ((bindingAttr & BindingFlags.DeclaredOnly) != 0)
|
|
||||||
{
|
|
||||||
stopAtType = initialType;
|
|
||||||
bindingAttr &= ~BindingFlags.DeclaredOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bindingAttr != 0)
|
|
||||||
throw new PlatformNotSupportedException("bad binding flags " + bindingAttr);
|
|
||||||
|
|
||||||
//
|
|
||||||
// collect methods from class and base classes
|
|
||||||
//
|
|
||||||
|
|
||||||
var currentType = initialType;
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
#pragma warning disable 0436
|
#pragma warning disable 0436
|
||||||
java.lang.reflect.Method[] javaMethods =
|
var javaMethod = (java.lang.reflect.Method) javaAccessibleObject;
|
||||||
(java.lang.reflect.Method[]) (object)
|
|
||||||
currentType.JavaClassForArray().getDeclaredMethods();
|
|
||||||
#pragma warning restore 0436
|
#pragma warning restore 0436
|
||||||
|
|
||||||
foreach (var javaMethod in javaMethods)
|
string originalName = javaMethod.getName();
|
||||||
{
|
// note the actual suffix character below is configured
|
||||||
int jmodifiers = javaMethod.getModifiers();
|
// in CilMain.cs, with special considerations for Android.
|
||||||
if ((jmodifiers & modifierMask) == modifierValue)
|
// we list all possible characters here, just in case.
|
||||||
{
|
int idx = originalName.IndexOf('\u00AB'); // U+00AB Left-Pointing Double Angle Quotation Mark
|
||||||
string originalName = javaMethod.getName();
|
if (idx == -1)
|
||||||
// note the actual suffix character below is configured
|
idx = originalName.IndexOf('\u00A1'); // U+00A1 Inverted Exclamation Mark
|
||||||
// in CilMain.cs, with special considerations for Android.
|
if (idx == -1)
|
||||||
// we list all possible characters here, just in case.
|
idx = originalName.IndexOf('(');
|
||||||
int idx = originalName.IndexOf('\u00AB'); // U+00AB Left-Pointing Double Angle Quotation Mark
|
if (idx == -1)
|
||||||
if (idx == -1)
|
idx = originalName.IndexOf('!');
|
||||||
idx = originalName.IndexOf('\u00A1'); // U+00A1 Inverted Exclamation Mark
|
var compareName =
|
||||||
if (idx == -1)
|
(idx == -1) ? originalName : originalName.Substring(0, idx);
|
||||||
idx = originalName.IndexOf('(');
|
|
||||||
if (idx == -1)
|
|
||||||
idx = originalName.IndexOf('!');
|
|
||||||
var compareName =
|
|
||||||
(idx == -1) ? originalName : originalName.Substring(0, idx);
|
|
||||||
|
|
||||||
if (name == compareName)
|
if (name == compareName)
|
||||||
{
|
{
|
||||||
javaMethod.setAccessible(true);
|
javaMethod.setAccessible(true);
|
||||||
return new RuntimeMethodInfo(javaMethod, jmodifiers, initialType,
|
var jmodifiers = javaMethod.getModifiers();
|
||||||
originalName, compareName);
|
foundMethod = new RuntimeMethodInfo(javaMethod, jmodifiers, initialType,
|
||||||
}
|
originalName, compareName);
|
||||||
}
|
return false; // stop iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
currentType = (system.RuntimeType) currentType.BaseType;
|
return true; // continue iteration
|
||||||
if (currentType == stopAtType)
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return foundMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -4,6 +4,8 @@ using System.Runtime.InteropServices;
|
|||||||
namespace system.reflection
|
namespace system.reflection
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public abstract class Module { }
|
||||||
|
|
||||||
public sealed class RuntimeModule
|
public sealed class RuntimeModule
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1433,6 +1433,54 @@ namespace system
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma warning disable 0436
|
||||||
|
public override System.Array GetEnumValues()
|
||||||
|
{
|
||||||
|
// the default implementation of System.Type::GetEnumValues()
|
||||||
|
// throws NotImplementedException, so we have to use reflection
|
||||||
|
// to invoke the underlying private method that does the work
|
||||||
|
|
||||||
|
if (! IsEnum)
|
||||||
|
throw new ArgumentException();
|
||||||
|
|
||||||
|
// the default implementation of System.Type::GetEnumValues()
|
||||||
|
// throws NotImplementedException, so we have to use reflection
|
||||||
|
// to invoke the underlying private method that does the work
|
||||||
|
|
||||||
|
if (GetEnumRawConstantValues == null)
|
||||||
|
{
|
||||||
|
var searchClass = (java.lang.Class) typeof(System.Type);
|
||||||
|
var modifierMask = java.lang.reflect.Modifier.PRIVATE
|
||||||
|
| java.lang.reflect.Modifier.FINAL
|
||||||
|
| java.lang.reflect.Modifier.STATIC;
|
||||||
|
var modifierValue = java.lang.reflect.Modifier.PRIVATE
|
||||||
|
| java.lang.reflect.Modifier.FINAL;
|
||||||
|
|
||||||
|
foreach (java.lang.reflect.Method method in
|
||||||
|
(java.lang.reflect.Method[]) (object) searchClass.getDeclaredMethods())
|
||||||
|
{
|
||||||
|
if ( (method.getModifiers() & modifierMask) == modifierValue
|
||||||
|
&& method.getParameterTypes().Length == 0
|
||||||
|
&& method.getReturnType() == (java.lang.Class) typeof(System.Array))
|
||||||
|
{
|
||||||
|
method.setAccessible(true);
|
||||||
|
GetEnumRawConstantValues = method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetEnumRawConstantValues != null)
|
||||||
|
{
|
||||||
|
return (System.Array) GetEnumRawConstantValues.invoke(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
[java.attr.RetainType] private static java.lang.reflect.Method GetEnumRawConstantValues;
|
||||||
|
#pragma warning restore 0436
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reflection on members of the type
|
// Reflection on members of the type
|
||||||
//
|
//
|
||||||
@ -1531,8 +1579,6 @@ namespace system
|
|||||||
public virtual int GenericParameterPosition
|
public virtual int GenericParameterPosition
|
||||||
public virtual Type[] GetGenericParameterConstraints()
|
public virtual Type[] GetGenericParameterConstraints()
|
||||||
|
|
||||||
public virtual Array GetEnumValues()
|
|
||||||
|
|
||||||
internal virtual string FormatTypeName(bool serialization)
|
internal virtual string FormatTypeName(bool serialization)
|
||||||
public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
|
public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +46,11 @@ namespace system
|
|||||||
|
|
||||||
count = count >> shift;
|
count = count >> shift;
|
||||||
this.array.Set(array = java.lang.reflect.Array.newInstance(cls, count));
|
this.array.Set(array = java.lang.reflect.Array.newInstance(cls, count));
|
||||||
|
if (! cls.isPrimitive())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
java.lang.reflect.Array.set(array, i, cls.newInstance());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -63,22 +67,14 @@ namespace system
|
|||||||
}
|
}
|
||||||
|
|
||||||
[java.attr.RetainName]
|
[java.attr.RetainName]
|
||||||
public static Span<object> Localloc(long bytes)
|
public static Span<ValueType> Localloc(long bytes)
|
||||||
{
|
{
|
||||||
// this helper method is invoked by code which uses the 'localloc'
|
// this helper method is invoked by code which uses the 'localloc'
|
||||||
// instruction. see also CodeSpan::Localloc method.
|
// instruction. see also CodeSpan::Localloc method.
|
||||||
int intBytes = (int) bytes;
|
int intBytes = (int) bytes;
|
||||||
if (intBytes != bytes)
|
if (intBytes != bytes)
|
||||||
throw new System.ArgumentOutOfRangeException();
|
throw new System.ArgumentOutOfRangeException();
|
||||||
return new Span<object>() { array = new Reference(), count = intBytes };
|
return new Span<ValueType>() { array = new Reference(), count = intBytes };
|
||||||
}
|
|
||||||
|
|
||||||
[java.attr.RetainName]
|
|
||||||
public static Span<char> String(java.lang.String str)
|
|
||||||
{
|
|
||||||
// this helper method is invoked by code which stores a string
|
|
||||||
// variable into a pointer. see also CodeSpan::Address method.
|
|
||||||
return new Span<char>(str.toCharArray()) { count = System.SByte.MinValue };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[java.attr.RetainName]
|
[java.attr.RetainName]
|
||||||
@ -115,6 +111,21 @@ namespace system
|
|||||||
return system.Array.Box(Array(null), start);
|
return system.Array.Box(Array(null), start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assign
|
||||||
|
//
|
||||||
|
// this helper method is invoked by code which stores an address into
|
||||||
|
// a pointer. see also CodeSpan::Address method.
|
||||||
|
//
|
||||||
|
|
||||||
|
[java.attr.RetainName]
|
||||||
|
public static Span<char> Assign(java.lang.String str)
|
||||||
|
=> new Span<char>(str.toCharArray()) { count = System.SByte.MinValue };
|
||||||
|
|
||||||
|
[java.attr.RetainName]
|
||||||
|
public static System.ValueType Assign(ValueType source)
|
||||||
|
=> new Span<T>((T[]) (object) (new ValueType[1] { source }));
|
||||||
|
|
||||||
//
|
//
|
||||||
// helper methods to access a span of a primitive type.
|
// helper methods to access a span of a primitive type.
|
||||||
// see also CodeSpan::LoadStore method.
|
// see also CodeSpan::LoadStore method.
|
||||||
@ -150,8 +161,24 @@ namespace system
|
|||||||
public double LoadD() => ((double[]) Array(java.lang.Double.TYPE))[start];
|
public double LoadD() => ((double[]) Array(java.lang.Double.TYPE))[start];
|
||||||
public void StoreD(double value) => ((double[]) Array(java.lang.Double.TYPE))[start] = value;
|
public void StoreD(double value) => ((double[]) Array(java.lang.Double.TYPE))[start] = value;
|
||||||
|
|
||||||
public object Load() => ((object[]) Array((java.lang.Class) typeof(object)))[start];
|
//
|
||||||
public void Store(object value) => ((object[]) Array((java.lang.Class) typeof(object)))[start] = value;
|
// helper methods to access a span of a value type.
|
||||||
|
// see also CodeSpan::LoadStore method.
|
||||||
|
//
|
||||||
|
|
||||||
|
public system.ValueType Load(java.lang.Class cls)
|
||||||
|
=> (system.ValueType) java.lang.reflect.Array.get(Array(cls), start);
|
||||||
|
|
||||||
|
public void Store(ValueType value, java.lang.Class cls)
|
||||||
|
=> ((ValueMethod) value).CopyTo(Load(cls));
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
if (this.array != null && this.array.Get() != null)
|
||||||
|
{
|
||||||
|
((ValueMethod) Load(null)).Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// System.Span methods
|
// System.Span methods
|
||||||
|
@ -91,4 +91,14 @@ namespace system
|
|||||||
ValueType Clone();
|
ValueType Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[java.attr.Discard] // discard in output
|
||||||
|
public static class Convert
|
||||||
|
{
|
||||||
|
// called by various implementations of System.IConvertible.ToType
|
||||||
|
[java.attr.Discard] extern public static object DefaultToType(
|
||||||
|
System.IConvertible value, System.Type targetType, System.IFormatProvider provider);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,20 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal static void MakeRoomForCategory2ValueOnStack(JavaCode code)
|
||||||
|
{
|
||||||
|
// ensure the stack has enough space for a category-2 value
|
||||||
|
if (code.StackMap != null)
|
||||||
|
{
|
||||||
|
code.StackMap.PushStack(JavaType.IntegerType);
|
||||||
|
code.StackMap.PushStack(JavaType.LongType);
|
||||||
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static List<JavaClass> Import(List<TypeDefinition> cilTypes)
|
public static List<JavaClass> Import(List<TypeDefinition> cilTypes)
|
||||||
{
|
{
|
||||||
if (_Where != null)
|
if (_Where != null)
|
||||||
|
@ -160,7 +160,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
if (defType.HasFields && numGeneric == 0)
|
if (defType.HasFields && numGeneric == 0)
|
||||||
{
|
{
|
||||||
var type = From(defType.Fields[0].FieldType);
|
var type = From(defType.Fields[0].FieldType);
|
||||||
if ((! type.IsReference) && type.PrimitiveType >= TypeCode.SByte
|
if ((! type.IsReference) && type.PrimitiveType >= TypeCode.Boolean
|
||||||
&& type.PrimitiveType <= TypeCode.UInt64)
|
&& type.PrimitiveType <= TypeCode.UInt64)
|
||||||
{
|
{
|
||||||
JavaName = ImportName(defType, 0);
|
JavaName = ImportName(defType, 0);
|
||||||
@ -733,10 +733,14 @@ namespace SpaceFlint.CilToJava
|
|||||||
private string VolatileName(string nm, bool isVolatile)
|
private string VolatileName(string nm, bool isVolatile)
|
||||||
=> ((UnboxedType.IsVolatile || isVolatile) ? ("Volatile" + nm) : nm);
|
=> ((UnboxedType.IsVolatile || isVolatile) ? ("Volatile" + nm) : nm);
|
||||||
|
|
||||||
public virtual void GetValue(JavaCode code, bool isVolatile = false) =>
|
public virtual void GetValue(JavaCode code, bool isVolatile = false)
|
||||||
|
{
|
||||||
code.NewInstruction(0xB6 /* invokevirtual */, ThisOrEnum,
|
code.NewInstruction(0xB6 /* invokevirtual */, ThisOrEnum,
|
||||||
new JavaMethodRef(VolatileName("Get", isVolatile),
|
new JavaMethodRef(VolatileName("Get", isVolatile),
|
||||||
UnboxedTypeInMethod));
|
UnboxedTypeInMethod));
|
||||||
|
if (UnboxedTypeInMethod.Category == 2)
|
||||||
|
CilMain.MakeRoomForCategory2ValueOnStack(code);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void SetValueOV(JavaCode code, bool isVolatile = false) =>
|
public virtual void SetValueOV(JavaCode code, bool isVolatile = false) =>
|
||||||
code.NewInstruction(0xB6 /* invokevirtual */, ThisOrEnum,
|
code.NewInstruction(0xB6 /* invokevirtual */, ThisOrEnum,
|
||||||
@ -783,6 +787,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
var innerOrEnum = GetInnerObject(code);
|
var innerOrEnum = GetInnerObject(code);
|
||||||
code.NewInstruction(0xB6 /* invokevirtual */, innerOrEnum,
|
code.NewInstruction(0xB6 /* invokevirtual */, innerOrEnum,
|
||||||
new JavaMethodRef("Get", UnboxedTypeInMethod));
|
new JavaMethodRef("Get", UnboxedTypeInMethod));
|
||||||
|
if (UnboxedTypeInMethod.Category == 2)
|
||||||
|
CilMain.MakeRoomForCategory2ValueOnStack(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetValueOV(JavaCode code, bool isVolatile = false)
|
public override void SetValueOV(JavaCode code, bool isVolatile = false)
|
||||||
|
@ -521,8 +521,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static bool MaybeGetProxy(CilType fromType, CilType intoType,
|
public static bool MaybeGetProxy(CilType fromType, CilType intoType, JavaCode code)
|
||||||
JavaCode code, bool pushFromType = false)
|
|
||||||
{
|
{
|
||||||
if ( fromType.IsArray
|
if ( fromType.IsArray
|
||||||
|| object.ReferenceEquals(fromType, GenericArrayType)
|
|| object.ReferenceEquals(fromType, GenericArrayType)
|
||||||
|
@ -237,7 +237,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TestGtLt(code, stackTop,
|
return TestGtLt(code, stackTop, stackTop2,
|
||||||
/* if greater than */ ( cilOp == Code.Bgt
|
/* if greater than */ ( cilOp == Code.Bgt
|
||||||
/* (vs less than) */ || cilOp == Code.Bgt_S
|
/* (vs less than) */ || cilOp == Code.Bgt_S
|
||||||
|| cilOp == Code.Bgt_Un
|
|| cilOp == Code.Bgt_Un
|
||||||
@ -286,7 +286,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
byte op = (cilOp == Code.Ceq)
|
byte op = (cilOp == Code.Ceq)
|
||||||
? TestEq(code, stackTop, stackTop2, cilInst)
|
? TestEq(code, stackTop, stackTop2, cilInst)
|
||||||
: TestGtLt(code, stackTop,
|
: TestGtLt(code, stackTop, stackTop2,
|
||||||
/* if greater than */ ( cilOp == Code.Cgt
|
/* if greater than */ ( cilOp == Code.Cgt
|
||||||
/* (vs less than) */ || cilOp == Code.Cgt_Un),
|
/* (vs less than) */ || cilOp == Code.Cgt_Un),
|
||||||
/* if unsigned */ ( cilOp == Code.Cgt_Un
|
/* if unsigned */ ( cilOp == Code.Cgt_Un
|
||||||
@ -326,7 +326,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
{
|
{
|
||||||
if (stackTop.IsReference || stackTop2.IsReference)
|
if (stackTop.IsReference || stackTop2.IsReference)
|
||||||
{
|
{
|
||||||
CodeSpan.Compare(stackTop, stackTop2, cilInst, code);
|
CodeSpan.CompareEq(stackTop, stackTop2, cilInst, code);
|
||||||
return 0xA5; // if_acmpeq (reference)
|
return 0xA5; // if_acmpeq (reference)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +373,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static byte TestGtLt(JavaCode code, JavaType stackTop, bool greater, bool unsigned_unordered)
|
static byte TestGtLt(JavaCode code, JavaType stackTop, JavaType stackTop2,
|
||||||
|
bool greater, bool unsigned_unordered)
|
||||||
{
|
{
|
||||||
byte op;
|
byte op;
|
||||||
|
|
||||||
@ -444,7 +445,15 @@ namespace SpaceFlint.CilToJava
|
|||||||
return 0xA6; // if_acmpne
|
return 0xA6; // if_acmpne
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (CodeSpan.CompareGtLt(stackTop, stackTop2, code))
|
||||||
|
{
|
||||||
|
return (byte) (greater ? 0x9D // ifgt
|
||||||
|
: 0x9B); // iflt
|
||||||
|
}
|
||||||
|
|
||||||
throw new InvalidProgramException();
|
throw new InvalidProgramException();
|
||||||
|
}
|
||||||
|
|
||||||
if (typeBits != 0)
|
if (typeBits != 0)
|
||||||
typeName = "UInt" + typeBits.ToString();
|
typeName = "UInt" + typeBits.ToString();
|
||||||
|
@ -140,7 +140,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
var dataType = CilType.From(typeRef);
|
var dataType = CilType.From(typeRef);
|
||||||
var fromType = (CilType) code.StackMap.PopStack(CilMain.Where);
|
var fromType = (CilType) code.StackMap.PopStack(CilMain.Where);
|
||||||
|
|
||||||
if (CodeSpan.LoadStore(true, fromType, null, code))
|
if (CodeSpan.LoadStore(true, fromType, null, dataType, code))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( (! dataType.IsReference) && cilOp == Code.Ldobj
|
if ( (! dataType.IsReference) && cilOp == Code.Ldobj
|
||||||
@ -265,14 +265,15 @@ namespace SpaceFlint.CilToJava
|
|||||||
{
|
{
|
||||||
if (data is TypeReference typeRef)
|
if (data is TypeReference typeRef)
|
||||||
{
|
{
|
||||||
|
var dataType = CilType.From(typeRef);
|
||||||
|
|
||||||
var stackTop1 = (CilType) code.StackMap.PopStack(CilMain.Where);
|
var stackTop1 = (CilType) code.StackMap.PopStack(CilMain.Where);
|
||||||
var stackTop2 = (CilType) code.StackMap.PopStack(CilMain.Where);
|
var stackTop2 = (CilType) code.StackMap.PopStack(CilMain.Where);
|
||||||
if (CodeSpan.LoadStore(false, stackTop2, null, code))
|
if (CodeSpan.LoadStore(false, stackTop2, null, dataType, code))
|
||||||
return;
|
return;
|
||||||
code.StackMap.PushStack(stackTop2);
|
code.StackMap.PushStack(stackTop2);
|
||||||
code.StackMap.PushStack(stackTop1);
|
code.StackMap.PushStack(stackTop1);
|
||||||
|
|
||||||
var dataType = CilType.From(typeRef);
|
|
||||||
GenericUtil.ValueCopy(dataType, code, true);
|
GenericUtil.ValueCopy(dataType, code, true);
|
||||||
code.StackMap.PopStack(CilMain.Where);
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
code.StackMap.PopStack(CilMain.Where);
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
@ -290,6 +291,9 @@ namespace SpaceFlint.CilToJava
|
|||||||
var dataType = CilType.From(typeRef);
|
var dataType = CilType.From(typeRef);
|
||||||
var fromType = code.StackMap.PopStack(CilMain.Where);
|
var fromType = code.StackMap.PopStack(CilMain.Where);
|
||||||
|
|
||||||
|
if (CodeSpan.Clear(fromType, dataType, code))
|
||||||
|
return;
|
||||||
|
|
||||||
if ( dataType.IsGenericParameter
|
if ( dataType.IsGenericParameter
|
||||||
|| (dataType.IsValueClass && dataType.Equals(fromType)))
|
|| (dataType.IsValueClass && dataType.Equals(fromType)))
|
||||||
{
|
{
|
||||||
|
@ -89,7 +89,10 @@ namespace SpaceFlint.CilToJava
|
|||||||
return 0x00; // nop
|
return 0x00; // nop
|
||||||
|
|
||||||
if (oldType == TypeCode.Single)
|
if (oldType == TypeCode.Single)
|
||||||
|
{
|
||||||
|
CilMain.MakeRoomForCategory2ValueOnStack(code);
|
||||||
return 0x8D; // f2d
|
return 0x8D; // f2d
|
||||||
|
}
|
||||||
|
|
||||||
if (oldType == TypeCode.Int64)
|
if (oldType == TypeCode.Int64)
|
||||||
return 0x8A; // l2d
|
return 0x8A; // l2d
|
||||||
@ -113,6 +116,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
bool fromInt32 = (oldType != TypeCode.Int64 && oldType != TypeCode.UInt64);
|
bool fromInt32 = (oldType != TypeCode.Int64 && oldType != TypeCode.UInt64);
|
||||||
if (fromInt32)
|
if (fromInt32)
|
||||||
{
|
{
|
||||||
|
CilMain.MakeRoomForCategory2ValueOnStack(code);
|
||||||
|
|
||||||
code.NewInstruction(0x85 /* i2l */, null, null);
|
code.NewInstruction(0x85 /* i2l */, null, null);
|
||||||
code.StackMap.PushStack(JavaType.LongType);
|
code.StackMap.PushStack(JavaType.LongType);
|
||||||
|
|
||||||
@ -176,6 +181,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
return 0x7F; // land
|
return 0x7F; // land
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CilMain.MakeRoomForCategory2ValueOnStack(code);
|
||||||
return 0x85; // i2l
|
return 0x85; // i2l
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +291,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
public static void Calculation(JavaCode code, Code cilOp)
|
public static void Calculation(JavaCode code, Code cilOp)
|
||||||
{
|
{
|
||||||
var stackTop1 = code.StackMap.PopStack(CilMain.Where);
|
var stackTop1 = code.StackMap.PopStack(CilMain.Where);
|
||||||
|
if (cilOp == Code.Sub && CodeSpan.SubOffset(stackTop1, code))
|
||||||
|
return;
|
||||||
var type1 = GetNumericTypeCode(stackTop1);
|
var type1 = GetNumericTypeCode(stackTop1);
|
||||||
|
|
||||||
if (cilOp == Code.Not)
|
if (cilOp == Code.Not)
|
||||||
@ -300,7 +308,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var stackTop2 = code.StackMap.PopStack(CilMain.Where);
|
var stackTop2 = code.StackMap.PopStack(CilMain.Where);
|
||||||
if (CodeSpan.AddOffset(stackTop1, stackTop2, code))
|
if (cilOp == Code.Add && CodeSpan.AddOffset(stackTop1, stackTop2, code))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char kind;
|
char kind;
|
||||||
@ -547,7 +555,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
var boxedType = stackTop as BoxedType;
|
var boxedType = stackTop as BoxedType;
|
||||||
if (boxedType == null || boxedType.IsBoxedReference != isRef)
|
if (boxedType == null || boxedType.IsBoxedReference != isRef)
|
||||||
{
|
{
|
||||||
if (CodeSpan.LoadStore(isLoad, stackTop, opcodeType, code))
|
if (CodeSpan.LoadStore(isLoad, stackTop, opcodeType, null, code))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (object.ReferenceEquals(stackTop, CodeArrays.GenericArrayType))
|
if (object.ReferenceEquals(stackTop, CodeArrays.GenericArrayType))
|
||||||
@ -590,7 +598,13 @@ namespace SpaceFlint.CilToJava
|
|||||||
code.StackMap.PushStack(unboxedType);
|
code.StackMap.PushStack(unboxedType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// if we are storing a real array into a boxed reference of
|
||||||
|
// e.g., system.Array, then we have to create an array proxy
|
||||||
|
CodeArrays.MaybeGetProxy(CodeArrays.GenericArrayType, unboxedType, code);
|
||||||
|
|
||||||
boxedType.SetValueOV(code);
|
boxedType.SetValueOV(code);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,46 @@ namespace SpaceFlint.CilToJava
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool SubOffset(JavaType secondType, JavaCode code)
|
||||||
|
{
|
||||||
|
// make sure the first operand is a pointer span, not a real Span<T>
|
||||||
|
var spanType1 = (CilType) code.StackMap.PopStack(CilMain.Where);
|
||||||
|
if ( (! spanType1.HasGenericParameters)
|
||||||
|
&& spanType1.GenericParameters != null
|
||||||
|
&& spanType1.GenericParameters[0] is CilType span1PointerType
|
||||||
|
&& (! span1PointerType.IsGenericParameter))
|
||||||
|
{
|
||||||
|
var spanType2 = (CilType) secondType;
|
||||||
|
|
||||||
|
// check if subtracting two pointer spans
|
||||||
|
if ( (! spanType2.HasGenericParameters)
|
||||||
|
&& spanType2.GenericParameters != null
|
||||||
|
&& spanType2.GenericParameters[0] is CilType span2PointerType
|
||||||
|
&& (! span2PointerType.IsGenericParameter))
|
||||||
|
{
|
||||||
|
code.NewInstruction(0xB6 /* invokevirtual */, SpanType,
|
||||||
|
new JavaMethodRef("Subtract",
|
||||||
|
JavaType.LongType, spanType2));
|
||||||
|
code.StackMap.PushStack(CilType.From(JavaType.LongType));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if subtracting an offset from a pointer span
|
||||||
|
if (spanType2.Equals(JavaType.IntegerType))
|
||||||
|
{
|
||||||
|
code.NewInstruction(0xB6 /* invokevirtual */, SpanType,
|
||||||
|
new JavaMethodRef("Subtract",
|
||||||
|
SpanType, spanType2));
|
||||||
|
code.StackMap.PushStack(SpanType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code.StackMap.PushStack(spanType1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static bool Box(CilType intoType, JavaType spanType, JavaCode code)
|
public static bool Box(CilType intoType, JavaType spanType, JavaCode code)
|
||||||
{
|
{
|
||||||
@ -122,42 +162,87 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
public static bool Address(CilType fromType, CilType intoType, JavaCode code)
|
public static bool Address(CilType fromType, CilType intoType, JavaCode code)
|
||||||
{
|
{
|
||||||
if (intoType.Equals(CodeSpan.SpanType) && (! fromType.Equals(CodeSpan.SpanType)))
|
if (intoType.Equals(SpanType) && (! fromType.Equals(SpanType)))
|
||||||
{
|
{
|
||||||
if ( fromType.Equals(JavaType.StringType)
|
// allow assignment of null to clear the pointer
|
||||||
&& intoType.GenericParameters != null
|
if (fromType.Equals(JavaStackMap.Null))
|
||||||
&& intoType.GenericParameters[0].Equals(fromType))
|
return true;
|
||||||
|
|
||||||
|
// allow assignment of native int (presumably zero)
|
||||||
|
bool callAssign = false;
|
||||||
|
bool pushNullType = true;
|
||||||
|
JavaType argType = fromType;
|
||||||
|
JavaType retType = SpanType;
|
||||||
|
|
||||||
|
if ((! fromType.IsReference) && fromType.PrimitiveType == TypeCode.UInt64)
|
||||||
|
callAssign = true;
|
||||||
|
else if (intoType.GenericParameters != null)
|
||||||
{
|
{
|
||||||
code.NewInstruction(0x01 /* aconst_null */, null, null);
|
// allow assignment when the types match
|
||||||
code.StackMap.PushStack(CilType.SystemTypeType);
|
callAssign = intoType.GenericParameters[0].Equals(fromType)
|
||||||
|
|| fromType.JavaName == intoType.GenericParameters[0].JavaName;
|
||||||
|
|
||||||
|
// for arbitrary value types, call a Assign(ValueType)
|
||||||
|
if (fromType.IsValueClass)
|
||||||
|
{
|
||||||
|
argType = retType = CilType.SystemValueType;
|
||||||
|
GenericUtil.LoadMaybeGeneric(fromType, code);
|
||||||
|
pushNullType = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callAssign)
|
||||||
|
{
|
||||||
|
if (pushNullType)
|
||||||
|
{
|
||||||
|
code.NewInstruction(0x01 /* aconst_null */, null, null);
|
||||||
|
code.StackMap.PushStack(CilType.SystemTypeType);
|
||||||
|
}
|
||||||
|
|
||||||
code.NewInstruction(0xB8 /* invokestatic */, SpanType,
|
code.NewInstruction(0xB8 /* invokestatic */, SpanType,
|
||||||
new JavaMethodRef("String" + CilMain.EXCLAMATION,
|
new JavaMethodRef("Assign" + CilMain.EXCLAMATION,
|
||||||
SpanType, JavaType.StringType, CilType.SystemTypeType));
|
retType, argType, CilType.SystemTypeType));
|
||||||
|
|
||||||
|
code.NewInstruction(0xC0 /* checkcast */, SpanType, null);
|
||||||
|
|
||||||
code.StackMap.PopStack(CilMain.Where); // null type
|
code.StackMap.PopStack(CilMain.Where); // null type
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromType.Equals(JavaStackMap.Null))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
throw new Exception($"bad assignment of '{fromType.JavaName}' into pointer");
|
throw new Exception($"bad assignment of '{fromType.JavaName}' into pointer of '{intoType.GenericParameters[0].JavaName}'");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static bool LoadStore(bool isLoad, CilType stackTop, JavaType opcodeType, JavaCode code)
|
public static bool LoadStore(bool isLoad, CilType stackTop, JavaType opcodeType,
|
||||||
|
CilType dataType, JavaCode code)
|
||||||
{
|
{
|
||||||
if (stackTop.Equals(SpanType) && code.Method.Class.Name != SpanType.ClassName)
|
if (stackTop.Equals(SpanType) && code.Method.Class.Name != SpanType.ClassName)
|
||||||
{
|
{
|
||||||
string opcodeDescr;
|
string opcodeDescr;
|
||||||
if (opcodeType == null)
|
if (opcodeType == null)
|
||||||
{
|
{
|
||||||
opcodeType = JavaType.ObjectType;
|
opcodeType = CilType.SystemValueType;
|
||||||
opcodeDescr = "";
|
opcodeDescr = "";
|
||||||
|
|
||||||
|
// at this point we should have been called from LoadObject or
|
||||||
|
// StoreObject in CodeMisc to handle a ldobj/stobj instruction,
|
||||||
|
// so make sure the pointer-span element is a value type
|
||||||
|
if (dataType.IsGenericParameter || (! dataType.IsValueClass))
|
||||||
|
throw new InvalidProgramException();
|
||||||
|
code.NewInstruction(0x12 /* ldc */, dataType.AsWritableClass, null);
|
||||||
|
|
||||||
|
// make sure the stack has room for three parameters:
|
||||||
|
// 'this', value reference (in case of Store), and class
|
||||||
|
code.StackMap.PushStack(JavaType.ObjectType);
|
||||||
|
code.StackMap.PushStack(JavaType.ObjectType);
|
||||||
|
code.StackMap.PushStack(JavaType.ObjectType);
|
||||||
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
|
code.StackMap.PopStack(CilMain.Where);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -175,6 +260,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
var spanMethod = isLoad
|
var spanMethod = isLoad
|
||||||
? (new JavaMethodRef("Load" + opcodeDescr, opcodeType))
|
? (new JavaMethodRef("Load" + opcodeDescr, opcodeType))
|
||||||
: (new JavaMethodRef("Store" + opcodeDescr, voidType, opcodeType));
|
: (new JavaMethodRef("Store" + opcodeDescr, voidType, opcodeType));
|
||||||
|
if (opcodeDescr == "")
|
||||||
|
spanMethod.Parameters.Add(new JavaFieldRef("", JavaType.ClassType));
|
||||||
code.NewInstruction(0xB6 /* invokevirtual */, SpanType, spanMethod);
|
code.NewInstruction(0xB6 /* invokevirtual */, SpanType, spanMethod);
|
||||||
if (isLoad)
|
if (isLoad)
|
||||||
code.StackMap.PushStack(CilType.From(opcodeType));
|
code.StackMap.PushStack(CilType.From(opcodeType));
|
||||||
@ -186,10 +273,26 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Compare(JavaType stackTop, JavaType stackTop2,
|
public static bool Clear(JavaType stackTop, CilType dataType, JavaCode code)
|
||||||
Mono.Cecil.Cil.Instruction cilInst, JavaCode code)
|
|
||||||
{
|
{
|
||||||
if ( stackTop.Equals(CodeSpan.SpanType)
|
if ( stackTop.Equals(SpanType)
|
||||||
|
&& dataType.IsValueClass
|
||||||
|
&& code.Method.Class.Name != SpanType.ClassName)
|
||||||
|
{
|
||||||
|
// if initobj is called on a span or pointer, call Span<T>.Clear()
|
||||||
|
code.NewInstruction(0xB6 /* invokevirtual */, SpanType,
|
||||||
|
new JavaMethodRef("Clear", JavaType.VoidType));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void CompareEq(JavaType stackTop, JavaType stackTop2,
|
||||||
|
Mono.Cecil.Cil.Instruction cilInst, JavaCode code)
|
||||||
|
{
|
||||||
|
if ( stackTop.Equals(SpanType)
|
||||||
&& ( stackTop2.PrimitiveType == TypeCode.Int64
|
&& ( stackTop2.PrimitiveType == TypeCode.Int64
|
||||||
|| stackTop2.PrimitiveType == TypeCode.UInt64))
|
|| stackTop2.PrimitiveType == TypeCode.UInt64))
|
||||||
{
|
{
|
||||||
@ -197,7 +300,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
throw new InvalidProgramException();
|
throw new InvalidProgramException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stackTop2.Equals(CodeSpan.SpanType)
|
if ( stackTop2.Equals(SpanType)
|
||||||
&& ( stackTop.PrimitiveType == TypeCode.Int64
|
&& ( stackTop.PrimitiveType == TypeCode.Int64
|
||||||
|| stackTop.PrimitiveType == TypeCode.UInt64))
|
|| stackTop.PrimitiveType == TypeCode.UInt64))
|
||||||
{
|
{
|
||||||
@ -222,6 +325,26 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static bool CompareGtLt(JavaType stackTop, JavaType stackTop2, JavaCode code)
|
||||||
|
{
|
||||||
|
if (stackTop.Equals(SpanType) && stackTop2.Equals(SpanType))
|
||||||
|
{
|
||||||
|
code.NewInstruction(0x01 /* aconst_null */, null, null);
|
||||||
|
code.StackMap.PushStack(CilType.SystemTypeType);
|
||||||
|
|
||||||
|
code.NewInstruction(0xB8 /* invokestatic */, SpanType,
|
||||||
|
new JavaMethodRef("CompareTo" + CilMain.EXCLAMATION,
|
||||||
|
JavaType.IntegerType, SpanType, SpanType, CilType.SystemTypeType));
|
||||||
|
|
||||||
|
code.StackMap.PopStack(CilMain.Where); // null type
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal static readonly CilType SpanType =
|
internal static readonly CilType SpanType =
|
||||||
CilType.From(new JavaType(0, 0, "system.Span$$1"));
|
CilType.From(new JavaType(0, 0, "system.Span$$1"));
|
||||||
}
|
}
|
||||||
|
@ -322,6 +322,8 @@ namespace SpaceFlint.CilToJava
|
|||||||
|
|
||||||
if (! (fromType.IsInterface || fromType.IsDelegate))
|
if (! (fromType.IsInterface || fromType.IsDelegate))
|
||||||
return;
|
return;
|
||||||
|
string varianceString = null;
|
||||||
|
|
||||||
bool anyVariance = false;
|
bool anyVariance = false;
|
||||||
foreach (var gp in defType.GenericParameters)
|
foreach (var gp in defType.GenericParameters)
|
||||||
{
|
{
|
||||||
@ -332,18 +334,31 @@ namespace SpaceFlint.CilToJava
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! anyVariance)
|
if (! anyVariance)
|
||||||
return;
|
{
|
||||||
|
if (fromType.JavaName == "system.collections.generic.IComparer$$1")
|
||||||
|
{
|
||||||
|
// force a variance string for an interface that we create
|
||||||
|
// as an abstract class; see also IComparer.cs in baselib
|
||||||
|
varianceString = "I";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// build a string that describes the generic variance
|
// build a string that describes the generic variance
|
||||||
|
|
||||||
var chars = new char[defType.GenericParameters.Count];
|
if (varianceString == null)
|
||||||
int idx = 0;
|
|
||||||
foreach (var gp in defType.GenericParameters)
|
|
||||||
{
|
{
|
||||||
var v = gp.Attributes & GenericParameterAttributes.VarianceMask;
|
var chars = new char[defType.GenericParameters.Count];
|
||||||
chars[idx++] = (v == GenericParameterAttributes.Covariant) ? 'O'
|
int idx = 0;
|
||||||
: (v == GenericParameterAttributes.Contravariant) ? 'I'
|
foreach (var gp in defType.GenericParameters)
|
||||||
: ' ';
|
{
|
||||||
|
var v = gp.Attributes & GenericParameterAttributes.VarianceMask;
|
||||||
|
chars[idx++] = (v == GenericParameterAttributes.Covariant) ? 'O'
|
||||||
|
: (v == GenericParameterAttributes.Contravariant) ? 'I'
|
||||||
|
: ' ';
|
||||||
|
}
|
||||||
|
varianceString = new string(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
var varianceField = new JavaField();
|
var varianceField = new JavaField();
|
||||||
@ -354,7 +369,7 @@ namespace SpaceFlint.CilToJava
|
|||||||
| JavaAccessFlags.ACC_PUBLIC
|
| JavaAccessFlags.ACC_PUBLIC
|
||||||
| JavaAccessFlags.ACC_TRANSIENT
|
| JavaAccessFlags.ACC_TRANSIENT
|
||||||
| JavaAccessFlags.ACC_SYNTHETIC;
|
| JavaAccessFlags.ACC_SYNTHETIC;
|
||||||
varianceField.Constant = new string(chars);
|
varianceField.Constant = varianceString;
|
||||||
varianceField.Class = theClass;
|
varianceField.Class = theClass;
|
||||||
|
|
||||||
if (theClass.Fields == null)
|
if (theClass.Fields == null)
|
||||||
|
@ -11,7 +11,8 @@ namespace Tests
|
|||||||
{
|
{
|
||||||
Test1();
|
Test1();
|
||||||
Test2("Hello, world");
|
Test2("Hello, world");
|
||||||
//Test3(default(Guid));
|
Test3(default(Guid));
|
||||||
|
Test4(default(AAA));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe void Test1()
|
unsafe void Test1()
|
||||||
@ -59,12 +60,21 @@ namespace Tests
|
|||||||
Console.WriteLine(from + " -> " + new String(into) + "~~~");
|
Console.WriteLine(from + " -> " + new String(into) + "~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*unsafe void Test3(Guid from)
|
unsafe void Test3(Guid from)
|
||||||
{
|
{
|
||||||
Guid *pFrom = &from;
|
Guid *pFrom = &from;
|
||||||
*pFrom = new Guid("00000001-0000-0000-0000-000000000000");
|
*pFrom = new Guid("00000001-0000-0000-0000-000000000000");
|
||||||
Console.WriteLine(from);
|
Console.WriteLine(from);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
struct AAA {}
|
||||||
|
|
||||||
|
unsafe void Test4(AAA from)
|
||||||
|
{
|
||||||
|
AAA *pFrom = &from;
|
||||||
|
*pFrom = new AAA();
|
||||||
|
Console.WriteLine(from);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace Tests
|
|||||||
// Enum
|
// Enum
|
||||||
//
|
//
|
||||||
|
|
||||||
[Flags] enum MyEnum : sbyte { None, First = 1, Second = 8, Third = 32 };
|
[Flags] enum MyEnum : short { None, First = 1, Second = 8, Third = 32 };
|
||||||
|
|
||||||
void TestEnum()
|
void TestEnum()
|
||||||
{
|
{
|
||||||
@ -92,6 +92,14 @@ namespace Tests
|
|||||||
Console.Write("\t");
|
Console.Write("\t");
|
||||||
Console.Write(y);
|
Console.Write(y);
|
||||||
Console.Write($"\t{x:F},{x:G},{x:D},{x:X},{x.GetType().GetEnumUnderlyingType()}");
|
Console.Write($"\t{x:F},{x:G},{x:D},{x:X},{x.GetType().GetEnumUnderlyingType()}");
|
||||||
|
Console.Write($"\t{((IConvertible) x).ToType(typeof(long), null)}");
|
||||||
|
Console.Write($"\t{x.HasFlag(MyEnum.Third)}");
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
var names = typeof(MyEnum).GetEnumNames();
|
||||||
|
var values = typeof(MyEnum).GetEnumValues();
|
||||||
|
for (int i = 0; i < names.Length; i++)
|
||||||
|
Console.Write($"\t{names[i]} = {(short) values.GetValue(i)}");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
void TestEnum2<T>(ref T e)
|
void TestEnum2<T>(ref T e)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user