Some changes for BNA
This commit is contained in:
parent
01a98c2f3f
commit
d3426fc442
@ -142,14 +142,18 @@ System.Runtime.Serialization.StreamingContext
|
||||
System.Runtime.Serialization.SerializationException
|
||||
|
||||
System.IO.BinaryReader
|
||||
System.IO.BinaryWriter
|
||||
System.IO.DirectoryNotFoundException
|
||||
System.IO.EndOfStreamException
|
||||
System.IO.FileAccess
|
||||
System.IO.FileAttributes
|
||||
System.IO.FileMode
|
||||
System.IO.FileNotFoundException
|
||||
System.IO.FileShare
|
||||
System.IO.MemoryStream
|
||||
System.IO.TextReader
|
||||
System.IO.TextWriter
|
||||
System.IO.SeekOrigin
|
||||
System.IO.StringReader
|
||||
System.IO.Stream
|
||||
System.IO.StreamReader
|
||||
|
149
Baselib/src/System/BitConverter.cs
Normal file
149
Baselib/src/System/BitConverter.cs
Normal file
@ -0,0 +1,149 @@
|
||||
|
||||
namespace system
|
||||
{
|
||||
|
||||
public static class BitConverter
|
||||
{
|
||||
|
||||
[java.attr.RetainType] private static readonly bool _IsLittleEndian =
|
||||
java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN;
|
||||
public static readonly bool IsLittleEndian = _IsLittleEndian;
|
||||
|
||||
public static int SingleToInt32Bits(float value) => java.lang.Float.floatToRawIntBits(value);
|
||||
public static float Int32BitsToSingle(int value) => java.lang.Float.intBitsToFloat(value);
|
||||
|
||||
public static long DoubleToInt64Bits(double value) => java.lang.Double.doubleToRawLongBits(value);
|
||||
public static double Int64BitsToDouble(long value) => java.lang.Double.longBitsToDouble(value);
|
||||
|
||||
public static byte[] GetBytes(bool value) => new byte[] { value ? (byte) 1 : (byte) 0 };
|
||||
public static byte[] GetBytes(short value)
|
||||
=> (byte[]) (object) java.util.Arrays.copyOf(
|
||||
GetByteBuffer(2).putShort(0, value).array(), 2);
|
||||
public static byte[] GetBytes(ushort value) => GetBytes((short) value);
|
||||
public static byte[] GetBytes(char value) => GetBytes((short) value);
|
||||
public static byte[] GetBytes(int value)
|
||||
=> (byte[]) (object) java.util.Arrays.copyOf(
|
||||
GetByteBuffer(4).putInt(0, value).array(), 4);
|
||||
public static byte[] GetBytes(uint value) => GetBytes((int) value);
|
||||
public static byte[] GetBytes(long value)
|
||||
=> (byte[]) (object) java.util.Arrays.copyOf(
|
||||
GetByteBuffer(8).putLong(0, value).array(), 8);
|
||||
public static byte[] GetBytes(ulong value) => GetBytes((long) value);
|
||||
public static byte[] GetBytes(float value)
|
||||
=> (byte[]) (object) java.util.Arrays.copyOf(
|
||||
GetByteBuffer(4).putFloat(0, value).array(), 4);
|
||||
public static byte[] GetBytes(double value)
|
||||
=> (byte[]) (object) java.util.Arrays.copyOf(
|
||||
GetByteBuffer(8).putDouble(0, value).array(), 8);
|
||||
|
||||
public static short ToInt16(byte[] value, int startIndex)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(value);
|
||||
if ((uint) startIndex >= value.Length || startIndex > value.Length - 2)
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
byte b0 = value[startIndex];
|
||||
byte b1 = value[++startIndex];
|
||||
if (! _IsLittleEndian)
|
||||
(b0, b1) = (b1, b0);
|
||||
return (short) (b0 | (b1 << 8));
|
||||
}
|
||||
public static ushort ToUInt16(byte[] value, int startIndex)
|
||||
=> (ushort) ToInt16(value, startIndex);
|
||||
public static char ToChar(byte[] value, int startIndex)
|
||||
=> (char) ToInt16(value, startIndex);
|
||||
|
||||
public static int ToInt32(byte[] value, int startIndex)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(value);
|
||||
if ((uint) startIndex >= value.Length || startIndex > value.Length - 4)
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
byte b0 = value[startIndex];
|
||||
byte b1 = value[++startIndex];
|
||||
byte b2 = value[++startIndex];
|
||||
byte b3 = value[++startIndex];
|
||||
if (! _IsLittleEndian)
|
||||
(b0, b1, b2, b3) = (b3, b2, b1, b0);
|
||||
return (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
|
||||
}
|
||||
public static uint ToUInt32(byte[] value, int startIndex)
|
||||
=> (uint) ToInt32(value, startIndex);
|
||||
public static float ToSingle(byte[] value, int startIndex)
|
||||
=> java.lang.Float.intBitsToFloat(ToInt32(value, startIndex));
|
||||
|
||||
public static long ToInt64(byte[] value, int startIndex)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(value);
|
||||
if ((uint) startIndex >= value.Length || startIndex > value.Length - 8)
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
byte b0 = value[startIndex];
|
||||
byte b1 = value[++startIndex];
|
||||
byte b2 = value[++startIndex];
|
||||
byte b3 = value[++startIndex];
|
||||
byte b4 = value[++startIndex];
|
||||
byte b5 = value[++startIndex];
|
||||
byte b6 = value[++startIndex];
|
||||
byte b7 = value[++startIndex];
|
||||
if (! _IsLittleEndian)
|
||||
(b0, b1, b2, b3, b4, b5, b6, b7) = (b7, b6, b5, b4, b3, b2, b1, b0);
|
||||
int i1 = (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
|
||||
int i2 = (b4 | (b5 << 8) | (b6 << 16) | (b7 << 24));
|
||||
return (uint) i1 | ((long) i2 << 32);
|
||||
}
|
||||
public static ulong ToUInt64(byte[] value, int startIndex)
|
||||
=> (ulong) ToInt64(value, startIndex);
|
||||
public static double ToDouble(byte[] value, int startIndex)
|
||||
=> java.lang.Double.longBitsToDouble(ToInt64(value, startIndex));
|
||||
|
||||
public static bool ToBoolean(byte[] value, int startIndex)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(value);
|
||||
if (startIndex < 0 || startIndex > value.Length - 1)
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
return (value[startIndex] != 0);
|
||||
}
|
||||
|
||||
public static string ToString(byte[] value, int startIndex, int length)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(value);
|
||||
int valueLength = value.Length;
|
||||
if ( startIndex < 0 || length < 0
|
||||
|| (startIndex >= valueLength && startIndex > 0)
|
||||
|| (startIndex > valueLength - length))
|
||||
{
|
||||
ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
if (length == 0)
|
||||
return "";
|
||||
|
||||
var output = new char[valueLength * 2];
|
||||
int outputIndex = 0;
|
||||
while (valueLength --> 0)
|
||||
{
|
||||
byte v = value[startIndex++];
|
||||
output[outputIndex++] = HexChars[v >> 4];
|
||||
output[outputIndex++] = HexChars[v & 0x0F];
|
||||
}
|
||||
return new string(output);
|
||||
}
|
||||
|
||||
private static java.nio.ByteBuffer GetByteBuffer(int len)
|
||||
{
|
||||
var buffer = (java.nio.ByteBuffer) TlsByteBuffer.get();
|
||||
if (buffer == null || buffer.limit() < len)
|
||||
{
|
||||
buffer = java.nio.ByteBuffer.allocate(len)
|
||||
.order(java.nio.ByteOrder.nativeOrder());
|
||||
TlsByteBuffer.set(buffer);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
[java.attr.RetainType] static java.lang.ThreadLocal TlsByteBuffer =
|
||||
new java.lang.ThreadLocal();
|
||||
|
||||
[java.attr.RetainType] private static readonly char[] HexChars =
|
||||
"0123456789ABCDEF".ToCharArray();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -8,6 +8,13 @@ namespace system
|
||||
public static void InternalBlockCopy(Array src, int srcOffsetBytes,
|
||||
Array dst, int dstOffsetBytes, int byteCount)
|
||||
{
|
||||
if (src.SyncRoot is sbyte[] srcBytes && dst.SyncRoot is sbyte[] dstBytes)
|
||||
{
|
||||
java.lang.System.arraycopy(srcBytes, srcOffsetBytes,
|
||||
dstBytes, dstOffsetBytes, byteCount);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.SyncRoot is char[] srcChars && dst.SyncRoot is char[] dstChars)
|
||||
{
|
||||
int srcIndex = srcOffsetBytes >> 1;
|
||||
@ -21,6 +28,7 @@ namespace system
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new System.PlatformNotSupportedException(
|
||||
"InternalBlockCopy/" + src.GetType() + "/" + dst.GetType());
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ namespace system
|
||||
// ToString
|
||||
//
|
||||
|
||||
public override string ToString() => JavaCalendar.ToString();
|
||||
public override string ToString() => ToString(null, null);
|
||||
|
||||
public string ToString(IFormatProvider provider) => ToString(null, provider);
|
||||
|
||||
@ -207,6 +207,23 @@ namespace system
|
||||
public static bool operator >= (DateTime d1, DateTime d2)
|
||||
=> d1.Ticks >= d2.Ticks;
|
||||
|
||||
//
|
||||
// SpecifyKind, ToUniversalTime, ToLocalTime
|
||||
//
|
||||
|
||||
public static DateTime SpecifyKind(DateTime value, DateTimeKind kind)
|
||||
{
|
||||
var javaCalendar = java.util.Calendar.getInstance();
|
||||
if (kind == DateTimeKind.Utc)
|
||||
javaCalendar.setTimeZone(TimeZoneUTC);
|
||||
javaCalendar.setTimeInMillis(value.JavaCalendar.getTimeInMillis());
|
||||
return new DateTime(javaCalendar, kind);
|
||||
}
|
||||
|
||||
public DateTime ToUniversalTime() => SpecifyKind(this, DateTimeKind.Utc);
|
||||
|
||||
public DateTime ToLocalTime() => SpecifyKind(this, DateTimeKind.Local);
|
||||
|
||||
//
|
||||
// ISerializable
|
||||
//
|
||||
|
@ -157,6 +157,29 @@ namespace system
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CodeNumber.Indirection methods
|
||||
//
|
||||
|
||||
public int Get_U8() => throw new System.NotSupportedException();
|
||||
public int Get_I8() => throw new System.NotSupportedException();
|
||||
public void Set_I8(int v) => throw new System.NotSupportedException();
|
||||
|
||||
public int Get_U16() => throw new System.NotSupportedException();
|
||||
public int Get_I16() => throw new System.NotSupportedException();
|
||||
public void Set_I16(int v) => throw new System.NotSupportedException();
|
||||
|
||||
public int Get_I32() => throw new System.NotSupportedException();
|
||||
public void Set_I32(int v) => throw new System.NotSupportedException();
|
||||
|
||||
public long Get_I64() => java.lang.Double.doubleToRawLongBits(v);
|
||||
public void Set_I64(long v) => Set(java.lang.Double.longBitsToDouble(v));
|
||||
|
||||
public double Get_F64() => throw new System.NotSupportedException();
|
||||
public void Set_F64(double v) => throw new System.NotSupportedException();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// IConvertible
|
||||
//
|
||||
|
32
Baselib/src/System/IO/Directory.cs
Normal file
32
Baselib/src/System/IO/Directory.cs
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
namespace system.io
|
||||
{
|
||||
|
||||
public static class Directory
|
||||
{
|
||||
|
||||
public static bool Exists(string path)
|
||||
{
|
||||
bool exists = false;
|
||||
if (path != null && path.Length != 0)
|
||||
{
|
||||
var file = new java.io.File(path);
|
||||
exists = file.exists() && file.isDirectory();
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
public static DirectoryInfo CreateDirectory(string path)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(path);
|
||||
path = path.Trim();
|
||||
if (path.Length == 0)
|
||||
throw new System.ArgumentException();
|
||||
var file = new java.io.File(path);
|
||||
file.mkdirs();
|
||||
return new DirectoryInfo(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
12
Baselib/src/System/IO/DirectoryInfo.cs
Normal file
12
Baselib/src/System/IO/DirectoryInfo.cs
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
namespace system.io
|
||||
{
|
||||
|
||||
public sealed class DirectoryInfo : FileSystemInfo
|
||||
{
|
||||
|
||||
public DirectoryInfo(java.io.File javaFile) : base(javaFile) { }
|
||||
|
||||
}
|
||||
|
||||
}
|
22
Baselib/src/System/IO/File.cs
Normal file
22
Baselib/src/System/IO/File.cs
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
using FileMode = System.IO.FileMode;
|
||||
using FileAccess = System.IO.FileAccess;
|
||||
using FileShare = System.IO.FileShare;
|
||||
|
||||
namespace system.io
|
||||
{
|
||||
|
||||
public static class File
|
||||
{
|
||||
|
||||
public static FileStream Open(string path, FileMode mode)
|
||||
=> new FileStream(path, mode);
|
||||
|
||||
public static FileStream Open(string path, FileMode mode, FileAccess access)
|
||||
=> new FileStream(path, mode, access);
|
||||
|
||||
public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
|
||||
=> new FileStream(path, mode, access);
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,9 @@ namespace system.io
|
||||
: this(path, mode, (mode == System.IO.FileMode.Append
|
||||
? System.IO.FileAccess.Write : System.IO.FileAccess.ReadWrite)) { }
|
||||
|
||||
public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share)
|
||||
: this(path, mode, access) { }
|
||||
|
||||
public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(path);
|
||||
@ -131,8 +134,7 @@ namespace system.io
|
||||
public override bool CanWrite => (Flags & CAN_WRITE) != 0;
|
||||
public override bool CanSeek => (Flags & CAN_SEEK) != 0;
|
||||
|
||||
public override long Length
|
||||
=> throw new System.PlatformNotSupportedException();
|
||||
public override long Length => JavaChannel.size();
|
||||
|
||||
public override long Position
|
||||
{
|
||||
@ -184,10 +186,23 @@ namespace system.io
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
=> throw new System.PlatformNotSupportedException();
|
||||
{
|
||||
if (value < 0)
|
||||
throw new System.ArgumentOutOfRangeException();
|
||||
JavaChannel.truncate(value);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||
=> throw new System.PlatformNotSupportedException();
|
||||
{
|
||||
if (origin == System.IO.SeekOrigin.Current)
|
||||
offset += JavaChannel.position();
|
||||
else if (origin == System.IO.SeekOrigin.End)
|
||||
offset = JavaChannel.size() - offset;
|
||||
else if (origin != System.IO.SeekOrigin.Begin)
|
||||
throw new System.ArgumentException();
|
||||
JavaChannel.position(offset);
|
||||
return JavaChannel.position();
|
||||
}
|
||||
|
||||
//
|
||||
// static constructor
|
||||
@ -199,6 +214,17 @@ namespace system.io
|
||||
(java.lang.Class) typeof(java.io.FileNotFoundException),
|
||||
(exc) => new System.IO.FileNotFoundException(exc.getMessage())
|
||||
);
|
||||
|
||||
system.Util.DefineException(
|
||||
(java.lang.Class) typeof(java.nio.channels.NonWritableChannelException),
|
||||
(exc) => new System.NotSupportedException(exc.getMessage())
|
||||
);
|
||||
|
||||
system.Util.DefineException(
|
||||
(java.lang.Class) typeof(java.nio.channels.ClosedChannelException),
|
||||
(exc) => new System.ObjectDisposedException(exc.getMessage())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
101
Baselib/src/System/IO/FileSystemInfo.cs
Normal file
101
Baselib/src/System/IO/FileSystemInfo.cs
Normal file
@ -0,0 +1,101 @@
|
||||
|
||||
using FileAttributes = System.IO.FileAttributes;
|
||||
|
||||
namespace system.io
|
||||
{
|
||||
|
||||
public abstract class FileSystemInfo
|
||||
{
|
||||
[java.attr.RetainType] protected java.io.File JavaFile;
|
||||
|
||||
protected FileSystemInfo(java.io.File javaFile)
|
||||
{
|
||||
JavaFile = javaFile;
|
||||
}
|
||||
|
||||
public virtual string FullName => JavaFile.getAbsolutePath();
|
||||
|
||||
public virtual string Name => JavaFile.getName();
|
||||
|
||||
public string Extension
|
||||
{
|
||||
get
|
||||
{
|
||||
var name = Name;
|
||||
int dot = Name.LastIndexOf('.');
|
||||
if (dot != -1)
|
||||
{
|
||||
int slash = Name.LastIndexOf('/');
|
||||
if (dot > slash)
|
||||
{
|
||||
return ((java.lang.String) (object) name).substring(dot);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public FileAttributes Attributes
|
||||
{
|
||||
get
|
||||
{
|
||||
FileAttributes attr = (FileAttributes) 0;
|
||||
if (JavaFile.isDirectory())
|
||||
attr |= FileAttributes.Directory;
|
||||
if (JavaFile.isHidden())
|
||||
attr |= FileAttributes.Hidden;
|
||||
if (! JavaFile.canWrite())
|
||||
attr |= FileAttributes.ReadOnly;
|
||||
if (attr == (FileAttributes) 0)
|
||||
attr = FileAttributes.Normal;
|
||||
return attr;
|
||||
}
|
||||
set => throw new System.PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
public virtual void Delete() => JavaFile.delete();
|
||||
|
||||
public virtual bool Exists => JavaFile.exists();
|
||||
|
||||
public DateTime CreationTimeUtc
|
||||
{
|
||||
get => throw new System.PlatformNotSupportedException();
|
||||
set => throw new System.PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
public DateTime LastAccessTimeUtc
|
||||
{
|
||||
get => throw new System.PlatformNotSupportedException();
|
||||
set => throw new System.PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
public DateTime LastWriteTimeUtc
|
||||
{
|
||||
// 10,000 DateTime ticks in a millisecond
|
||||
get => new DateTime(JavaFile.lastModified() * 10000);
|
||||
set => JavaFile.setLastModified(value.Ticks / 10000);
|
||||
}
|
||||
|
||||
public DateTime CreationTime
|
||||
{
|
||||
get => CreationTimeUtc.ToLocalTime();
|
||||
set => CreationTimeUtc = value.ToUniversalTime();
|
||||
}
|
||||
|
||||
public DateTime LastAccessTime
|
||||
{
|
||||
get => LastAccessTimeUtc.ToLocalTime();
|
||||
set => LastAccessTimeUtc = value.ToUniversalTime();
|
||||
}
|
||||
|
||||
public DateTime LastWriteTime
|
||||
{
|
||||
get => LastWriteTimeUtc.ToLocalTime();
|
||||
set => LastWriteTimeUtc = value.ToUniversalTime();
|
||||
}
|
||||
|
||||
public void Refresh() { }
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ namespace system.io
|
||||
|
||||
public static bool IsPathRooted(string path) => false;
|
||||
|
||||
public static string Combine (string path1, string path2)
|
||||
public static string Combine(string path1, string path2)
|
||||
{
|
||||
path1 = CheckPath(path1);
|
||||
path2 = CheckPath(path2);
|
||||
@ -26,6 +26,12 @@ namespace system.io
|
||||
return (ch != '/') ? (path1 + "/" + path2) : (path1 + path2);
|
||||
}
|
||||
|
||||
public static string Combine(string path1, string path2, string path3)
|
||||
=> Combine(Combine(path1, path2), path3);
|
||||
}
|
||||
|
||||
public static class PathInternal
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -122,6 +122,29 @@ namespace system
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CodeNumber.Indirection methods
|
||||
//
|
||||
|
||||
public int Get_U8() => throw new System.NotSupportedException();
|
||||
public int Get_I8() => throw new System.NotSupportedException();
|
||||
public void Set_I8(int v) => throw new System.NotSupportedException();
|
||||
|
||||
public int Get_U16() => throw new System.NotSupportedException();
|
||||
public int Get_I16() => throw new System.NotSupportedException();
|
||||
public void Set_I16(int v) => throw new System.NotSupportedException();
|
||||
|
||||
public int Get_I32() => java.lang.Float.floatToRawIntBits(v);
|
||||
public void Set_I32(int v) => Set(java.lang.Float.intBitsToFloat(v));
|
||||
|
||||
public long Get_I64() => throw new System.NotSupportedException();
|
||||
public void Set_I64(long v) => throw new System.NotSupportedException();
|
||||
|
||||
public double Get_F64() => throw new System.NotSupportedException();
|
||||
public void Set_F64(double v) => throw new System.NotSupportedException();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// IConvertible
|
||||
//
|
||||
|
@ -255,6 +255,13 @@ namespace system.text
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public virtual int GetBytes(string s, int charIndex, int charCount,
|
||||
byte[] bytes, int byteIndex)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(s);
|
||||
return GetBytes(s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
|
||||
}
|
||||
|
||||
public virtual string GetString(byte[] bytes)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(bytes);
|
||||
|
@ -561,10 +561,10 @@ namespace SpaceFlint.CilToJava
|
||||
// if we detect such a conflict at a branch target, we assume this
|
||||
// is the cause, and set the stack elements to a common denominator
|
||||
// or to the lowest common denominator, java.lang.Object
|
||||
if ( IsReference && other.IsReference && other is CilType other2
|
||||
&& (! this.IsValueClass) && (! other2.IsValueClass))
|
||||
if (IsReference && other.IsReference && other is CilType other2)
|
||||
{
|
||||
return FindCommonSuperType(this, other2) ?? CilType.From(JavaType.ObjectType);
|
||||
return FindCommonSuperType(this, other2)
|
||||
?? CilType.From(JavaType.ObjectType);
|
||||
}
|
||||
return null;
|
||||
|
||||
|
@ -330,7 +330,7 @@ namespace SpaceFlint.CilToJava
|
||||
|
||||
|
||||
|
||||
public void Store(Code op)
|
||||
public void Store(Code op, Mono.Cecil.Cil.Instruction inst)
|
||||
{
|
||||
TypeCode elemType;
|
||||
|
||||
@ -338,7 +338,7 @@ namespace SpaceFlint.CilToJava
|
||||
{
|
||||
case Code.Stelem_Ref: case Code.Stelem_Any:
|
||||
|
||||
Store(null);
|
||||
Store(null, null);
|
||||
return;
|
||||
|
||||
case Code.Stelem_I1: elemType = TypeCode.Byte; break;
|
||||
@ -351,12 +351,12 @@ namespace SpaceFlint.CilToJava
|
||||
default: throw new InvalidProgramException();
|
||||
}
|
||||
|
||||
Store(CilType.From(new JavaType(elemType, 0, null)));
|
||||
Store(CilType.From(new JavaType(elemType, 0, null)), inst);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Store(CilType elemType)
|
||||
void Store(CilType elemType, Mono.Cecil.Cil.Instruction inst)
|
||||
{
|
||||
stackMap.PopStack(CilMain.Where); // value
|
||||
stackMap.PopStack(CilMain.Where); // index
|
||||
@ -406,6 +406,8 @@ namespace SpaceFlint.CilToJava
|
||||
elemType = arrayType.AdjustRank(-arrayType.ArrayRank);
|
||||
}
|
||||
|
||||
CheckImmediate(arrayType.PrimitiveType, inst);
|
||||
|
||||
if (arrayType.IsValueClass || elemType.IsValueClass)
|
||||
{
|
||||
CilMethod.ValueMethod(CilMethod.ValueClone, code);
|
||||
@ -413,6 +415,32 @@ namespace SpaceFlint.CilToJava
|
||||
|
||||
code.NewInstruction(elemType.StoreArrayOpcode, null, null);
|
||||
}
|
||||
|
||||
|
||||
void CheckImmediate(TypeCode arrayPrimitiveType, Mono.Cecil.Cil.Instruction inst)
|
||||
{
|
||||
// Android AOT aborts the compilation with a crash if storing
|
||||
// an immediate value that does not fit in the target array.
|
||||
if ( inst != null && inst.Previous != null
|
||||
&& inst.Previous.OpCode.Code == Code.Ldc_I4)
|
||||
{
|
||||
var imm = (int) inst.Previous.Operand;
|
||||
if ( arrayType.PrimitiveType == TypeCode.Boolean
|
||||
|| arrayType.PrimitiveType == TypeCode.SByte
|
||||
|| arrayType.PrimitiveType == TypeCode.Byte)
|
||||
{
|
||||
if (imm < -128 || imm >= 128)
|
||||
code.NewInstruction(0x91 /* i2b */, null, null);
|
||||
}
|
||||
else if ( arrayType.PrimitiveType == TypeCode.Char
|
||||
|| arrayType.PrimitiveType == TypeCode.Int16
|
||||
|| arrayType.PrimitiveType == TypeCode.UInt16)
|
||||
{
|
||||
if (imm < -32768 || imm >= 32768)
|
||||
code.NewInstruction(0x93 /* i2s */, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -505,7 +533,7 @@ namespace SpaceFlint.CilToJava
|
||||
stackMap.PushStack(valueType);
|
||||
}
|
||||
|
||||
Store(elemType);
|
||||
Store(elemType, null);
|
||||
}
|
||||
|
||||
else if (method.Name == "Address")
|
||||
|
@ -418,7 +418,7 @@ namespace SpaceFlint.CilToJava
|
||||
case Code.Stelem_I: case Code.Stelem_R4:case Code.Stelem_R8:case Code.Stelem_Any:
|
||||
case Code.Stelem_Ref:
|
||||
|
||||
arrays.Store(cilOp);
|
||||
arrays.Store(cilOp, cilInst);
|
||||
break;
|
||||
|
||||
case Code.Ldftn: case Code.Ldvirtftn:
|
||||
|
@ -121,7 +121,18 @@ namespace SpaceFlint.CilToJava
|
||||
else if (dstType.IsReference)
|
||||
{
|
||||
CodeArrays.CheckCast(dstType, true, code);
|
||||
if (dstType.IsGenericParameter)
|
||||
|
||||
if ( srcType.ArrayRank != 0
|
||||
&& srcType.ArrayRank == dstType.ArrayRank
|
||||
&& srcType.PrimitiveType != 0
|
||||
&& dstType.PrimitiveType != 0
|
||||
&& srcType.AdjustRank(-srcType.ArrayRank).NewArrayType
|
||||
== dstType.AdjustRank(-dstType.ArrayRank).NewArrayType)
|
||||
{
|
||||
// casting to same java array type, e.g. byte[] to sbyte[]
|
||||
op = 0x00; // nop
|
||||
}
|
||||
else if (dstType.IsGenericParameter)
|
||||
op = 0x00; // nop
|
||||
else
|
||||
op = 0xC0; // checkcast
|
||||
|
@ -58,6 +58,8 @@ There are some additional demos:
|
||||
- Note that the Android demos require the `ANDROID_HOME` environment directory, and the project is hard-coded to use Android platform version 28, and build-tools 30.0.2
|
||||
- Note also that the Android demos build an APK file, but do not install it.
|
||||
|
||||
See the [BNA](https://github.com/spaceflint7/bna) repository for another demo for Android.
|
||||
|
||||
## Usage
|
||||
|
||||
For more information about using Bluebonnet, please see the [USAGE.md](USAGE.md) file. That document also records any known differences and deficiencies, compared to a proper .NET implementation.
|
Loading…
x
Reference in New Issue
Block a user