diff --git a/.gitignore b/.gitignore index 30a6fc18..8bba145f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ bin obj +Debug +Release *.suo *.user *.nupkg diff --git a/src/DNA/corlib/System.Collections.Generic/Comparer.cs b/src/DNA/corlib/System.Collections.Generic/Comparer.cs index c46cf680..6d403872 100644 --- a/src/DNA/corlib/System.Collections.Generic/Comparer.cs +++ b/src/DNA/corlib/System.Collections.Generic/Comparer.cs @@ -24,7 +24,7 @@ using System.Collections; namespace System.Collections.Generic { - public abstract class Comparer : IComparer,IComparer { + public abstract class Comparer : IComparer, IComparer { private sealed class DefaultComparer : Comparer { @@ -45,7 +45,6 @@ public override int Compare(T x, T y) { } throw new ArgumentException("Does not implement IComparable"); } - } private sealed class DefaultComparerValueType : Comparer { @@ -61,7 +60,21 @@ public override int Compare(T x, T y) { } throw new ArgumentException("Does not implement IComparable"); } + } + + private sealed class ComparisonComparer : Comparer { + private readonly Comparison comparison; + public ComparisonComparer(Comparison comparison) { + this.comparison = comparison; + } + public override int Compare(T x, T y) { + return comparison(x, y); + } + } + public static Comparer Create(Comparison comparison) { + if (comparison == null) throw new ArgumentNullException("comparison"); + return new ComparisonComparer(comparison); } static Comparer() { diff --git a/src/DNA/corlib/System.Collections.Generic/IReadOnlyCollection.cs b/src/DNA/corlib/System.Collections.Generic/IReadOnlyCollection.cs new file mode 100644 index 00000000..83cda666 --- /dev/null +++ b/src/DNA/corlib/System.Collections.Generic/IReadOnlyCollection.cs @@ -0,0 +1,33 @@ +// +// IReadOnlyCollection.cs +// +// Authors: +// Marek Safar +// +// Copyright (C) 2012 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace System.Collections.Generic { + public interface IReadOnlyCollection : IEnumerable { + int Count { get; } + } +} diff --git a/src/DNA/corlib/System.Collections.Generic/List.cs b/src/DNA/corlib/System.Collections.Generic/List.cs index 359e25df..bcf49071 100644 --- a/src/DNA/corlib/System.Collections.Generic/List.cs +++ b/src/DNA/corlib/System.Collections.Generic/List.cs @@ -184,6 +184,22 @@ public void InsertRange(int index, IEnumerable collection) { } } + // public void Sort() { + // Array.Sort(this.items, 0, this.size); + // } + + public void Sort(Comparison comparison) { + Array.Sort(this.items, 0, this.size, comparison); + } + + public void Sort(IComparer comparer) { + Array.Sort(this.items, 0, this.size, comparer); + } + + public void Sort(int index, int count, IComparer comparer) { + Array.Sort(this.items, index, count, comparer); + } + public T[] ToArray() { T[] array = new T[this.size]; Array.Copy(this.items, array, this.size); diff --git a/src/DNA/corlib/System.Collections.Generic/Queue.cs b/src/DNA/corlib/System.Collections.Generic/Queue.cs new file mode 100644 index 00000000..a753fa8c --- /dev/null +++ b/src/DNA/corlib/System.Collections.Generic/Queue.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.Collections.Generic { + public class Queue : IEnumerable, ICollection, IEnumerable { + T[] _array; + int _head; + int _tail; + int _size; + int _version; + + private const int INITIAL_SIZE = 16; + + public Queue() { + } + + public Queue(int count) { + if (count < 0) + throw new ArgumentOutOfRangeException("count"); + + _array = new T[count]; + } + + public Queue(IEnumerable collection) { + if (collection == null) + throw new ArgumentNullException("collection"); + + foreach (T t in collection) + Enqueue(t); + } + + public void Clear() { + if (_array != null) + Array.Clear(_array, 0, _array.Length); + + _head = _tail = _size = 0; + _version++; + } + + public bool Contains(T item) { + if (item == null) { + foreach (T t in this) + if (t == null) + return true; + } else { + foreach (T t in this) + if (item.Equals(t)) + return true; + } + + return false; + } + + public void CopyTo(T[] array, int idx) { + if (array == null) + throw new ArgumentNullException(); + + if ((uint)idx > (uint)array.Length) + throw new ArgumentOutOfRangeException(); + + if (array.Length - idx < _size) + throw new ArgumentOutOfRangeException(); + + if (_size == 0) + return; + + int contents_length = _array.Length; + int length_from_head = contents_length - _head; + + Array.Copy(_array, _head, array, idx, Math.Min(_size, length_from_head)); + if (_size > length_from_head) + Array.Copy(_array, 0, array, + idx + length_from_head, + _size - length_from_head); + + } + + void ICollection.CopyTo(Array array, int idx) { + if (array == null) + throw new ArgumentNullException(); + + if ((uint)idx < (uint)array.Length) + throw new ArgumentOutOfRangeException(); + + if (array.Length - idx < _size) + throw new ArgumentOutOfRangeException(); + + if (_size == 0) + return; + + try { + int contents_length = _array.Length; + int length_from_head = contents_length - _head; + + Array.Copy(_array, _head, array, idx, Math.Min(_size, length_from_head)); + if (_size > length_from_head) + Array.Copy(_array, 0, array, + idx + length_from_head, + _size - length_from_head); + } catch (ArrayTypeMismatchException) { + throw new ArgumentException(); + } + } + + public T Dequeue() { + T ret = Peek(); + + // clear stuff out to make the GC happy + _array[_head] = default(T); + + if (++_head == _array.Length) + _head = 0; + _size--; + _version++; + + return ret; + } + + public T Peek() { + if (_size == 0) + throw new InvalidOperationException(); + + return _array[_head]; + } + + public void Enqueue(T item) { + if (_array == null || _size == _array.Length) + SetCapacity(Math.Max(_size * 2, 4)); + + _array[_tail] = item; + + if (++_tail == _array.Length) + _tail = 0; + + _size++; + _version++; + } + + public T[] ToArray() { + T[] t = new T[_size]; + CopyTo(t, 0); + return t; + } + + public void TrimExcess() { + if (_array != null && (_size < _array.Length * 0.9)) + SetCapacity(_size); + } + + void SetCapacity(int new_size) { + if (_array != null && new_size == _array.Length) + return; + + if (new_size < _size) + throw new InvalidOperationException("shouldnt happen"); + + T[] new_data = new T[new_size]; + if (_size > 0) + CopyTo(new_data, 0); + + _array = new_data; + _tail = _size; + _head = 0; + _version++; + } + + public int Count { + get { return _size; } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return this; } + } + + public Enumerator GetEnumerator() { + return new Enumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public struct Enumerator : IEnumerator, IEnumerator, IDisposable { + const int NOT_STARTED = -2; + + // this MUST be -1, because we depend on it in move next. + // we just decr the _size, so, 0 - 1 == FINISHED + const int FINISHED = -1; + + Queue q; + int idx; + int ver; + + internal Enumerator(Queue q) { + this.q = q; + idx = NOT_STARTED; + ver = q._version; + } + + public void Dispose() { + idx = NOT_STARTED; + } + + public bool MoveNext() { + if (ver != q._version) + throw new InvalidOperationException(); + + if (idx == NOT_STARTED) + idx = q._size; + + return idx != FINISHED && --idx != FINISHED; + } + + public T Current { + get { + if (idx < 0) + throw new InvalidOperationException(); + + return q._array[(q._size - 1 - idx + q._head) % q._array.Length]; + } + } + + void IEnumerator.Reset() { + if (ver != q._version) + throw new InvalidOperationException(); + + idx = NOT_STARTED; + } + + object IEnumerator.Current { + get { return Current; } + } + + } + } +} diff --git a/src/DNA/corlib/System.Collections.Generic/Stack.cs b/src/DNA/corlib/System.Collections.Generic/Stack.cs new file mode 100644 index 00000000..ec9f4915 --- /dev/null +++ b/src/DNA/corlib/System.Collections.Generic/Stack.cs @@ -0,0 +1,239 @@ +// +// System.Collections.Generic.Stack +// +// Authors: +// Martin Baulig (martin@ximian.com) +// Ben Maurer (bmaurer@ximian.com) +// +// (C) 2003, 2004 Novell, Inc. +// + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +//using System.Runtime.InteropServices; + +namespace System.Collections.Generic +{ + public class Stack : IEnumerable , ICollection, IEnumerable + { + T [] _array; + int _size; + int _version; + + private const int INITIAL_SIZE = 16; + + public Stack () + { + } + + public Stack (int count) + { + if (count < 0) + throw new ArgumentOutOfRangeException ("count"); + + _array = new T [count]; + } + + public Stack (IEnumerable collection) + { + if (collection == null) + throw new ArgumentNullException ("collection"); + + ICollection col = collection as ICollection ; + + if (col != null) { + _size = col.Count; + _array = new T [_size]; + col.CopyTo (_array, 0); + } else { + foreach (T t in collection) + Push (t); + } + } + + public void Clear () + { + if (_array != null) + Array.Clear (_array, 0, _array.Length); + + _size = 0; + _version ++; + } + + public bool Contains (T t) + { + return _array != null && Array.IndexOf (_array, t, 0, _size) != -1; + } + + public void CopyTo (T [] dest, int idx) + { + // this gets copied in the order that it is poped + if (_array != null) { + Array.Copy (_array, 0, dest, idx, _size); + Array.Reverse (dest, idx, _size); + } + } + + public T Peek () + { + if (_size == 0) + throw new InvalidOperationException (); + + return _array [_size - 1]; + } + + public T Pop () + { + if (_size == 0) + throw new InvalidOperationException (); + + _version ++; + T popped = _array [--_size]; + // clear stuff out to make the GC happy + _array [_size] = default(T); + return popped; + } + + public void Push (T t) + { + if (_size == 0 || _size == _array.Length) + Array.Resize (ref _array, _size == 0 ? INITIAL_SIZE : 2 * _size); + + _version ++; + + _array [_size++] = t; + } + + public T [] ToArray () + { + T [] copy = new T [_size]; + CopyTo (copy, 0); + return copy; + } + + public void TrimExcess () + { + if (_array != null && (_size < _array.Length * 0.9)) + Array.Resize (ref _array, _size); + _version ++; + } + + public int Count { + get { return _size; } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return this; } + } + + void ICollection.CopyTo (Array dest, int idx) + { + try { + if (_array != null) { + _array.CopyTo (dest, idx); + Array.Reverse (dest, idx, _size); + } + } catch (ArrayTypeMismatchException) { + throw new ArgumentException (); + } + } + + public Enumerator GetEnumerator () + { + return new Enumerator (this); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + + public struct Enumerator : IEnumerator , IEnumerator, IDisposable { + const int NOT_STARTED = -2; + + // this MUST be -1, because we depend on it in move next. + // we just decr the _size, so, 0 - 1 == FINISHED + const int FINISHED = -1; + + Stack parent; + int idx; + int _version; + + internal Enumerator (Stack t) + { + parent = t; + idx = NOT_STARTED; + _version = t._version; + } + + public void Dispose () + { + idx = NOT_STARTED; + } + + public bool MoveNext () + { + if (_version != parent._version) + throw new InvalidOperationException (); + + if (idx == -2) + idx = parent._size; + + return idx != FINISHED && -- idx != FINISHED; + } + + public T Current { + get { + if (idx < 0) + throw new InvalidOperationException (); + + return parent._array [idx]; + } + } + + void IEnumerator.Reset () + { + if (_version != parent._version) + throw new InvalidOperationException (); + + idx = NOT_STARTED; + } + + object IEnumerator.Current { + get { return Current; } + } + + } + } +} diff --git a/src/DNA/corlib/System.Collections/IStructuralComparable.cs b/src/DNA/corlib/System.Collections/IStructuralComparable.cs new file mode 100644 index 00000000..42a38dc6 --- /dev/null +++ b/src/DNA/corlib/System.Collections/IStructuralComparable.cs @@ -0,0 +1,10 @@ +// source: https://bitbucket.org/danipen/mono/src/master/mcs/class/corlib/System.Collections/IStructuralComparable.cs +// Copyright (C) 2009 Novell + +using System; + +namespace System.Collections { + public interface IStructuralComparable { + int CompareTo(object other, IComparer comparer); + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Collections/IStructuralEquatable.cs b/src/DNA/corlib/System.Collections/IStructuralEquatable.cs new file mode 100644 index 00000000..50f1561e --- /dev/null +++ b/src/DNA/corlib/System.Collections/IStructuralEquatable.cs @@ -0,0 +1,13 @@ +// source: https://bitbucket.org/danipen/mono/src/master/mcs/class/corlib/System.Collections/IStructuralEquatable.cs +// Copyright (C) 2009 Novell + +using System; + +namespace System.Collections +{ + public interface IStructuralEquatable { + bool Equals (object other, IEqualityComparer comparer); + + int GetHashCode (IEqualityComparer comparer); + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Diagnostics/Debug.cs b/src/DNA/corlib/System.Diagnostics/Debug.cs new file mode 100644 index 00000000..3606a113 --- /dev/null +++ b/src/DNA/corlib/System.Diagnostics/Debug.cs @@ -0,0 +1,22 @@ + +namespace System.Diagnostics { + public static class Debug { + + public static void Assert(bool condition) { +#if DEBUG + if (!condition) { + throw new Exception(string.Empty); + } +#endif + } + + public static void Assert(bool condition, string message) { +#if DEBUG + if (!condition) { + throw new Exception(message); + } +#endif + } + + } +} diff --git a/src/DNA/corlib/System.Diagnostics/Debugger.cs b/src/DNA/corlib/System.Diagnostics/Debugger.cs index 39acce7a..8543dad0 100644 --- a/src/DNA/corlib/System.Diagnostics/Debugger.cs +++ b/src/DNA/corlib/System.Diagnostics/Debugger.cs @@ -27,10 +27,12 @@ public sealed class Debugger { [MethodImpl(MethodImplOptions.InternalCall)] extern public static void Break(); - [MethodImpl(MethodImplOptions.InternalCall)] - extern private static void Internal_BreakPoint(int method, int offset); + public static bool Launch() { Break(); return false; } - } + [MethodImpl(MethodImplOptions.InternalCall)] + extern private static void Internal_BreakPoint(int method, int offset); + + } } #endif diff --git a/src/DNA/corlib/System.Globalization/CultureInfo.cs b/src/DNA/corlib/System.Globalization/CultureInfo.cs index c9d46d77..193d78f9 100644 --- a/src/DNA/corlib/System.Globalization/CultureInfo.cs +++ b/src/DNA/corlib/System.Globalization/CultureInfo.cs @@ -5,7 +5,7 @@ using System.IO; namespace System.Globalization { - public class CultureInfo { + public class CultureInfo : IFormatProvider { #region Static methods @@ -267,6 +267,14 @@ public override string ToString() { return this.name; } + #region IFormatProvider Members + + object IFormatProvider.GetFormat(Type formatType) { + // throw new Exception("The method or operation is not implemented."); + return null; + } + + #endregion } } diff --git a/src/DNA/corlib/System.Globalization/DateTimeFormatInfo.cs b/src/DNA/corlib/System.Globalization/DateTimeFormatInfo.cs index a9bcfab3..123b97d9 100644 --- a/src/DNA/corlib/System.Globalization/DateTimeFormatInfo.cs +++ b/src/DNA/corlib/System.Globalization/DateTimeFormatInfo.cs @@ -3,7 +3,7 @@ using System.IO; using System.Threading; namespace System.Globalization { - public sealed class DateTimeFormatInfo { + public sealed class DateTimeFormatInfo : IFormatProvider { public static DateTimeFormatInfo InvariantInfo { get { @@ -164,6 +164,15 @@ public string GetEraName(int era) { public string GetMonthName(int m) { return this.monthNames[m]; } + + #region IFormatProvider Members + + object IFormatProvider.GetFormat(Type formatType) { + // throw new Exception("The method or operation is not implemented."); + return null; + } + + #endregion } } diff --git a/src/DNA/corlib/System.Globalization/NumberFormatInfo.cs b/src/DNA/corlib/System.Globalization/NumberFormatInfo.cs index becf5703..9126b644 100644 --- a/src/DNA/corlib/System.Globalization/NumberFormatInfo.cs +++ b/src/DNA/corlib/System.Globalization/NumberFormatInfo.cs @@ -172,8 +172,9 @@ public NumberFormatInfo() { #region IFormatProvider Members - public object GetFormat(Type formatType) { - throw new Exception("The method or operation is not implemented."); + object IFormatProvider.GetFormat(Type formatType) { + // throw new Exception("The method or operation is not implemented."); + return null; } #endregion diff --git a/src/DNA/corlib/System.IO/TextWriter.cs b/src/DNA/corlib/System.IO/TextWriter.cs new file mode 100644 index 00000000..e29464e5 --- /dev/null +++ b/src/DNA/corlib/System.IO/TextWriter.cs @@ -0,0 +1,268 @@ +// source: https://bitbucket.org/danipen/mono/src/master/mcs/class/corlib/System.IO/TextWriter.cs +// Copyright 2011 Xamarin Inc. + +using System.Text; +using System.Runtime.InteropServices; + +namespace System.IO { + + [Serializable] + // [ComVisible (true)] + public abstract class TextWriter : MarshalByRefObject, IDisposable { + + // + // Null version of the TextWriter, for the `Null' instance variable + // + sealed class NullTextWriter : TextWriter { + public override Encoding Encoding { + get { + return Encoding.Default; + } + } + + public override void Write(string s) { + } + public override void Write(char value) { + } + public override void Write(char[] value, int index, int count) { + } + } + + protected TextWriter() { + CoreNewLine = System.Environment.NewLine.ToCharArray(); + } + + protected TextWriter(IFormatProvider formatProvider) { + CoreNewLine = System.Environment.NewLine.ToCharArray(); + internalFormatProvider = formatProvider; + } + + protected char[] CoreNewLine; + + internal IFormatProvider internalFormatProvider; + + public static readonly TextWriter Null = new NullTextWriter(); + + public abstract Encoding Encoding { get; } + + public virtual IFormatProvider FormatProvider { + get { + return internalFormatProvider; + } + } + + public virtual string NewLine { + get { + return new string(CoreNewLine); + } + + set { + if (value == null) + value = Environment.NewLine; + + CoreNewLine = value.ToCharArray(); + } + } + + public virtual void Close() { + Dispose(true); + } + + protected virtual void Dispose(bool disposing) { + if (disposing) { + // If we are explicitly disposed, we can avoid finalization. + GC.SuppressFinalize(this); + } + } + public void Dispose() { + Dispose(true); + + // If we are explicitly disposed, we can avoid finalization. + GC.SuppressFinalize(this); + } + + public virtual void Flush() { + // do nothing + } + + public static TextWriter Synchronized(TextWriter writer) { + throw new NotImplementedException(); + } + + public virtual void Write(bool value) { + Write(value.ToString()); + } + + public virtual void Write(char value) { + // Do nothing + } + + public virtual void Write(char[] buffer) { + if (buffer == null) + return; + Write(buffer, 0, buffer.Length); + } + + public virtual void Write(decimal value) { + Write(value.ToString()); // .ToString(internalFormatProvider)); + } + + public virtual void Write(double value) { + Write(value.ToString(internalFormatProvider)); + } + + public virtual void Write(int value) { + Write(value.ToString(internalFormatProvider)); + } + + public virtual void Write(long value) { + Write(value.ToString(internalFormatProvider)); + } + + public virtual void Write(object value) { + if (value != null) + Write(value.ToString()); + } + + public virtual void Write(float value) { + Write(value.ToString(internalFormatProvider)); + } + + public virtual void Write(string value) { + if (value != null) + Write(value.ToCharArray()); + } + + // [CLSCompliant (false)] + public virtual void Write(uint value) { + Write(value.ToString(internalFormatProvider)); + } + + // [CLSCompliant (false)] + public virtual void Write(ulong value) { + Write(value.ToString(internalFormatProvider)); + } + + public virtual void Write(string format, object arg0) { + Write(String.Format(format, arg0)); + } + + public virtual void Write(string format, params object[] arg) { + Write(String.Format(format, arg)); + } + + public virtual void Write(char[] buffer, int index, int count) { + if (buffer == null) + throw new ArgumentNullException("buffer"); + if (index < 0 || index > buffer.Length) + throw new ArgumentOutOfRangeException("index"); + // re-ordered to avoid possible integer overflow + if (count < 0 || (index > buffer.Length - count)) + throw new ArgumentOutOfRangeException("count"); + + for (; count > 0; --count, ++index) { + Write(buffer[index]); + } + } + + public virtual void Write(string format, object arg0, object arg1) { + Write(String.Format(format, arg0, arg1)); + } + + public virtual void Write(string format, object arg0, object arg1, object arg2) { + Write(String.Format(format, arg0, arg1, arg2)); + } + + public virtual void WriteLine() { + Write(CoreNewLine); + } + + public virtual void WriteLine(bool value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(char value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(char[] buffer) { + Write(buffer); + WriteLine(); + } + + public virtual void WriteLine(decimal value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(double value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(int value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(long value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(object value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(float value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(string value) { + Write(value); + WriteLine(); + } + + // [CLSCompliant (false)] + public virtual void WriteLine(uint value) { + Write(value); + WriteLine(); + } + + // [CLSCompliant (false)] + public virtual void WriteLine(ulong value) { + Write(value); + WriteLine(); + } + + public virtual void WriteLine(string format, object arg0) { + Write(format, arg0); + WriteLine(); + } + + public virtual void WriteLine(string format, params object[] arg) { + Write(format, arg); + WriteLine(); + } + + public virtual void WriteLine(char[] buffer, int index, int count) { + Write(buffer, index, count); + WriteLine(); + } + + public virtual void WriteLine(string format, object arg0, object arg1) { + Write(format, arg0, arg1); + WriteLine(); + } + + public virtual void WriteLine(string format, object arg0, object arg1, object arg2) { + Write(format, arg0, arg1, arg2); + WriteLine(); + } + + } +} diff --git a/src/DNA/corlib/System.Net.Http/HttpClient.cs b/src/DNA/corlib/System.Net.Http/HttpClient.cs index bdbd3cb7..f7688876 100644 --- a/src/DNA/corlib/System.Net.Http/HttpClient.cs +++ b/src/DNA/corlib/System.Net.Http/HttpClient.cs @@ -1,4 +1,4 @@ -using Blazor.System.Runtime.InteropServices.Json; +using MiniJSON; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/DNA/corlib/System.Reflection/AmbiguousMatchException.cs b/src/DNA/corlib/System.Reflection/AmbiguousMatchException.cs new file mode 100644 index 00000000..9f1b46d9 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/AmbiguousMatchException.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System.Reflection { + + public class AmbiguousMatchException : SystemException { + + public AmbiguousMatchException() : base("Ambiguous matching in method resolution.") { } + + public AmbiguousMatchException(string message) : base(message) { } + + public AmbiguousMatchException(string message, Exception inner) : base(message, inner) { } + + } +} + +#endif diff --git a/src/DNA/corlib/System.Reflection/ConstructorInfo.cs b/src/DNA/corlib/System.Reflection/ConstructorInfo.cs new file mode 100644 index 00000000..bb8b8d24 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/ConstructorInfo.cs @@ -0,0 +1,8 @@ +using System.Runtime.CompilerServices; + +namespace System.Reflection +{ + public abstract class ConstructorInfo : MethodBase + { + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Reflection/EventInfo.cs b/src/DNA/corlib/System.Reflection/EventInfo.cs new file mode 100644 index 00000000..4b813263 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/EventInfo.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +namespace System.Reflection +{ + public abstract class EventInfo : MemberInfo + { + public override string Name { get; } + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Reflection/FieldInfo.cs b/src/DNA/corlib/System.Reflection/FieldInfo.cs new file mode 100644 index 00000000..e64033ca --- /dev/null +++ b/src/DNA/corlib/System.Reflection/FieldInfo.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +namespace System.Reflection +{ + public abstract class FieldInfo : MemberInfo + { + public override string Name { get; } + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Reflection/ICustomAttributeProvider.cs b/src/DNA/corlib/System.Reflection/ICustomAttributeProvider.cs new file mode 100644 index 00000000..3950b63c --- /dev/null +++ b/src/DNA/corlib/System.Reflection/ICustomAttributeProvider.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System.Reflection { + + public interface ICustomAttributeProvider { + + bool IsDefined(Type attributeType, bool inherit); + + Object[] GetCustomAttributes(bool inherit); + + Object[] GetCustomAttributes(Type attributeType, bool inherit); + } + +} + +#endif diff --git a/src/DNA/corlib/System.Reflection/MemberInfo.cs b/src/DNA/corlib/System.Reflection/MemberInfo.cs index 9c49fecc..fb4a7941 100644 --- a/src/DNA/corlib/System.Reflection/MemberInfo.cs +++ b/src/DNA/corlib/System.Reflection/MemberInfo.cs @@ -26,15 +26,22 @@ using System.Text; namespace System.Reflection { - public abstract class MemberInfo { + public abstract class MemberInfo : ICustomAttributeProvider { + #pragma warning disable 0169, 0649 - protected readonly Type _ownerType; - protected readonly string _name; + protected readonly Type _ownerType; + protected readonly string _name; #pragma warning restore 0169, 0649 - protected MemberInfo() { + protected MemberInfo() { } + public abstract bool IsDefined(Type attributeType, bool inherit); + + public abstract Object[] GetCustomAttributes(bool inherit); + + public abstract Object[] GetCustomAttributes(Type attributeType, bool inherit); + protected MemberInfo(Type ownerType, string name) { _ownerType = ownerType; diff --git a/src/DNA/corlib/System.Reflection/MethodAttributes.cs b/src/DNA/corlib/System.Reflection/MethodAttributes.cs new file mode 100644 index 00000000..82e2aedd --- /dev/null +++ b/src/DNA/corlib/System.Reflection/MethodAttributes.cs @@ -0,0 +1,69 @@ +// MethodAttributes.cs +// +// This code was automatically generated from +// ECMA CLI XML Library Specification. +// Generator: libgen.xsl [1.0; (C) Sergey Chaban (serge@wildwestsoftware.com)] +// Created: Wed, 5 Sep 2001 06:39:32 UTC +// Source file: all.xml +// URL: http://devresource.hp.com/devresource/Docs/TechPapers/CSharp/all.xml +// +// (C) 2001 Ximian, Inc. http://www.ximian.com + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Runtime.InteropServices; + +namespace System.Reflection { + + // [ComVisible (true)] + [Serializable] + [Flags] + public enum MethodAttributes { + MemberAccessMask = 7, + PrivateScope = 0, + Private = 1, + FamANDAssem = 2, + Assembly = 3, + Family = 4, + FamORAssem = 5, + Public = 6, + Static = 16, + Final = 32, + Virtual = 64, + HideBySig = 128, + VtableLayoutMask = 256, + CheckAccessOnOverride = 512, + ReuseSlot = 0, + NewSlot = 256, + Abstract = 1024, + SpecialName = 2048, + PinvokeImpl = 8192, + UnmanagedExport = 8, + RTSpecialName = 4096, + ReservedMask = 53248, + HasSecurity = 16384, + RequireSecObject = 32768, + } // MethodAttributes + +} // System.Reflection diff --git a/src/DNA/corlib/System.Reflection/MethodBase.cs b/src/DNA/corlib/System.Reflection/MethodBase.cs new file mode 100644 index 00000000..c07dffc4 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/MethodBase.cs @@ -0,0 +1,54 @@ + using System.Runtime.CompilerServices; + + namespace System.Reflection { + + public abstract class MethodBase : MemberInfo { +#pragma warning disable 0169, 0649 + // populated by interop, MUST be synced with C code + private readonly uint _flags; + private readonly IntPtr _methodDef; +#pragma warning restore 0169, 0649 + + public object Invoke(object target, object[] parameters) { + // This is not invoked at runtime, because the JITter specifically replaces calls + // to MethodBase.Invoke with its own special opcode + throw new NotImplementedException(); + } + + public MethodAttributes Attributes { get { return (MethodAttributes)_flags; } } + + public Boolean IsPublic { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } + } + public Boolean IsPrivate { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } + } + public Boolean IsFamily { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } + } + public Boolean IsAssembly { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } + } + public Boolean IsFamilyAndAssembly { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } + } + public Boolean IsFamilyOrAssembly { + get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } + } + public Boolean IsStatic { + get { return (Attributes & MethodAttributes.Static) != 0; } + } + public Boolean IsFinal { + get { return (Attributes & MethodAttributes.Final) != 0; } + } + public Boolean IsVirtual { + get { return (Attributes & MethodAttributes.Virtual) != 0; } + } + public Boolean IsHideBySig { + get { return (Attributes & MethodAttributes.HideBySig) != 0; } + } + public Boolean IsAbstract { + get { return (Attributes & MethodAttributes.Abstract) != 0; } + } + } +} \ No newline at end of file diff --git a/src/DNA/corlib/System.Reflection/MethodInfo.cs b/src/DNA/corlib/System.Reflection/MethodInfo.cs index b3108d60..b483f74d 100644 --- a/src/DNA/corlib/System.Reflection/MethodInfo.cs +++ b/src/DNA/corlib/System.Reflection/MethodInfo.cs @@ -1,22 +1,10 @@ using System.Runtime.CompilerServices; -namespace System.Reflection -{ - public abstract class MethodInfo : MethodBase - { - } +namespace System.Reflection { + + public abstract class MethodInfo : MethodBase { - public abstract class MethodBase : MemberInfo - { -#pragma warning disable 0169, 0649 - private readonly IntPtr _methodDef; -#pragma warning restore 0169, 0649 - - public object Invoke(object target, object[] parameters) - { - // This is not invoked at runtime, because the JITter specifically replaces calls - // to MethodBase.Invoke with its own special opcode - throw new NotImplementedException(); - } + [MethodImpl(MethodImplOptions.InternalCall)] + extern public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments); } } \ No newline at end of file diff --git a/src/DNA/corlib/System.Reflection/Module.cs b/src/DNA/corlib/System.Reflection/Module.cs new file mode 100644 index 00000000..e1f50fe9 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/Module.cs @@ -0,0 +1,15 @@ +namespace System.Reflection { + public abstract class Module : ICustomAttributeProvider { + + protected Module() { + } + + public abstract string Name { get; } + + public abstract bool IsDefined(Type attributeType, bool inherit); + + public abstract Object[] GetCustomAttributes(bool inherit); + + public abstract Object[] GetCustomAttributes(Type attributeType, bool inherit); + } +} diff --git a/src/DNA/corlib/System.Reflection/ParameterInfo.cs b/src/DNA/corlib/System.Reflection/ParameterInfo.cs new file mode 100644 index 00000000..bfa3113d --- /dev/null +++ b/src/DNA/corlib/System.Reflection/ParameterInfo.cs @@ -0,0 +1,15 @@ +namespace System.Reflection { + public abstract class ParameterInfo : ICustomAttributeProvider { + + protected ParameterInfo() { + } + + public abstract string Name { get; } + + public abstract bool IsDefined(Type attributeType, bool inherit); + + public abstract Object[] GetCustomAttributes(bool inherit); + + public abstract Object[] GetCustomAttributes(Type attributeType, bool inherit); + } +} diff --git a/src/DNA/corlib/System.Reflection/PropertyInfo.cs b/src/DNA/corlib/System.Reflection/PropertyInfo.cs index ec09db70..b951e6dd 100644 --- a/src/DNA/corlib/System.Reflection/PropertyInfo.cs +++ b/src/DNA/corlib/System.Reflection/PropertyInfo.cs @@ -1,21 +1,18 @@ -namespace System.Reflection -{ - public abstract class PropertyInfo : MemberInfo - { +namespace System.Reflection { + public abstract class PropertyInfo : MemberInfo { + #pragma warning disable 0649 private readonly Type _propertyType; #pragma warning restore 0649 public Type PropertyType => _propertyType; - public MethodInfo GetGetMethod() - { - return _ownerType.GetMethod("get_" + _name); + public MethodInfo GetGetMethod() { + return _ownerType.GetMethod("get_" + Name); } - public MethodInfo GetSetMethod() - { - return _ownerType.GetMethod("set_" + _name); + public MethodInfo GetSetMethod() { + return _ownerType.GetMethod("set_" + Name); } public MethodInfo GetMethod => GetGetMethod(); diff --git a/src/DNA/corlib/System.Reflection/RuntimeReflectionExtensions.cs b/src/DNA/corlib/System.Reflection/RuntimeReflectionExtensions.cs index 5a1c1216..3abecef9 100644 --- a/src/DNA/corlib/System.Reflection/RuntimeReflectionExtensions.cs +++ b/src/DNA/corlib/System.Reflection/RuntimeReflectionExtensions.cs @@ -10,5 +10,9 @@ public static IEnumerable GetRuntimeProperties(this Type type) { return type.GetProperties(); } + public static IEnumerable GetRuntimeMethods(this Type type) + { + return type.GetMethods(); + } } } diff --git a/src/DNA/corlib/System.Reflection/TypeAttributes.cs b/src/DNA/corlib/System.Reflection/TypeAttributes.cs new file mode 100644 index 00000000..dacd7002 --- /dev/null +++ b/src/DNA/corlib/System.Reflection/TypeAttributes.cs @@ -0,0 +1,65 @@ +// source: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/reflection/typeattributes.cs +// Copyright (c) Microsoft Corporation. All rights reserved. + +namespace System.Reflection { + using System.Runtime.InteropServices; + using System; + // This Enum matches the CorTypeAttr defined in CorHdr.h +[Serializable] +[Flags] +// [System.Runtime.InteropServices.ComVisible(true)] + public enum TypeAttributes + { + VisibilityMask = 0x00000007, + NotPublic = 0x00000000, // Class is not public scope. + Public = 0x00000001, // Class is public scope. + NestedPublic = 0x00000002, // Class is nested with public visibility. + NestedPrivate = 0x00000003, // Class is nested with private visibility. + NestedFamily = 0x00000004, // Class is nested with family visibility. + NestedAssembly = 0x00000005, // Class is nested with assembly visibility. + NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility. + NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility. + + // Use this mask to retrieve class layout informaiton + // 0 is AutoLayout, 0x2 is SequentialLayout, 4 is ExplicitLayout + LayoutMask = 0x00000018, + AutoLayout = 0x00000000, // Class fields are auto-laid out + SequentialLayout = 0x00000008, // Class fields are laid out sequentially + ExplicitLayout = 0x00000010, // Layout is supplied explicitly + // end layout mask + + // Use this mask to distinguish whether a type declaration is an interface. (Class vs. ValueType done based on whether it subclasses S.ValueType) + ClassSemanticsMask= 0x00000020, + Class = 0x00000000, // Type is a class (or a value type). + Interface = 0x00000020, // Type is an interface. + + // Special semantics in addition to class semantics. + Abstract = 0x00000080, // Class is abstract + Sealed = 0x00000100, // Class is concrete and may not be extended + SpecialName = 0x00000400, // Class name is special. Name describes how. + + // Implementation attributes. + Import = 0x00001000, // Class / interface is imported + Serializable = 0x00002000, // The class is Serializable. + + // [ComVisible(false)] + WindowsRuntime = 0x00004000, // Type is a Windows Runtime type. + + // Use tdStringFormatMask to retrieve string information for native interop + StringFormatMask = 0x00030000, + AnsiClass = 0x00000000, // LPTSTR is interpreted as ANSI in this class + UnicodeClass = 0x00010000, // LPTSTR is interpreted as UNICODE + AutoClass = 0x00020000, // LPTSTR is interpreted automatically + CustomFormatClass = 0x00030000, // A non-standard encoding specified by CustomFormatMask + CustomFormatMask = 0x00C00000, // Use this mask to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified. + + // end string format mask + + BeforeFieldInit = 0x00100000, // Initialize the class any time before first static field access. + + // Flags reserved for runtime use. + ReservedMask = 0x00040800, + RTSpecialName = 0x00000800, // Runtime should check name encoding. + HasSecurity = 0x00040000, // Class has security associate with it. + } +} diff --git a/src/DNA/corlib/System.Reflection/TypeExtensions.cs b/src/DNA/corlib/System.Reflection/TypeExtensions.cs new file mode 100644 index 00000000..b3a83d9c --- /dev/null +++ b/src/DNA/corlib/System.Reflection/TypeExtensions.cs @@ -0,0 +1,24 @@ +using System; + +namespace System.Reflection { + + public static class TypeExtensions { + + public static Type[] GetGenericArguments(Type type) { + return type.GetGenericArguments(); + } + + public static MethodInfo GetMethod(Type type, string name) { + return type.GetMethod(name); + } + + public static MethodInfo[] GetMethods(Type type) { + return type.GetMethods(); + } + + public static PropertyInfo[] GetProperties(Type type) { + return type.GetProperties(); + } + + } +} diff --git a/src/DNA/corlib/System.Reflection/TypeInfo.cs b/src/DNA/corlib/System.Reflection/TypeInfo.cs index 6f0c63b7..3fe357d7 100644 --- a/src/DNA/corlib/System.Reflection/TypeInfo.cs +++ b/src/DNA/corlib/System.Reflection/TypeInfo.cs @@ -1,14 +1,32 @@ -namespace System.Reflection -{ - public class TypeInfo : MemberInfo - { +using System.Collections.Generic; + +namespace System.Reflection { + + public class TypeInfo { + private readonly Type _type; - internal TypeInfo(Type type) : base(type, type.Name) + internal TypeInfo(Type type) { _type = type; } public bool IsValueType => _type.IsValueType; + + public virtual Type[] GenericTypeParameters { + get { return _type.GetGenericArguments(); } + } + + public virtual IEnumerable DeclaredMethods { + get { return _type.GetMethods(); } + } + + public virtual bool IsGenericType { + get { return _type.IsGenericType; } + } + + public virtual bool IsGenericTypeDefinition { + get { return _type.IsGenericTypeDefinition; } + } } } \ No newline at end of file diff --git a/src/DNA/corlib/System.Runtime.InteropServices/CharSet.cs b/src/DNA/corlib/System.Runtime.InteropServices/CharSet.cs index d506e2ac..a9ef5a9a 100644 --- a/src/DNA/corlib/System.Runtime.InteropServices/CharSet.cs +++ b/src/DNA/corlib/System.Runtime.InteropServices/CharSet.cs @@ -21,6 +21,7 @@ #if !LOCALTEST namespace System.Runtime.InteropServices { + [Serializable] public enum CharSet { None = 1, Ansi = 2, diff --git a/src/DNA/corlib/System.Runtime.InteropServices/FieldOffsetAttribute.cs b/src/DNA/corlib/System.Runtime.InteropServices/FieldOffsetAttribute.cs new file mode 100644 index 00000000..8befab8e --- /dev/null +++ b/src/DNA/corlib/System.Runtime.InteropServices/FieldOffsetAttribute.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System.Runtime.InteropServices { + + [AttributeUsage (AttributeTargets.Field, Inherited=false)] + public sealed class FieldOffsetAttribute : Attribute { + private int val; + public FieldOffsetAttribute( int offset) { val = offset; } + public int Value { get { return val; } } + } +} + +#endif diff --git a/src/DNA/corlib/System.Runtime.InteropServices/Json/Json.cs b/src/DNA/corlib/System.Runtime.InteropServices/Json/Json.cs index 40d13c3c..a162979c 100644 --- a/src/DNA/corlib/System.Runtime.InteropServices/Json/Json.cs +++ b/src/DNA/corlib/System.Runtime.InteropServices/Json/Json.cs @@ -30,16 +30,10 @@ using System.Collections; using System.Collections.Generic; using System.IO; -using System.Text; using System.Reflection; +using System.Text; -// This is currently duplicated in both the corlib code (because it can't directly address -// anything in Blazor.Runtime), and in Blazor.Runtime (because it can only see corlib APIs -// that are also part of netstandard). Consider restructuring these assemblies and their -// references to one another. - -namespace Blazor.System.Runtime.InteropServices.Json -{ +namespace MiniJSON { // Example usage: // // using UnityEngine; @@ -102,6 +96,12 @@ public static bool IsWordBreak(char c) { return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1; } + const string HEX_DIGIT = "0123456789ABCDEFabcdef"; + + public static bool IsHexDigit(char c) { + return HEX_DIGIT.IndexOf(c) != -1; + } + enum TOKEN { NONE, CURLY_OPEN, @@ -149,7 +149,7 @@ Dictionary ParseObject() { continue; case TOKEN.CURLY_CLOSE: return table; - default: + case TOKEN.STRING: // name string name = ParseString(); if (name == null) { @@ -164,8 +164,14 @@ Dictionary ParseObject() { json.Read(); // value - table[name] = ParseValue(); + TOKEN valueToken = NextToken; + object value = ParseByToken(valueToken); + if(value==null && valueToken!=TOKEN.NULL) + return null; + table[name] = value; break; + default: + return null; } } } @@ -191,7 +197,8 @@ List ParseArray() { break; default: object value = ParseByToken(nextToken); - + if(value==null && nextToken!=TOKEN.NULL) + return null; array.Add(value); break; } @@ -279,10 +286,12 @@ string ParseString() { for (int i=0; i< 4; i++) { hex[i] = NextChar; + if (!IsHexDigit(hex[i])) + return null; } - throw new NotImplementedException("Parsing incoming \\u values"); - //s.Append((char) Convert.ToInt32(new string(hex), 16)); - //break; + + s.Append((char) Convert.ToInt32(new string(hex), 16)); + break; } break; default: @@ -297,19 +306,15 @@ string ParseString() { object ParseNumber() { string number = NextWord; - if (number.IndexOf('.') == -1) { + if (number.IndexOf('.') == -1 && number.IndexOf('E') == -1 && number.IndexOf('e') == -1) { int parsedInt; Int32.TryParse(number, out parsedInt); - return parsedInt; + return (double)parsedInt; } - // TODO: Actually parse doubles - return 0; - /* - float parsedDouble; - Single.TryParse(number, out parsedDouble); + double parsedDouble; + Double.TryParse(number, out parsedDouble); return parsedDouble; - */ } void EatWhitespace() { diff --git a/src/DNA/corlib/System.Runtime.InteropServices/LayoutKind.cs b/src/DNA/corlib/System.Runtime.InteropServices/LayoutKind.cs new file mode 100644 index 00000000..1266c4f1 --- /dev/null +++ b/src/DNA/corlib/System.Runtime.InteropServices/LayoutKind.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System.Runtime.InteropServices { + [Serializable] + public enum LayoutKind { + Sequential = 0, + Explicit = 2, + Auto = 3 + } +} + +#endif diff --git a/src/DNA/corlib/System.Runtime.InteropServices/StructLayoutAttribute.cs b/src/DNA/corlib/System.Runtime.InteropServices/StructLayoutAttribute.cs new file mode 100644 index 00000000..5d3c9bc1 --- /dev/null +++ b/src/DNA/corlib/System.Runtime.InteropServices/StructLayoutAttribute.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System.Runtime.InteropServices { + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)] + public sealed class StructLayoutAttribute : Attribute { + + private readonly LayoutKind _value; + + public LayoutKind Value { get { return _value; } } + + public int Pack; + + public int Size; + + public CharSet CharSet; + + public StructLayoutAttribute(LayoutKind layoutKind) { + _value = layoutKind; + } + + public StructLayoutAttribute(short layoutKind) { + _value = (LayoutKind)layoutKind; + } + } +} + +#endif \ No newline at end of file diff --git a/src/DNA/corlib/System.Text/Encoding.cs b/src/DNA/corlib/System.Text/Encoding.cs index 04e3f706..77a3936e 100644 --- a/src/DNA/corlib/System.Text/Encoding.cs +++ b/src/DNA/corlib/System.Text/Encoding.cs @@ -22,74 +22,80 @@ namespace System.Text { - public abstract class Encoding : ICloneable { - - private static object lockObj = new object(); - - #region Static common Encoding properties - - private static Encoding unicodeEncoding = null; - private static Encoding utf8Encoding = null; - private static Encoding utf8UnmarkedEncoding = null; - - public static Encoding Unicode { - get { - if (unicodeEncoding == null) { - lock (lockObj) { - if (unicodeEncoding == null) { - unicodeEncoding = new UnicodeEncoding(true, false); - } - } - } - return unicodeEncoding; - } - } - - public static Encoding UTF8 { - get { - if (utf8Encoding == null) { - lock (lockObj) { - if (utf8Encoding == null) { - utf8Encoding = new UTF8Encoding(true); - } - } - } - return utf8Encoding; - } - } - - public static Encoding UTF8Unmarked { - get { - if (utf8UnmarkedEncoding == null) { - lock (lockObj) { - if (utf8UnmarkedEncoding == null) { - utf8UnmarkedEncoding = new UTF8Encoding(false); - } - } - } - return utf8UnmarkedEncoding; - } - } - - #endregion - - public virtual byte[] GetPreamble() { - return new byte[0]; - } - - public abstract int GetMaxCharCount(int byteCount); - - public abstract Decoder GetDecoder(); - - - #region ICloneable Members - - public object Clone() { - return (Encoding)object.Clone(this); - } - - #endregion - } + public abstract class Encoding : ICloneable { + + private static object lockObj = new object(); + + #region Static common Encoding properties + + private static Encoding unicodeEncoding = null; + private static Encoding utf8Encoding = null; + private static Encoding utf8UnmarkedEncoding = null; + + public static Encoding Default { + get { + return Encoding.UTF8; + } + } + + public static Encoding Unicode { + get { + if (unicodeEncoding == null) { + lock (lockObj) { + if (unicodeEncoding == null) { + unicodeEncoding = new UnicodeEncoding(true, false); + } + } + } + return unicodeEncoding; + } + } + + public static Encoding UTF8 { + get { + if (utf8Encoding == null) { + lock (lockObj) { + if (utf8Encoding == null) { + utf8Encoding = new UTF8Encoding(true); + } + } + } + return utf8Encoding; + } + } + + public static Encoding UTF8Unmarked { + get { + if (utf8UnmarkedEncoding == null) { + lock (lockObj) { + if (utf8UnmarkedEncoding == null) { + utf8UnmarkedEncoding = new UTF8Encoding(false); + } + } + } + return utf8UnmarkedEncoding; + } + } + + #endregion + + public virtual byte[] GetPreamble() { + return new byte[0]; + } + + public abstract int GetMaxCharCount(int byteCount); + + public abstract Decoder GetDecoder(); + + + #region ICloneable Members + + public object Clone() { + return (Encoding)object.Clone(this); + } + + #endregion + } } diff --git a/src/DNA/corlib/System.Threading/Thread.cs b/src/DNA/corlib/System.Threading/Thread.cs index 57c04aab..fd9f099d 100644 --- a/src/DNA/corlib/System.Threading/Thread.cs +++ b/src/DNA/corlib/System.Threading/Thread.cs @@ -26,12 +26,12 @@ namespace System.Threading { public sealed class Thread { - // These member vars MUST be synced with C code. + // These member vars MUST be synced with C code. #pragma warning disable 0169, 0414, 0649 - private int managedThreadID = 0; + private int managedThreadID = 0; private MulticastDelegate threadStart = null; #pragma warning restore 0169, 0414, 0649 - private object param = null; + private object param = null; private ThreadState threadState = ThreadState.Unstarted; private CultureInfo currentCulture; diff --git a/src/DNA/corlib/System/ArgumentOutOfRangeException.cs b/src/DNA/corlib/System/ArgumentOutOfRangeException.cs index 875c6f19..8e286ccd 100644 --- a/src/DNA/corlib/System/ArgumentOutOfRangeException.cs +++ b/src/DNA/corlib/System/ArgumentOutOfRangeException.cs @@ -28,6 +28,11 @@ public ArgumentOutOfRangeException() : base("Argument is out of range.") { } public ArgumentOutOfRangeException(string paramName) : base("Argument is out of range.", paramName) { } public ArgumentOutOfRangeException(string paramName, string msg) : base(msg, paramName) { } + + public ArgumentOutOfRangeException(String paramName, Object actualValue, String message) + : base(message, paramName) + { + } } } diff --git a/src/DNA/corlib/System/Array.cs b/src/DNA/corlib/System/Array.cs index 88013d22..79a6d944 100644 --- a/src/DNA/corlib/System/Array.cs +++ b/src/DNA/corlib/System/Array.cs @@ -326,15 +326,86 @@ public static TOutput[] ConvertAll(TInput[] array, Converter(T[] array) where T: IComparable, IComparable { + Sort(array, 0, array.Length); + } - public static T[] Empty() - { - return (T[])CreateInstance(typeof(T), 0); - } + public static void Sort(T[] array, int index, int count) where T: IComparable, IComparable { + void swap(T[] a, int i, int j) { T t = a[i]; a[i] = a[j]; a[j] = t; } + int gap = count; + bool swapped; + do { + swapped = false; + gap = gap * 4 / 5; // 80% gap reduction + gap = gap < 1 ? 1 : (gap == 9 || gap == 10) ? 11 : gap; + for (int i = index; i < count - gap; ++i) { + if (array[i].CompareTo(array[i + gap]) > 0) { + swapped = true; + swap(array, i, i + gap); + } + } + } while (gap > 1 || swapped); + } - [MethodImpl(MethodImplOptions.InternalCall)] - extern public static Array CreateInstance(Type elementType, int length); + public static void Sort(T[] array, Comparison comparison) { + Sort(array, 0, array.Length, comparison); + } + + public static void Sort(T[] array, IComparer comparer) { + Sort(array, 0, array.Length, comparer ?? Comparer.Default); + } + + public static void Sort(T[] array, int index, int count, Comparison comparison) { + Sort(array, index, count, Comparer.Create(comparison)); + } + + public static void Sort(T[] array, int index, int count, IComparer comparer) { + void swap(T[] a, int i, int j) { T t = a[i]; a[i] = a[j]; a[j] = t; } + int gap = count; + bool swapped; + do { + swapped = false; + gap = gap * 4 / 5; // 80% gap reduction + gap = gap < 1 ? 1 : (gap == 9 || gap == 10) ? 11 : gap; + for (int i = index; i < count - gap; ++i) { + if (comparer.Compare(array[i], array[i + gap]) > 0) { + swapped = true; + swap(array, i, i + gap); + } + } + } while (gap > 1 || swapped); + } + + public static void Sort(TKey[] keys, TValue[] items, IComparer comparer) { + Sort(keys, items, 0, keys.Length, comparer ?? Comparer.Default); + } + + public static void Sort(TKey[] keys, TValue[] items, int index, int count, IComparer comparer) { + void swap(V[] a, int i, int j) { V t = a[i]; a[i] = a[j]; a[j] = t; } + int gap = count; + bool swapped; + do { + swapped = false; + gap = gap * 4 / 5; // 80% gap reduction + gap = gap < 1 ? 1 : (gap == 9 || gap == 10) ? 11 : gap; + for (int i = index; i < count - gap; ++i) { + if (comparer.Compare(keys[i], keys[i + gap]) > 0) { + swapped = true; + swap(keys, i, i + gap); + swap(items, i, i + gap); + } + } + } while (gap > 1 || swapped); + } + + public static T[] Empty() { + return (T[])CreateInstance(typeof(T), 0); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + extern public static Array CreateInstance(Type elementType, int length); #region Interface Members diff --git a/src/DNA/corlib/System/Attribute.cs b/src/DNA/corlib/System/Attribute.cs index 83b3af6c..4b484598 100644 --- a/src/DNA/corlib/System/Attribute.cs +++ b/src/DNA/corlib/System/Attribute.cs @@ -18,10 +18,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System.Collections.Generic; +using System.Reflection; + #if !LOCALTEST namespace System { public abstract class Attribute { + + public virtual object TypeId { + get { + return this.GetType(); + } + } + + public static IEnumerable GetCustomAttributes(MemberInfo element, bool inherit) + { + return null; + } } } diff --git a/src/DNA/corlib/System/AttributeTargets.cs b/src/DNA/corlib/System/AttributeTargets.cs index 77a98180..ea55153a 100644 --- a/src/DNA/corlib/System/AttributeTargets.cs +++ b/src/DNA/corlib/System/AttributeTargets.cs @@ -22,6 +22,7 @@ namespace System { + [Flags, Serializable] public enum AttributeTargets { Assembly = 0x00000001, Module = 0x00000002, diff --git a/src/DNA/corlib/System/BitConverter.cs b/src/DNA/corlib/System/BitConverter.cs index e66583ab..b371c36b 100644 --- a/src/DNA/corlib/System/BitConverter.cs +++ b/src/DNA/corlib/System/BitConverter.cs @@ -1,22 +1,318 @@ -#if !LOCALTEST +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; using System.Runtime.CompilerServices; +using System.Text; + namespace System { + public static class BitConverter { + private static readonly bool SwappedWordsInDouble = DoubleWordsAreSwapped (); + public static readonly bool IsLittleEndian = AmILittleEndian (); + + static unsafe bool AmILittleEndian () { + // binary representations of 1.0: + // big endian: 3f f0 00 00 00 00 00 00 + // little endian: 00 00 00 00 00 00 f0 3f + // arm fpa little endian: 00 00 f0 3f 00 00 00 00 + double d = 1.0; + byte *b = (byte*)&d; + return (b [0] == 0); + } + + static unsafe bool DoubleWordsAreSwapped () { + // binary representations of 1.0: + // big endian: 3f f0 00 00 00 00 00 00 + // little endian: 00 00 00 00 00 00 f0 3f + // arm fpa little endian: 00 00 f0 3f 00 00 00 00 + double d = 1.0; + byte *b = (byte*)&d; + return b [2] == 0xf0; + } + + public unsafe static long DoubleToInt64Bits (double value) { + return *(long *) &value; + } + + public unsafe static double Int64BitsToDouble (long value) { + return *(double *) &value; + } + + unsafe static byte[] GetBytes (byte *ptr, int count) { + byte [] ret = new byte [count]; + for (int i = 0; i < count; i++) { + ret [i] = ptr [i]; + } + return ret; + } + + unsafe public static byte[] GetBytes (bool value) { + return GetBytes ((byte *) &value, 1); + } + + unsafe public static byte[] GetBytes (char value) { + return GetBytes ((byte *) &value, 2); + } + + unsafe public static byte[] GetBytes (short value) { + return GetBytes ((byte *) &value, 2); + } + + unsafe public static byte[] GetBytes (int value) { + return GetBytes ((byte *) &value, 4); + } - public static readonly bool IsLittleEndian = AmILittleEndian(); + unsafe public static byte[] GetBytes (long value) { + return GetBytes ((byte *) &value, 8); + } + + //[CLSCompliant (false)] + unsafe public static byte[] GetBytes (ushort value) { + return GetBytes ((byte *) &value, 2); + } + + //[CLSCompliant (false)] + unsafe public static byte[] GetBytes (uint value) { + return GetBytes ((byte *) &value, 4); + } + + //[CLSCompliant (false)] + unsafe public static byte[] GetBytes (ulong value) { + return GetBytes ((byte *) &value, 8); + } + + unsafe public static byte[] GetBytes (float value) { + return GetBytes ((byte *) &value, 4); + } + + unsafe public static byte[] GetBytes (double value) { + if (SwappedWordsInDouble) { + byte[] data = new byte [8]; + byte *p = (byte*)&value; + data [0] = p [4]; + data [1] = p [5]; + data [2] = p [6]; + data [3] = p [7]; + data [4] = p [0]; + data [5] = p [1]; + data [6] = p [2]; + data [7] = p [3]; + return data; + } else { + return GetBytes ((byte *) &value, 8); + } + } + + unsafe static void PutBytes (byte *dst, byte[] src, int start_index, int count) { + if (src == null) + throw new ArgumentNullException ("value"); + + if (start_index < 0 || (start_index > src.Length - 1)) + throw new ArgumentOutOfRangeException ("startIndex", "Index was" + + " out of range. Must be non-negative and less than the" + + " size of the collection."); + + // avoid integer overflow (with large pos/neg start_index values) + if (src.Length - count < start_index) + throw new ArgumentException ("Destination array is not long" + + " enough to copy all the items in the collection." + + " Check array index and length."); + + for (int i = 0; i < count; i++) + dst[i] = src[i + start_index]; + } + + unsafe public static bool ToBoolean (byte[] value, int startIndex) { + if (value == null) + throw new ArgumentNullException ("value"); + + if (startIndex < 0 || (startIndex > value.Length - 1)) + throw new ArgumentOutOfRangeException ("startIndex", "Index was" + + " out of range. Must be non-negative and less than the" + + " size of the collection."); + + if (value [startIndex] != 0) + return true; + + return false; + } - private unsafe static bool AmILittleEndian() { - int i = 1; - byte b = *((byte*)&i); - return (b == 1); + unsafe public static char ToChar (byte[] value, int startIndex) { + char ret; + PutBytes ((byte *) &ret, value, startIndex, 2); + return ret; } - public unsafe static long DoubleToInt64Bits(double value) { - return *((long*)&value); + unsafe public static short ToInt16 (byte[] value, int startIndex) { + short ret; + PutBytes ((byte *) &ret, value, startIndex, 2); + return ret; + } + + unsafe public static int ToInt32 (byte[] value, int startIndex) { + int ret; + PutBytes ((byte *) &ret, value, startIndex, 4); + return ret; + } + + unsafe public static long ToInt64 (byte[] value, int startIndex) { + long ret; + PutBytes ((byte *) &ret, value, startIndex, 8); + return ret; + } + + //[CLSCompliant (false)] + unsafe public static ushort ToUInt16 (byte[] value, int startIndex) { + ushort ret; + PutBytes ((byte *) &ret, value, startIndex, 2); + return ret; + } + + //[CLSCompliant (false)] + unsafe public static uint ToUInt32 (byte[] value, int startIndex) { + uint ret; + PutBytes ((byte *) &ret, value, startIndex, 4); + return ret; + } + + //[CLSCompliant (false)] + unsafe public static ulong ToUInt64 (byte[] value, int startIndex) { + ulong ret; + PutBytes ((byte *) &ret, value, startIndex, 8); + return ret; + } + + unsafe public static float ToSingle (byte[] value, int startIndex) { + float ret; + PutBytes ((byte *) &ret, value, startIndex, 4); + return ret; + } + + unsafe public static double ToDouble (byte[] value, int startIndex) { + double ret; + + if (SwappedWordsInDouble) { + byte* p = (byte*)&ret; + if (value == null) + throw new ArgumentNullException ("value"); + + if (startIndex < 0 || (startIndex > value.Length - 1)) + throw new ArgumentOutOfRangeException ("startIndex", "Index was" + + " out of range. Must be non-negative and less than the" + + " size of the collection."); + + // avoid integer overflow (with large pos/neg start_index values) + if (value.Length - 8 < startIndex) + throw new ArgumentException ("Destination array is not long" + + " enough to copy all the items in the collection." + + " Check array index and length."); + + p [0] = value [startIndex + 4]; + p [1] = value [startIndex + 5]; + p [2] = value [startIndex + 6]; + p [3] = value [startIndex + 7]; + p [4] = value [startIndex + 0]; + p [5] = value [startIndex + 1]; + p [6] = value [startIndex + 2]; + p [7] = value [startIndex + 3]; + + return ret; + } + + PutBytes ((byte *) &ret, value, startIndex, 8); + + return ret; + } + + public static string ToString (byte[] value) { + if (value == null) + throw new ArgumentNullException ("value"); + + return ToString (value, 0, value.Length); + } + + public static string ToString (byte[] value, int startIndex) { + if (value == null) + throw new ArgumentNullException ("value"); + + return ToString (value, startIndex, value.Length - startIndex); + } + + public static string ToString (byte[] value, int startIndex, int length) { + if (value == null) + throw new ArgumentNullException ("byteArray"); + + // The 4th and last clause (start_index >= value.Length) + // was added as a small fix to a very obscure bug. + // It makes a small difference when start_index is + // outside the range and length==0. + if (startIndex < 0 || startIndex >= value.Length) { + // special (but valid) case (e.g. new byte [0]) + if ((startIndex == 0) && (value.Length == 0)) + return String.Empty; + throw new ArgumentOutOfRangeException ("startIndex", "Index was" + + " out of range. Must be non-negative and less than the" + + " size of the collection."); + } + + if (length < 0) + throw new ArgumentOutOfRangeException ("length", + "Value must be positive."); + + // note: re-ordered to avoid possible integer overflow + if (startIndex > value.Length - length) + throw new ArgumentException ("startIndex + length > value.Length"); + + if (length == 0) + return string.Empty; + + StringBuilder builder = new StringBuilder(length * 3 - 1); + int end = startIndex + length; + + for (int i = startIndex; i < end; i++) { + if (i > startIndex) + builder.Append('-'); + + char high = (char)((value[i] >> 4) & 0x0f); + char low = (char)(value[i] & 0x0f); + + if (high < 10) + high += '0'; + else { + high -= (char) 10; + high += 'A'; + } + + if (low < 10) + low += '0'; + else { + low -= (char) 10; + low += 'A'; + } + builder.Append(high); + builder.Append(low); + } + + return builder.ToString (); } } } - -#endif diff --git a/src/DNA/corlib/System/Boolean.cs b/src/DNA/corlib/System/Boolean.cs index 56edc562..520481ad 100644 --- a/src/DNA/corlib/System/Boolean.cs +++ b/src/DNA/corlib/System/Boolean.cs @@ -26,11 +26,11 @@ public struct Boolean : IComparable, IComparable, IEquatable { public static readonly string TrueString = "True"; public static readonly string FalseString = "False"; -#pragma warning disable 0649 - internal bool m_value; -#pragma warning disable 0649 +#pragma warning disable 0169, 0649 + internal bool m_value; +#pragma warning restore 0169, 0649 - public override string ToString() { + public override string ToString() { return this.m_value ? TrueString : FalseString; } diff --git a/src/DNA/corlib/System/Char.cs b/src/DNA/corlib/System/Char.cs index cfab4af3..562d2970 100644 --- a/src/DNA/corlib/System/Char.cs +++ b/src/DNA/corlib/System/Char.cs @@ -38,11 +38,11 @@ public struct Char : IComparable, IComparable, IEquatable { (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B, (char) 0x3000, (char) 0xFEFF }; -#pragma warning disable 0649 - internal char m_value; -#pragma warning restore 0649 +#pragma warning disable 0169, 0649 + internal char m_value; +#pragma warning restore 0169, 0649 - public override string ToString() { + public override string ToString() { return new string(m_value, 1); } diff --git a/src/DNA/corlib/System/Comparison.cs b/src/DNA/corlib/System/Comparison.cs new file mode 100644 index 00000000..a250305b --- /dev/null +++ b/src/DNA/corlib/System/Comparison.cs @@ -0,0 +1,4 @@ +namespace System +{ + public delegate int Comparison (T x, T y); +} \ No newline at end of file diff --git a/src/DNA/corlib/System/Console.cs b/src/DNA/corlib/System/Console.cs index 51150152..007fa4e8 100644 --- a/src/DNA/corlib/System/Console.cs +++ b/src/DNA/corlib/System/Console.cs @@ -45,6 +45,25 @@ public static class Console { [MethodImpl(MethodImplOptions.InternalCall)] extern private static bool Internal_KeyAvailable(); + sealed class InternalTextWriter : IO.TextWriter { + public override System.Text.Encoding Encoding { + get { + return System.Text.Encoding.Default; + } + } + + public override void Write(string s) { + Console.Write(s); + } + public override void Write(char value) { + Console.Write(value.ToString()); + } + } + + public static IO.TextWriter Error { get; } = new InternalTextWriter(); + + public static IO.TextWriter Out { get; } = new InternalTextWriter(); + #region Write Methods public static void Write(object value) { diff --git a/src/DNA/corlib/System/Converter.cs b/src/DNA/corlib/System/Converter.cs index fd598288..1e6233d1 100644 --- a/src/DNA/corlib/System/Converter.cs +++ b/src/DNA/corlib/System/Converter.cs @@ -22,6 +22,34 @@ namespace System { public delegate TOutput Converter(TInput input); + + public class Convert + { + public static int ToInt32(string str, int fromBase) + { + int res = 0; + if (fromBase == 2) + { + for(int i = 0; i < str.Length; ++i) + { + var s = str[i]; + if ((char)s == '0') + { + res <<= 1; + } + else + { + res <<= 1; + res += 1; + } + } + + return res; + } + + return res; + } + } } #endif diff --git a/src/DNA/corlib/System/Double.cs b/src/DNA/corlib/System/Double.cs index 97b13714..df64eacb 100644 --- a/src/DNA/corlib/System/Double.cs +++ b/src/DNA/corlib/System/Double.cs @@ -31,7 +31,9 @@ public struct Double : IFormattable, IComparable, IComparable, IEquatabl public const double NegativeInfinity = -1.0d / 0.0d; public const double PositiveInfinity = 1.0d / 0.0d; +#pragma warning disable 0169, 0649 internal double m_value; +#pragma warning restore 0169, 0649 public static bool IsNaN(double d) { #pragma warning disable 1718 @@ -61,9 +63,9 @@ public override bool Equals(object o) { return ((double)o) == this.m_value; } - public override unsafe int GetHashCode() { + public override int GetHashCode() { double d = m_value; - return (*((long*)&d)).GetHashCode(); + return BitConverter.DoubleToInt64Bits(d).GetHashCode(); } public override string ToString() { @@ -122,6 +124,63 @@ public bool Equals(double x) { #endregion + #region Parsing + + public static bool TryParse(String s, out double result) + { + return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result); + } + + public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out double result) + { + // NumberFormatInfo.ValidateParseStyleFloatingPoint(style); + return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result); + } + + private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out double result) + { + if (s == null) + { + result = 0; + return false; + } + + result = s.ToDouble(); // returns zero on parsing error + + String sTrim = s.Trim(); + bool isZero = true; + int len = sTrim.Length; + for (int i = 0; i < len; i++) { + var c = sTrim[i]; + if (c != '0' || c != '.') { + isZero = false; + break; + } + } + bool success = (result != 0.0) || isZero; + //bool success = Number.TryParseDouble(s, style, info, out result); + if (!success) + { + if (sTrim.Equals(info.PositiveInfinitySymbol)) + { + result = PositiveInfinity; + } + else if (sTrim.Equals(info.NegativeInfinitySymbol)) + { + result = NegativeInfinity; + } + else if (sTrim.Equals(info.NaNSymbol)) + { + result = NaN; + } + else + return false; // We really failed + } + return true; + } + + #endregion + } } diff --git a/src/DNA/corlib/System/Int32.cs b/src/DNA/corlib/System/Int32.cs index 428d19b3..37ce12fb 100644 --- a/src/DNA/corlib/System/Int32.cs +++ b/src/DNA/corlib/System/Int32.cs @@ -9,7 +9,9 @@ public struct Int32 : IFormattable, IComparable, IComparable,IEquatable, IEquatable 0; + _decPointPos = 0; - if (double.IsNaN(value) || double.IsInfinity(value)) { - _NaN = double.IsNaN(value); - _infinity = double.IsInfinity(value); - _positive = value > 0; - _decPointPos = 0; + if (_NaN || _infinity) return; - } else { - _NaN = _infinity = false; - } long bits = BitConverter.DoubleToInt64Bits(value); _positive = (bits >= 0); @@ -1583,7 +1580,7 @@ public NumberStore(double value) { if (e == 0) { e++; - } else if (e != 0) { + } else { m |= (1L << 52); } @@ -1610,13 +1607,13 @@ public NumberStore(double value) { if (e >= 0) { for (int i = 0; i < e; i++) { - if (MultiplyBy(ref temp, ref length, 2)) { + if (MultiplyBy(temp, ref length, 2)) { _decPointPos++; } } } else { for (int i = 0; i < -e; i++) { - if (MultiplyBy(ref temp, ref length, 5)) { + if (MultiplyBy(temp, ref length, 5)) { _decPointPos++; } } @@ -1641,20 +1638,19 @@ public NumberStore(double value) { RoundEffectiveDigits(17, true, true); } + public NumberStore(float value) { - _digits = null; + _digits = new byte[] {}; _defByteSize = 32; _defPrecision = 7; _defMaxPrecision = _defPrecision + 2; + _NaN = float.IsNaN(value); + _infinity = float.IsInfinity(value); + _positive = value > 0; + _decPointPos = 0; - if (float.IsNaN(value) || float.IsInfinity(value)) { - _NaN = float.IsNaN(value); - _infinity = float.IsInfinity(value); - _positive = value > 0; - _decPointPos = 0; + if (_NaN || _infinity) return; - } else - _infinity = _NaN = false; long bits = BitConverter.DoubleToInt64Bits(value); _positive = (bits >= 0); @@ -1670,7 +1666,7 @@ public NumberStore(float value) { if (e == 0) { e++; - } else if (e != 0) { + } else { m |= (1L << 52); } @@ -1697,13 +1693,13 @@ public NumberStore(float value) { if (e >= 0) { for (int i = 0; i < e; i++) { - if (MultiplyBy(ref temp, ref length, 2)) { + if (MultiplyBy(temp, ref length, 2)) { _decPointPos++; } } } else { for (int i = 0; i < -e; i++) { - if (MultiplyBy(ref temp, ref length, 5)) { + if (MultiplyBy(temp, ref length, 5)) { _decPointPos++; } } @@ -1729,7 +1725,7 @@ public NumberStore(float value) { RoundEffectiveDigits(9, true, true); } - internal bool MultiplyBy(ref byte[] buffer, ref int length, int amount) { + internal bool MultiplyBy(byte[] buffer, ref int length, int amount) { int mod = 0; int ret; int start = buffer.Length - length - 1; diff --git a/src/DNA/corlib/System/OperationCanceledException.cs b/src/DNA/corlib/System/OperationCanceledException.cs index 8101be69..e4d49ae7 100644 --- a/src/DNA/corlib/System/OperationCanceledException.cs +++ b/src/DNA/corlib/System/OperationCanceledException.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Text; -namespace System -{ - public class OperationCanceledException : Exception - { +namespace System { + public class OperationCanceledException : Exception { + public OperationCanceledException(String message) + : base(message) { } } } diff --git a/src/DNA/corlib/System/RuntimeType.cs b/src/DNA/corlib/System/RuntimeType.cs index 06b19fae..6d7d5470 100644 --- a/src/DNA/corlib/System/RuntimeType.cs +++ b/src/DNA/corlib/System/RuntimeType.cs @@ -20,13 +20,14 @@ #if !LOCALTEST +using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Collections.Generic; namespace System { - class RuntimeType : Type { + sealed class RuntimeType : Type { [MethodImpl(MethodImplOptions.InternalCall)] extern private RuntimeType GetNestingParentType(); @@ -93,10 +94,29 @@ public override Type GetGenericTypeDefinition() { [MethodImpl(MethodImplOptions.InternalCall)] extern public override Type[] GetGenericArguments(); - [MethodImpl(MethodImplOptions.InternalCall)] - extern public override Type GetElementType(); + [MethodImpl(MethodImplOptions.InternalCall)] + extern public override bool IsDefined(Type attributeType, bool inherit); + + public override Object[] GetCustomAttributes(bool inherit) + { + return Internal_GetCustomAttributes(null, inherit); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException(); + + return Internal_GetCustomAttributes(attributeType, inherit); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + extern private Object[] Internal_GetCustomAttributes(Type attributeType, bool inherit); + + [MethodImpl(MethodImplOptions.InternalCall)] + extern public override Type GetElementType(); - } + } } diff --git a/src/DNA/corlib/System/SerializableAttribute.cs b/src/DNA/corlib/System/SerializableAttribute.cs new file mode 100644 index 00000000..99b8cbcb --- /dev/null +++ b/src/DNA/corlib/System/SerializableAttribute.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2012 DotNetAnywhere +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !LOCALTEST + +namespace System { + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)] + public sealed class SerializableAttribute : Attribute { + } + +} + +#endif \ No newline at end of file diff --git a/src/DNA/corlib/System/Single.cs b/src/DNA/corlib/System/Single.cs index 919d78e9..152deb8a 100644 --- a/src/DNA/corlib/System/Single.cs +++ b/src/DNA/corlib/System/Single.cs @@ -31,7 +31,9 @@ public struct Single : IFormattable, IComparable, IComparable, IEquatable public const float PositiveInfinity = 1.0f / 0.0f; public const float NegativeInfinity = -1.0f / 0.0f; +#pragma warning disable 0169, 0649 private float m_value; +#pragma warning restore 0169, 0649 public static bool IsNaN(float f) { #pragma warning disable 1718 @@ -61,9 +63,9 @@ public override bool Equals(object o) { return ((float)o).m_value == this.m_value; } - public unsafe override int GetHashCode() { + public override int GetHashCode() { float f = this.m_value; - return (*((int*)&f)).GetHashCode(); + return BitConverter.DoubleToInt64Bits(f).GetHashCode(); } public override string ToString() { diff --git a/src/DNA/corlib/System/String.cs b/src/DNA/corlib/System/String.cs index b0c1efa5..46fa585b 100644 --- a/src/DNA/corlib/System/String.cs +++ b/src/DNA/corlib/System/String.cs @@ -85,14 +85,31 @@ extern virtual public char this[int index] { #region Misc Methods - public static string Join(string separator, string[] value) { - return Join(separator, value, 0, value.Length); + public char[] ToCharArray () { + char[] tmp = new char [length]; + for (int i = 0; i < tmp.Length; i++) { + tmp[i] = this[i]; + } + return tmp; + } + + public static string Join(string separator, T[] values) { + return Join(separator, values, 0, values.Length); } - public static string Join(string separator, string[] value, int startIndex, int count) { + public static string Join(string separator, T[] values, int startIndex, int count) { StringBuilder sb = new StringBuilder(); for (int i = startIndex; i < count; i++) { - sb.Append(value[i]); + sb.Append(values[i]); + sb.Append(separator); + } + return sb.ToString(0, sb.Length - separator.Length); + } + + public static string Join(string separator, IEnumerable values) { + StringBuilder sb = new StringBuilder(); + foreach(var v in values) { + sb.Append(v); sb.Append(separator); } return sb.ToString(0, sb.Length - separator.Length); @@ -606,6 +623,13 @@ IEnumerator IEnumerable.GetEnumerator() { } #endregion + + #region IEquatable Members + + [MethodImpl(MethodImplOptions.InternalCall)] + extern public double ToDouble(); + + #endregion } } #endif diff --git a/src/DNA/corlib/System/Tuple.cs b/src/DNA/corlib/System/Tuple.cs new file mode 100644 index 00000000..ac5c2427 --- /dev/null +++ b/src/DNA/corlib/System/Tuple.cs @@ -0,0 +1,820 @@ +// +// Tuples.cs +// +// Authors: +// Zoltan Varga (vargaz@gmail.com) +// Marek Safar (marek.safar@gmail.com) +// +// Copyright (C) 2009 Novell +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System { + public static class Tuple { + public static Tuple> Create + ( + T1 item1, + T2 item2, + T3 item3, + T4 item4, + T5 item5, + T6 item6, + T7 item7, + T8 item8) { + return new Tuple>(item1, item2, item3, item4, item5, item6, item7, new Tuple(item8)); + } + + public static Tuple Create + ( + T1 item1, + T2 item2, + T3 item3, + T4 item4, + T5 item5, + T6 item6, + T7 item7) { + return new Tuple(item1, item2, item3, item4, item5, item6, item7); + } + + public static Tuple Create + ( + T1 item1, + T2 item2, + T3 item3, + T4 item4, + T5 item5, + T6 item6) { + return new Tuple(item1, item2, item3, item4, item5, item6); + } + + public static Tuple Create + ( + T1 item1, + T2 item2, + T3 item3, + T4 item4, + T5 item5) { + return new Tuple(item1, item2, item3, item4, item5); + } + + public static Tuple Create + ( + T1 item1, + T2 item2, + T3 item3, + T4 item4) { + return new Tuple(item1, item2, item3, item4); + } + + public static Tuple Create + ( + T1 item1, + T2 item2, + T3 item3) { + return new Tuple(item1, item2, item3); + } + + public static Tuple Create + ( + T1 item1, + T2 item2) { + return new Tuple(item1, item2); + } + + public static Tuple Create + ( + T1 item1) { + return new Tuple(item1); + } + } + + public partial class Tuple { + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + this.item5 = item5; + this.item6 = item6; + this.item7 = item7; + this.rest = rest; + + bool ok = true; + if (!typeof(TRest).IsGenericType) + ok = false; + if (ok) { + Type t = typeof(TRest).GetGenericTypeDefinition(); + if (!(t == typeof(Tuple<>) || t == typeof(Tuple<,>) || t == typeof(Tuple<,,>) || t == typeof(Tuple<,,,>) || t == typeof(Tuple<,,,,>) || t == typeof(Tuple<,,,,,>) || t == typeof(Tuple<,,,,,,>) || t == typeof(Tuple<,,,,,,,>))) + ok = false; + } + if (!ok) + throw new ArgumentException("rest", "The last element of an eight element tuple must be a Tuple."); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + + public Tuple(T1 item1) { + this.item1 = item1; + } + + public T1 Item1 { + get { return item1; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + return comparer.Compare(item1, t.item1); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + return comparer.GetHashCode(item1); + } + + public override string ToString() { + return String.Format("({0})", item1); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + + public Tuple(T1 item1, T2 item2) { + this.item1 = item1; + this.item2 = item2; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + return comparer.Compare(item2, t.item2); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1})", item1, item2); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + + public Tuple(T1 item1, T2 item2, T3 item3) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + return comparer.Compare(item3, t.item3); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2})", item1, item2, item3); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + T4 item4; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + public T4 Item4 { + get { return item4; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + res = comparer.Compare(item3, t.item3); + if (res != 0) return res; + return comparer.Compare(item4, t.item4); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3) && + comparer.Equals(item4, t.item4); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + h = (h << 5) - h + comparer.GetHashCode(item4); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2}, {3})", item1, item2, item3, item4); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + T4 item4; + T5 item5; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + this.item5 = item5; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + public T4 Item4 { + get { return item4; } + } + + public T5 Item5 { + get { return item5; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + res = comparer.Compare(item3, t.item3); + if (res != 0) return res; + res = comparer.Compare(item4, t.item4); + if (res != 0) return res; + return comparer.Compare(item5, t.item5); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3) && + comparer.Equals(item4, t.item4) && + comparer.Equals(item5, t.item5); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + h = (h << 5) - h + comparer.GetHashCode(item4); + h = (h << 5) - h + comparer.GetHashCode(item5); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2}, {3}, {4})", item1, item2, item3, item4, item5); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + T4 item4; + T5 item5; + T6 item6; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + this.item5 = item5; + this.item6 = item6; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + public T4 Item4 { + get { return item4; } + } + + public T5 Item5 { + get { return item5; } + } + + public T6 Item6 { + get { return item6; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + res = comparer.Compare(item3, t.item3); + if (res != 0) return res; + res = comparer.Compare(item4, t.item4); + if (res != 0) return res; + res = comparer.Compare(item5, t.item5); + if (res != 0) return res; + return comparer.Compare(item6, t.item6); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3) && + comparer.Equals(item4, t.item4) && + comparer.Equals(item5, t.item5) && + comparer.Equals(item6, t.item6); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + h = (h << 5) - h + comparer.GetHashCode(item4); + h = (h << 5) - h + comparer.GetHashCode(item5); + h = (h << 5) - h + comparer.GetHashCode(item6); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2}, {3}, {4}, {5})", item1, item2, item3, item4, item5, item6); + } + } + + [Serializable] + public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + T4 item4; + T5 item5; + T6 item6; + T7 item7; + + public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + this.item5 = item5; + this.item6 = item6; + this.item7 = item7; + } + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + public T4 Item4 { + get { return item4; } + } + + public T5 Item5 { + get { return item5; } + } + + public T6 Item6 { + get { return item6; } + } + + public T7 Item7 { + get { return item7; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + res = comparer.Compare(item3, t.item3); + if (res != 0) return res; + res = comparer.Compare(item4, t.item4); + if (res != 0) return res; + res = comparer.Compare(item5, t.item5); + if (res != 0) return res; + res = comparer.Compare(item6, t.item6); + if (res != 0) return res; + return comparer.Compare(item7, t.item7); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3) && + comparer.Equals(item4, t.item4) && + comparer.Equals(item5, t.item5) && + comparer.Equals(item6, t.item6) && + comparer.Equals(item7, t.item7); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + h = (h << 5) - h + comparer.GetHashCode(item4); + h = (h << 5) - h + comparer.GetHashCode(item5); + h = (h << 5) - h + comparer.GetHashCode(item6); + h = (h << 5) - h + comparer.GetHashCode(item7); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2}, {3}, {4}, {5}, {6})", item1, item2, item3, item4, item5, item6, item7); + } + } + + [Serializable] + public partial class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { + T1 item1; + T2 item2; + T3 item3; + T4 item4; + T5 item5; + T6 item6; + T7 item7; + TRest rest; + + public T1 Item1 { + get { return item1; } + } + + public T2 Item2 { + get { return item2; } + } + + public T3 Item3 { + get { return item3; } + } + + public T4 Item4 { + get { return item4; } + } + + public T5 Item5 { + get { return item5; } + } + + public T6 Item6 { + get { return item6; } + } + + public T7 Item7 { + get { return item7; } + } + + public TRest Rest { + get { return rest; } + } + + int IComparable.CompareTo(object obj) { + return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) { + var t = other as Tuple; + if (t == null) { + if (other == null) return 1; + throw new ArgumentException("other"); + } + + int res = comparer.Compare(item1, t.item1); + if (res != 0) return res; + res = comparer.Compare(item2, t.item2); + if (res != 0) return res; + res = comparer.Compare(item3, t.item3); + if (res != 0) return res; + res = comparer.Compare(item4, t.item4); + if (res != 0) return res; + res = comparer.Compare(item5, t.item5); + if (res != 0) return res; + res = comparer.Compare(item6, t.item6); + if (res != 0) return res; + res = comparer.Compare(item7, t.item7); + if (res != 0) return res; + return comparer.Compare(rest, t.rest); + } + + public override bool Equals(object obj) { + return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { + var t = other as Tuple; + if (t == null) + return false; + + return comparer.Equals(item1, t.item1) && + comparer.Equals(item2, t.item2) && + comparer.Equals(item3, t.item3) && + comparer.Equals(item4, t.item4) && + comparer.Equals(item5, t.item5) && + comparer.Equals(item6, t.item6) && + comparer.Equals(item7, t.item7) && + comparer.Equals(rest, t.rest); + } + + public override int GetHashCode() { + return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { + int h = comparer.GetHashCode(item1); + h = (h << 5) - h + comparer.GetHashCode(item2); + h = (h << 5) - h + comparer.GetHashCode(item3); + h = (h << 5) - h + comparer.GetHashCode(item4); + h = (h << 5) - h + comparer.GetHashCode(item5); + h = (h << 5) - h + comparer.GetHashCode(item6); + h = (h << 5) - h + comparer.GetHashCode(item7); + h = (h << 5) - h + comparer.GetHashCode(rest); + return h; + } + + public override string ToString() { + return String.Format("({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7})", item1, item2, item3, item4, item5, item6, item7, rest); + } + } +} diff --git a/src/DNA/corlib/System/Type.cs b/src/DNA/corlib/System/Type.cs index 2373708e..0171a697 100644 --- a/src/DNA/corlib/System/Type.cs +++ b/src/DNA/corlib/System/Type.cs @@ -30,55 +30,71 @@ public abstract class Type : MemberInfo { private static IDictionary typesByNameCache = new Dictionary(); - public static readonly Type[] EmptyTypes = new Type[0]; + public static readonly Type[] EmptyTypes = new Type[0]; - [MethodImpl(MethodImplOptions.InternalCall)] - extern public static Type GetTypeFromHandle(RuntimeTypeHandle handle); + [MethodImpl(MethodImplOptions.InternalCall)] + extern public static Type GetTypeFromHandle(RuntimeTypeHandle handle); - public abstract Type BaseType { - get; - } + public abstract Type BaseType { + get; + } - public abstract bool IsEnum { - get; - } + public abstract bool IsEnum { + get; + } - public abstract string Namespace { - get; - } + public abstract string Namespace { + get; + } - public abstract string FullName { - get; - } + public abstract string FullName { + get; + } - public abstract bool IsGenericType { - get; - } + public abstract bool IsGenericType { + get; + } - public abstract Type GetGenericTypeDefinition(); + public abstract Type GetGenericTypeDefinition(); - public abstract Type[] GetGenericArguments(); + public abstract Type[] GetGenericArguments(); public abstract Type GetElementType(); public virtual bool IsArray => GetElementType() != null; extern public bool IsValueType { - [MethodImpl(MethodImplOptions.InternalCall)] - get; - } + [MethodImpl(MethodImplOptions.InternalCall)] + get; + } - public override string ToString() { - return this.FullName; - } + public override string ToString() { + return this.FullName; + } - public static Type GetType(string typeName) - { - lock (typesByNameCache) - { + public virtual bool Equals (Type o) { + return Object.Equals(this, o); + } + + public virtual Type[] GenericTypeArguments { + get { + if (IsGenericType && !IsGenericTypeDefinition) { + return GetGenericArguments(); + } else { + return Type.EmptyTypes; + } + + } + } + + public virtual bool IsGenericTypeDefinition { + get { return false; } + } + + public static Type GetType(string typeName) { + lock (typesByNameCache) { Type cachedResult; - if (typesByNameCache.TryGetValue(typeName, out cachedResult)) - { + if (typesByNameCache.TryGetValue(typeName, out cachedResult)) { return cachedResult; } } @@ -86,15 +102,12 @@ public static Type GetType(string typeName) string assemblyName; string namespaceQualifiedTypeName; - if (typeName.IndexOf(',') > 0) - { + if (typeName.IndexOf(',') > 0) { // Assembly is specified var parts = typeName.Split(','); assemblyName = parts[1].Trim(); namespaceQualifiedTypeName = parts[0]; - } - else - { + } else { // No assembly specified assemblyName = null; namespaceQualifiedTypeName = typeName; @@ -105,10 +118,8 @@ public static Type GetType(string typeName) var className = namespaceQualifiedTypeName.Substring(namespaceSplitPoint + 1).Trim(); var result = GetType(assemblyName, namespaceName, className); - if (result != null) - { - lock (typesByNameCache) - { + if (result != null) { + lock (typesByNameCache) { typesByNameCache[typeName] = result; } } @@ -119,8 +130,10 @@ public static Type GetType(string typeName) [MethodImpl(MethodImplOptions.InternalCall)] extern public PropertyInfo[] GetProperties(); - public MethodInfo GetMethod(string name) - { + [MethodImpl(MethodImplOptions.InternalCall)] + extern public MethodInfo[] GetMethods(); + + public MethodInfo GetMethod(string name) { return (MethodInfo)GetMethodInternal(name); } diff --git a/src/DNA/corlib/System/UInt32.cs b/src/DNA/corlib/System/UInt32.cs index e52d155b..fdb9dad6 100644 --- a/src/DNA/corlib/System/UInt32.cs +++ b/src/DNA/corlib/System/UInt32.cs @@ -28,10 +28,10 @@ public struct UInt32 : IFormattable, IComparable, IComparable, IEquatable< public const uint MinValue = 0; #pragma warning disable 0169, 0649 - internal uint m_value; + internal uint m_value; #pragma warning restore 0169, 0649 - public override bool Equals(object obj) { + public override bool Equals(object obj) { return (obj is uint) && ((uint)obj).m_value == this.m_value; } diff --git a/src/DNA/native/src/ChangeLog.txt b/src/DNA/native/ChangeLog.txt similarity index 100% rename from src/DNA/native/src/ChangeLog.txt rename to src/DNA/native/ChangeLog.txt diff --git a/src/DNA/native/src/License.txt b/src/DNA/native/License.txt similarity index 100% rename from src/DNA/native/src/License.txt rename to src/DNA/native/License.txt diff --git a/src/DNA/native/System.Attribute.h b/src/DNA/native/System.Attribute.h deleted file mode 100644 index 83d20a1c..00000000 --- a/src/DNA/native/System.Attribute.h +++ /dev/null @@ -1,8 +0,0 @@ -#if !defined(__SYSTEM_ATTRIBUTE_H) -#define __SYSTEM_ATTRIBUTE_H - -typedef struct tSystemAttribute_ tSystemAttribute; -struct tSystemAttribute_ { -}; - -#endif \ No newline at end of file diff --git a/src/DNA/native/dna.vcxproj b/src/DNA/native/dna.vcxproj index ea656ecb..89f34ba4 100644 --- a/src/DNA/native/dna.vcxproj +++ b/src/DNA/native/dna.vcxproj @@ -192,7 +192,7 @@ Console true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ws2_32.lib;%(AdditionalDependencies) @@ -206,6 +206,7 @@ Console true + ws2_32.lib;%(AdditionalDependencies) @@ -223,6 +224,7 @@ true true true + ws2_32.lib;%(AdditionalDependencies) @@ -240,12 +242,10 @@ true true true + ws2_32.lib;%(AdditionalDependencies) - - - \ No newline at end of file diff --git a/src/DNA/native/dna.vcxproj.filters b/src/DNA/native/dna.vcxproj.filters deleted file mode 100644 index b0154b68..00000000 --- a/src/DNA/native/dna.vcxproj.filters +++ /dev/null @@ -1,309 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/src/DNA/native/js-interop.js b/src/DNA/native/js-interop.js index 037945a8..fb0fc8ef 100644 --- a/src/DNA/native/js-interop.js +++ b/src/DNA/native/js-interop.js @@ -18,15 +18,17 @@ mergeInto(LibraryManager.library, { funcName = Pointer_stringify(funcName); arg0 = Pointer_stringify(arg0); - if (!(libName in window)) { + var globalRef = ENVIRONMENT_IS_NODE ? global : window; + + if (!(libName in globalRef)) { throw new Error('No such library \'' + libName + '\''); } - if (!(funcName in window[libName])) { + if (!(funcName in globalRef[libName])) { throw new Error('No such function \'' + funcName + '\' on library \'' + libName + '\''); } - var result = window[libName][funcName](arg0); + var result = globalRef[libName][funcName](arg0); if (result !== null && result !== undefined) { var resultString = result.toString(); var resultPtr = allocate(intArrayFromString(resultString), 'i8', ALLOC_NORMAL); diff --git a/src/DNA/native/src/CIL_OpCodes.h b/src/DNA/native/src/CIL_OpCodes.h index 9a79fb64..2a292443 100644 --- a/src/DNA/native/src/CIL_OpCodes.h +++ b/src/DNA/native/src/CIL_OpCodes.h @@ -20,6 +20,8 @@ #define CIL_NOP 0x00 +#define CIL_BREAK 0x01 + #define CIL_LDARG_0 0x02 #define CIL_LDARG_1 0x03 #define CIL_LDARG_2 0x04 @@ -103,6 +105,9 @@ #define CIL_STIND_I1 0x52 #define CIL_STIND_I2 0x53 #define CIL_STIND_I4 0x54 +#define CIL_STIND_I8 0x55 +#define CIL_STIND_R4 0x56 +#define CIL_STIND_R8 0x57 #define CIL_ADD 0x58 #define CIL_SUB 0x59 @@ -218,7 +223,12 @@ #define CILX_CLT 0x04 #define CILX_CLT_UN 0x05 #define CILX_LOADFUNCTION 0x06 +#define CILX_LOADVIRTFN 0x07 + +#define CILX_LDLOC 0x0c +#define CILX_STLOC 0x0e +#define CILX_TAIL 0x14 #define CILX_INITOBJ 0x15 #define CILX_CONSTRAINED 0x16 diff --git a/src/DNA/native/src/Generics.c b/src/DNA/native/src/Generics.c index 2ac5918e..725f2ffd 100644 --- a/src/DNA/native/src/Generics.c +++ b/src/DNA/native/src/Generics.c @@ -41,38 +41,46 @@ void Generic_GetHeapRoots(tHeapRoots *pHeapRoots, tMD_TypeDef *pTypeDef) { tMD_TypeDef* Generics_GetGenericTypeFromSig (tMetaData *pMetaData, SIG *pSig, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) { - tMD_TypeDef *pCoreType, *pRet; - U32 numTypeArgs, i; - tMD_TypeDef **ppTypeArgs; - pCoreType = Type_GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); - MetaData_Fill_TypeDef(pCoreType, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); //NULL, NULL); + tMD_TypeDef *pCoreType = Type_GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); + MetaData_Fill_TypeDef(pCoreType, NULL, NULL); - numTypeArgs = MetaData_DecodeSigEntry(pSig); - ppTypeArgs = (tMD_TypeDef**)malloc(numTypeArgs * sizeof(tMD_TypeDef*)); - for (i=0; ipMetaData, MAKE_TABLE_INDEX(MD_TABLE_GENERICPARAM, 1)); - - for (i=0; ipMetaData->tables.numRows[MD_TABLE_GENERICPARAM]; i++, pGenericParam++) { - if (pGenericParam->owner == pCoreType->tableIndex && pGenericParam->number == typeArgIndex) { - return pGenericParam; + U32 rows = pCoreType->pMetaData->tables.numRows[MD_TABLE_GENERICPARAM]; + tMD_GenericParam *pGenericParam = (tMD_GenericParam*)MetaData_GetTableRow(pCoreType->pMetaData, MAKE_TABLE_INDEX(MD_TABLE_GENERICPARAM, 1)); + IDX_TABLE value = pCoreType->tableIndex; + + // binary search in GenericParams table + int lo = 0; + int hi = rows - 1; + while (lo <= hi) { + int i = lo + ((hi - lo) >> 1); + if (pGenericParam[i].owner < value) { lo = i + 1; } + else { + if (pGenericParam[i].owner > value) { hi = i - 1; } + else { + while (pGenericParam[i].owner == value) { + if (pGenericParam[i].number < typeArgIndex) { ++i; } + else { + if (pGenericParam[i].number > typeArgIndex) { --i; } + else { return (pGenericParam + i); } + } + } + } } } return NULL; @@ -112,7 +120,7 @@ tMD_TypeDef* Generics_GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, U32 num memset(pTypeDef, 0, sizeof(tMD_TypeDef)); // Make the name of the instantiation. strcpy(name, pCoreType->name); - strcat(name, "["); + strcat(name, "<"); for (i=0; i 0) { strcat(name, ","); @@ -122,13 +130,13 @@ tMD_TypeDef* Generics_GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, U32 num } else { tMD_GenericParam *pGenericParam = FindGenericParam(pCoreType, i); if (pGenericParam != NULL) { - sprintf(strchr(name, 0), pGenericParam->name); + sprintf(strchr(name, 0), "%s", pGenericParam->name); } else { sprintf(strchr(name, 0), "???"); } } } - strcat(name, "]"); + strcat(name, ">"); // Fill in the basic bits of the new type def. pTypeDef->pTypeDef = pTypeDef; pTypeDef->pMetaData = pMetaData; @@ -143,6 +151,7 @@ tMD_TypeDef* Generics_GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, U32 num pTypeDef->nameSpace = pCoreType->nameSpace; pTypeDef->name = (STRING)mallocForever((U32)strlen(name)+1); strcpy(pTypeDef->name, name); + // dprintfn("Instantiated type %s.%s", pTypeDef->nameSpace, pTypeDef->name); pTypeDef->ppClassTypeArgs = pInst->pTypeArgs; pTypeDef->extends = pCoreType->extends; pTypeDef->tableIndex = pCoreType->tableIndex; @@ -163,25 +172,22 @@ tMD_MethodDef* Generics_GetMethodDefFromSpec (tMD_MethodSpec *pMethodSpec, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) { tMD_MethodDef *pCoreMethod, *pMethod; - SIG sig; - U32 argCount, i; - tMD_TypeDef **ppTypeArgs; - + pCoreMethod = MetaData_GetMethodDefFromDefRefOrSpec(pMethodSpec->pMetaData, pMethodSpec->method, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); + if (pCoreMethod->pParentType == NULL) { + pCoreMethod->pParentType = MetaData_GetTypeDefFromMethodDef(pCoreMethod); + } - //ppClassTypeArgs = pCoreMethod->pParentType->ppClassTypeArgs; - sig = MetaData_GetBlob(pMethodSpec->instantiation, NULL); + SIG sig = MetaData_GetBlob(pMethodSpec->instantiation, NULL); MetaData_DecodeSigEntry(&sig); // always 0x0a - argCount = MetaData_DecodeSigEntry(&sig); - ppTypeArgs = malloc(argCount * sizeof(tMD_TypeDef*)); - - for (i=0; ipMetaData, &sig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); + U32 argCount = MetaData_DecodeSigEntry(&sig); + tMD_TypeDef **ppTypeArgs = malloc(argCount * sizeof(tMD_TypeDef*)); + for (U32 i = 0; ipMetaData, &sig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); ppTypeArgs[i] = pArgType; } + //ppClassTypeArgs = pCoreMethod->pParentType->ppClassTypeArgs; pMethod = Generics_GetMethodDefFromCoreMethod(pCoreMethod, pCoreMethod->pParentType, argCount, ppTypeArgs); free(ppTypeArgs); diff --git a/src/DNA/native/src/Heap.c b/src/DNA/native/src/Heap.c index 8c31592e..2d41e3ac 100644 --- a/src/DNA/native/src/Heap.c +++ b/src/DNA/native/src/Heap.c @@ -72,6 +72,9 @@ struct tHeapEntry_ { // unused U8 padding; + // size in bytes + U32 byteSize; + // The type in this heap entry tMD_TypeDef *pTypeDef; @@ -305,7 +308,7 @@ static void GarbageCollect() { while (pNode != nil) { if (pMemRef < (void*)pNode) { pNode = pNode->pLink[0]; - } else if ((char*)pMemRef > ((char*)pNode) + GetSize(pNode) + sizeof(tHeapEntry)) { + } else if ((char*)pMemRef > ((char*)pNode) + pNode->byteSize) { pNode = pNode->pLink[1]; } else { // Found memory. See if it's already been marked. @@ -467,6 +470,7 @@ HEAP_PTR Heap_Alloc(tMD_TypeDef *pTypeDef, U32 size) { } pHeapEntry = (tHeapEntry*)malloc(totalSize); + pHeapEntry->byteSize = totalSize; pHeapEntry->pTypeDef = pTypeDef; pHeapEntry->pSync = NULL; pHeapEntry->needToFinalize = (pTypeDef->pFinalizer != NULL); diff --git a/src/DNA/native/src/InternalCall.c b/src/DNA/native/src/InternalCall.c index 44d19eed..120fb355 100644 --- a/src/DNA/native/src/InternalCall.c +++ b/src/DNA/native/src/InternalCall.c @@ -72,7 +72,8 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "GetHashCode", System_Object_GetHashCode, TYPE_SYSTEM_INT32, 0}, {NULL, NULL, "GetType", System_Object_GetType, TYPE_SYSTEM_TYPE, 0}, - {NULL, "String", ".ctor", System_String_ctor_CharInt32, TYPE_SYSTEM_VOID, 2, {TYPE_SYSTEM_CHAR, TYPE_SYSTEM_INT32}}, + {NULL, "String", ".ctor", System_String_ctor_CharInt32, TYPE_SYSTEM_VOID, 2, { TYPE_SYSTEM_CHAR, TYPE_SYSTEM_INT32 } }, + {NULL, NULL, ".ctor", System_String_ctor_CharA, TYPE_SYSTEM_VOID, 1, { TYPE_SYSTEM_ARRAY_CHAR } }, {NULL, NULL, ".ctor", System_String_ctor_CharAIntInt, TYPE_SYSTEM_VOID, 3, {TYPE_SYSTEM_ARRAY_CHAR, TYPE_SYSTEM_INT32, TYPE_SYSTEM_INT32}}, {NULL, NULL, ".ctor", System_String_ctor_StringIntInt, TYPE_SYSTEM_VOID, 3, {TYPE_SYSTEM_STRING, TYPE_SYSTEM_INT32, TYPE_SYSTEM_INT32}}, {NULL, NULL, "get_Chars", System_String_get_Chars, TYPE_SYSTEM_CHAR, 1, {TYPE_SYSTEM_INT32}}, @@ -83,6 +84,7 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "InternalReplace", System_String_InternalReplace, TYPE_SYSTEM_STRING, 2, {TYPE_SYSTEM_STRING, TYPE_SYSTEM_STRING}}, {NULL, NULL, "InternalIndexOf", System_String_InternalIndexOf, TYPE_SYSTEM_INT32, 4, {TYPE_SYSTEM_CHAR, TYPE_SYSTEM_INT32, TYPE_SYSTEM_INT32, TYPE_SYSTEM_BOOLEAN}}, {NULL, NULL, "InternalIndexOfAny", System_String_InternalIndexOfAny, TYPE_SYSTEM_INT32, 4, {TYPE_SYSTEM_ARRAY_CHAR, TYPE_SYSTEM_INT32, TYPE_SYSTEM_INT32, TYPE_SYSTEM_BOOLEAN}}, + {NULL, NULL, "ToDouble", System_String_ToDouble, TYPE_SYSTEM_DOUBLE, 0}, {NULL, "Activator", "CreateInstance", Framework_JSInterop_Activator_CreateInstance, TYPE_SYSTEM_OBJECT, 1, {TYPE_SYSTEM_TYPE}}, @@ -106,6 +108,7 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "EnsureAssemblyLoaded", System_Type_EnsureAssemblyLoaded, TYPE_SYSTEM_VOID, 1, {TYPE_SYSTEM_STRING}}, {NULL, NULL, "GetMethodInternal", System_Type_GetMethod, TYPE_SYSTEM_OBJECT, 1, {TYPE_SYSTEM_STRING}}, {NULL, NULL, "GetProperties", System_Type_GetProperties, TYPE_SYSTEM_ARRAY_NO_TYPE, 0}, + {NULL, NULL, "GetMethods", System_Type_GetMethods, TYPE_SYSTEM_ARRAY_NO_TYPE, 0}, {NULL, NULL, "GetType", System_Type_GetTypeFromName, TYPE_SYSTEM_TYPE, 3, {TYPE_SYSTEM_STRING, TYPE_SYSTEM_STRING, TYPE_SYSTEM_STRING}}, {NULL, NULL, "get_IsValueType", System_Type_get_IsValueType, TYPE_SYSTEM_BOOLEAN, 0}, @@ -117,6 +120,8 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "get_IsGenericType", System_RuntimeType_get_IsGenericType, TYPE_SYSTEM_BOOLEAN, 0}, {NULL, NULL, "Internal_GetGenericTypeDefinition", System_RuntimeType_Internal_GetGenericTypeDefinition, TYPE_SYSTEM_RUNTIMETYPE, 0}, {NULL, NULL, "GetGenericArguments", System_RuntimeType_GetGenericArguments, TYPE_SYSTEM_ARRAY_TYPE, 0}, + {NULL, NULL, "IsDefined", System_RuntimeType_IsDefined, TYPE_SYSTEM_BOOLEAN, 2, {TYPE_SYSTEM_TYPE, TYPE_SYSTEM_BOOLEAN}}, + {NULL, NULL, "Internal_GetCustomAttributes", System_RuntimeType_GetCustomAttributes, TYPE_SYSTEM_ARRAY_OBJECT, 2, {TYPE_SYSTEM_TYPE, TYPE_SYSTEM_BOOLEAN}}, {NULL, NULL, "GetElementType", System_RuntimeType_GetElementType, TYPE_SYSTEM_TYPE, 0}, {NULL, "Char", "GetUnicodeCategory", System_Char_GetUnicodeCategory, TYPE_SYSTEM_GLOBALIZATION_UNICODECATEGORY, 1, {TYPE_SYSTEM_CHAR}}, @@ -142,7 +147,10 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "Cos", System_Math_Cos, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, {NULL, NULL, "Tan", System_Math_Tan, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, {NULL, NULL, "Pow", System_Math_Pow, TYPE_SYSTEM_DOUBLE, 2, {TYPE_SYSTEM_DOUBLE, TYPE_SYSTEM_DOUBLE}}, - {NULL, NULL, "Sqrt", System_Math_Sqrt, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, + {NULL, NULL, "Sqrt", System_Math_Sqrt, TYPE_SYSTEM_DOUBLE, 1, { TYPE_SYSTEM_DOUBLE}}, + {NULL, NULL, "Ceiling", System_Math_Ceiling, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, + {NULL, NULL, "Floor", System_Math_Floor, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, + {NULL, NULL, "Round", System_Math_Round, TYPE_SYSTEM_DOUBLE, 1, {TYPE_SYSTEM_DOUBLE}}, {"System.Reflection", "MemberInfo", "GetCustomAttributes", Reflection_MemberInfo_GetCustomAttributes, TYPE_SYSTEM_ARRAY_NO_TYPE, 0}, @@ -168,6 +176,8 @@ static tInternalCall internalCalls[] = { {NULL, NULL, "GetFileAttributes", System_IO_FileInternal_GetFileAttributes, TYPE_SYSTEM_IO_FILESYSTEMATTRIBUTES, 2, {TYPE_SYSTEM_STRING, TYPE_SYSTEM_INTPTR}}, {NULL, NULL, "GetFileSystemEntries", System_IO_FileInternal_GetFileSystemEntries, TYPE_SYSTEM_ARRAY_STRING, 5, {TYPE_SYSTEM_STRING, TYPE_SYSTEM_STRING, TYPE_SYSTEM_IO_FILESYSTEMATTRIBUTES, TYPE_SYSTEM_IO_FILESYSTEMATTRIBUTES, TYPE_SYSTEM_INTPTR}}, + {"System.Reflection", "MethodInfo", "MakeGenericMethod", System_Reflection_MethodInfo_MakeGenericMethod, TYPE_SYSTEM_REFLECTION_METHODINFO, 1, {TYPE_SYSTEM_ARRAY_TYPE}}, + {"System.Runtime.CompilerServices", "RuntimeHelpers", "InitializeArray", System_Runtime_CompilerServices_InitializeArray, TYPE_SYSTEM_VOID, 2, {TYPE_SYSTEM_ARRAY_NO_TYPE, TYPE_SYSTEM_RUNTIMEFIELDHANDLE}}, {"System.Diagnostics", "Debugger", "Break", System_Diagnostics_Debugger_Break, TYPE_SYSTEM_VOID, 0}, @@ -218,6 +228,6 @@ fnInternalCall InternalCall_Map(tMD_MethodDef *pMethod) { } } - Crash("InternalCall_Map(): Cannot map [%s]%s.%s", pMethod->pParentType->nameSpace, pMethod->pParentType->name, pMethod->name); + Crash("InternalCall_Map(): Cannot map %s.%s.%s", pMethod->pParentType->nameSpace, pMethod->pParentType->name, pMethod->name); FAKE_RETURN; } diff --git a/src/DNA/native/src/JIT.c b/src/DNA/native/src/JIT.c index 083bcfd1..123be473 100644 --- a/src/DNA/native/src/JIT.c +++ b/src/DNA/native/src/JIT.c @@ -94,7 +94,7 @@ static U32 Translate(U32 op, U32 getDynamic) { #define PushFloat(v) convFloat.f=(float)(v); PushU32_(&ops, convFloat.u32, -1) #define PushDouble(v) convDouble.d=(double)(v); PushU32_(&ops, convDouble.u32.a, -1); PushU32_(&ops, convDouble.u32.b, -1) #define PushPTR(ptr) PushU32_(&ops, (U32)(ptr), -1) -#define PushOp(op) PushU32_(&ops, Translate((U32)(op), 0), nextOpSequencePoint) +#define PushOp(op) PushU32_(&ops, Translate((U32)(op), 0), nextOpSequencePoint); //dprintfn("PushOp: 0x%03x (%s)", op, Sys_JIT_OpCodeName(op)); #define PushOpParam(op, param) PushOp(op); PushU32_(&ops, (U32)(param), -1) #endif @@ -121,13 +121,13 @@ static void PushStackType_(tTypeStack *pTypeStack, tMD_TypeDef *pType) { if (size > pTypeStack->maxBytes) { pTypeStack->maxBytes = size; } - //printf("Stack ofs = %d; Max stack size: %d (0x%x)\n", pTypeStack->ofs, size, size); + //dprintfn("Stack ofs = %d; Max stack size: %d (0x%x)", pTypeStack->ofs, size, size); } static void PushU32_(tOps *pOps, U32 v, I32 opSequencePoint) { if (pOps->ofs >= pOps->capacity) { pOps->capacity <<= 1; -// printf("a.pOps->p = 0x%08x size=%d\n", pOps->p, pOps->capacity * sizeof(U32)); + //dprintfn("a.pOps->p = 0x%08x size=%d", pOps->p, pOps->capacity * sizeof(U32)); pOps->p = realloc(pOps->p, pOps->capacity * sizeof(U32)); pOps->pSequencePoints = realloc(pOps->pSequencePoints, pOps->capacity * sizeof(U32)); } @@ -135,6 +135,13 @@ static void PushU32_(tOps *pOps, U32 v, I32 opSequencePoint) { pOps->p[pOps->ofs++] = v; } +static U32 GetUnalignedU16(U8 *pCIL, U32 *pCILOfs) { + U32 a, b; + a = pCIL[(*pCILOfs)++]; + b = pCIL[(*pCILOfs)++]; + return a | (b << 8); +} + static U32 GetUnalignedU32(U8 *pCIL, U32 *pCILOfs) { U32 a,b,c,d; a = pCIL[(*pCILOfs)++]; @@ -336,6 +343,8 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter op = pCIL[cilOfs++]; //printf("Opcode: 0x%02x\n", op); + //U32 op2 = (op == CIL_EXTENDED) ? 0x100 + pCIL[cilOfs] : op; + //dprintfn("CIL op: 0x%03x (%s)", op2, Sys_CIL_OpCodeName(op2)); if (pDebugMetadataEntry != NULL && sequencePointIndex < pDebugMetadataEntry->sequencePointsCount) { U32 spOffset = pDebugMetadataEntry->sequencePoints[sequencePointIndex]; if (spOffset == pcilOfs) { @@ -352,6 +361,9 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter PushOp(JIT_NOP); } break; + case CIL_BREAK: + Crash("Break-point requested."); + break; case CIL_LDNULL: PushOp(JIT_LOAD_NULL); @@ -582,6 +594,9 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter case CIL_STIND_I1: case CIL_STIND_I2: case CIL_STIND_I4: + case CIL_STIND_I8: + case CIL_STIND_R4: + case CIL_STIND_R8: PopStackTypeMulti(2); // Don't care what they are PushOp(JIT_STOREINDIRECT_REF + (op - CIL_STIND_REF)); break; @@ -596,7 +611,7 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter { tMD_MethodDef *pCallMethod; tMD_TypeDef *pBoxCallType; - U32 derefRefType; + U32 derefRefType = 0; U8 dynamicallyBoxReturnValue = 0; u32Value2 = 0; @@ -604,6 +619,7 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter cilCallVirtConstrained: pBoxCallType = NULL; derefRefType = 0; + dynamicallyBoxReturnValue = 0; u32Value = GetUnalignedU32(pCIL, &cilOfs); pCallMethod = MetaData_GetMethodDefFromDefRefOrSpec(pMetaData, u32Value, pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs); @@ -655,7 +671,7 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter // Pop stack type for each argument. Don't actually care what these are, // except the last one which will be the 'this' object type of a non-static method - //printf("Call %s() - popping %d stack args\n", pCallMethod->name, pCallMethod->numberOfParameters); + //dprintfn("Call %s() - popping %d stack args", pCallMethod->name, pCallMethod->numberOfParameters); for (i=0; inumberOfParameters; i++) { pStackType = PopStackType(); } @@ -753,17 +769,21 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter case CIL_BRFALSE_S: case CIL_BRTRUE_S: u32Value = (I8)pCIL[cilOfs++]; - u32Value2 = JIT_BRANCH_FALSE + (op - CIL_BRFALSE_S); + u32Value2 = (op - CIL_BRFALSE_S); goto cilBrFalseTrue; case CIL_BRFALSE: case CIL_BRTRUE: u32Value = GetUnalignedU32(pCIL, &cilOfs); - u32Value2 = JIT_BRANCH_FALSE + (op - CIL_BRFALSE); + u32Value2 = (op - CIL_BRFALSE); cilBrFalseTrue: - PopStackTypeDontCare(); // Don't care what it is + pStackType = PopStackType(); + if (pStackType->stackSize > 8) { + Crash("JITit(): Cannot perform branch operation on type: %s", pStackType->name); + } // Put a temporary CIL offset value into the JITted code. This will be updated later u32Value = cilOfs + (I32)u32Value; + u32Value2 = (pStackType->stackSize == 4 ? JIT_BRANCH_FALSE : JIT_BRANCH64_FALSE) + u32Value2; MayCopyTypeStack(); PushOp(u32Value2); PushBranch(); @@ -801,8 +821,7 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter pTypeA = PopStackType(); u32Value = cilOfs + (I32)u32Value; MayCopyTypeStack(); - if ((pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32) || - (pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_O)) { + if (pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32) { PushOp(JIT_BEQ_I32I32 + (op - u32Value2)); } else if (pTypeA->stackType == EVALSTACK_INT64 && pTypeB->stackType == EVALSTACK_INT64) { PushOp(JIT_BEQ_I64I64 + (op - u32Value2)); @@ -810,6 +829,10 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter PushOp(JIT_BEQ_F32F32 + (op - u32Value2)); } else if (pTypeA->stackType == EVALSTACK_F64 && pTypeB->stackType == EVALSTACK_F64) { PushOp(JIT_BEQ_F64F64 + (op - u32Value2)); + } else if (pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_O) { + //pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_INT32 || + //pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_O) { + PushOp(JIT_BEQ_I32I32 + (op - u32Value2)); } else { Crash("JITit(): Cannot perform conditional branch on stack types: %d and %d", pTypeA->stackType, pTypeB->stackType); } @@ -839,21 +862,24 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter cilBinaryArithOp: pTypeB = PopStackType(); pTypeA = PopStackType(); - if (pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32) { + if ((pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32)) { PushOp(JIT_ADD_I32I32 + (op - CIL_ADD) - u32Value); - PushStackType(types[TYPE_SYSTEM_INT32]); } else if (pTypeA->stackType == EVALSTACK_INT64 && pTypeB->stackType == EVALSTACK_INT64) { PushOp(JIT_ADD_I64I64 + (op - CIL_ADD) - u32Value); - PushStackType(types[TYPE_SYSTEM_INT64]); } else if (pTypeA->stackType == EVALSTACK_F32 && pTypeB->stackType == EVALSTACK_F32) { PushOp(JIT_ADD_F32F32 + (op - CIL_ADD) - u32Value); - PushStackType(pTypeA); } else if (pTypeA->stackType == EVALSTACK_F64 && pTypeB->stackType == EVALSTACK_F64) { PushOp(JIT_ADD_F64F64 + (op - CIL_ADD) - u32Value); - PushStackType(pTypeA); + } else if (pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_O) { + //pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_INT32 || + //pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_O) { + PushOp(JIT_ADD_I32I32 + (op - CIL_ADD) - u32Value); + } else if (pTypeA->stackType == EVALSTACK_PTR && pTypeB->stackType == EVALSTACK_INT32 && (op == CIL_ADD || op == CIL_SUB)) { + PushOp((sizeof(void*) == 4 ? JIT_ADD_I32I32 : JIT_ADD_I64I64) + (op - CIL_ADD)); } else { Crash("JITit(): Cannot perform binary numeric operand on stack types: %d and %d", pTypeA->stackType, pTypeB->stackType); } + PushStackType(pTypeA); break; case CIL_NEG: @@ -865,6 +891,12 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter } else if (pTypeA->stackType == EVALSTACK_INT64) { PushOp(JIT_NEG_I64 + (op - CIL_NEG)); PushStackType(types[TYPE_SYSTEM_INT64]); + } else if (pTypeA->stackType == EVALSTACK_F32) { + PushOp(JIT_NEG_F32); + PushStackType(types[TYPE_SYSTEM_SINGLE]); + } else if (pTypeA->stackType == EVALSTACK_F64) { + PushOp(JIT_NEG_F64); + PushStackType(types[TYPE_SYSTEM_DOUBLE]); } else { Crash("JITit(): Cannot perform unary operand on stack types: %d", pTypeA->stackType); } @@ -1470,7 +1502,8 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter break; case CILX_LOADFUNCTION: - { + case CILX_LOADVIRTFN: + { tMD_MethodDef *pFuncMethodDef; u32Value = GetUnalignedU32(pCIL, &cilOfs); @@ -1488,10 +1521,7 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter case CILX_CLT_UN: pTypeB = PopStackType(); pTypeA = PopStackType(); - if ((pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32) || - (pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_O) || - // Next line: only on 32-bit - (pTypeA->stackType == EVALSTACK_PTR && pTypeB->stackType == EVALSTACK_PTR)) { + if (pTypeA->stackType == EVALSTACK_INT32 && pTypeB->stackType == EVALSTACK_INT32) { PushOp(JIT_CEQ_I32I32 + (op - CILX_CEQ)); } else if (pTypeA->stackType == EVALSTACK_INT64 && pTypeB->stackType == EVALSTACK_INT64) { PushOp(JIT_CEQ_I64I64 + (op - CILX_CEQ)); @@ -1499,12 +1529,24 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter PushOp(JIT_CEQ_F32F32 + (op - CILX_CEQ)); } else if (pTypeA->stackType == EVALSTACK_F64 && pTypeB->stackType == EVALSTACK_F64) { PushOp(JIT_CEQ_F64F64 + (op - CILX_CEQ)); + } else if (pTypeA->stackType == EVALSTACK_O && pTypeB->stackType == EVALSTACK_O) { + PushOp(JIT_CEQ_I32I32 + (op - CILX_CEQ)); + } else if (pTypeA->stackType == EVALSTACK_PTR && pTypeB->stackType == EVALSTACK_PTR) { + PushOp((sizeof(void*) == 4 ? JIT_CEQ_I32I32 : JIT_CEQ_I64I64) + (op - CILX_CEQ)); } else { Crash("JITit(): Cannot perform comparison operand on stack types: %s and %s", pTypeA->name, pTypeB->name); } PushStackType(types[TYPE_SYSTEM_INT32]); break; - + + case CILX_LDLOC: + u32Value = GetUnalignedU16(pCIL, &cilOfs); + goto cilLdLoc; + + case CILX_STLOC: + u32Value = GetUnalignedU16(pCIL, &cilOfs); + goto cilStLoc; + case CILX_RETHROW: PushOp(JIT_RETHROW); break; @@ -1518,6 +1560,10 @@ static U32* JITit(tMD_MethodDef *pMethodDef, U8 *pCIL, U32 codeSize, tParameter // Do nothing break; + case CILX_TAIL: + // Do nothing. TODO: implement + break; + default: Crash("JITit(): JITter cannot handle extended op-code:0x%02x", op); diff --git a/src/DNA/native/src/JIT_Execute.c b/src/DNA/native/src/JIT_Execute.c index cddd4a29..6dc1b434 100644 --- a/src/DNA/native/src/JIT_Execute.c +++ b/src/DNA/native/src/JIT_Execute.c @@ -44,59 +44,62 @@ tJITCodeInfo jitCodeInfo[JIT_OPCODE_MAXNUM]; tJITCodeInfo jitCodeGoNext; // Get the next op-code -#define GET_OP() *(pCurOp++) +#define GET_OP() (*(pCurOp++)) +//#define GET_OP() (dprintfn("GETOP : stackOfs = %d", (U32)(pCurEvalStack - pCurrentMethodState->pEvalStack)), *(pCurOp++)) + +// PUSH/POP returns nothing - it just alters the stack offset correctly +#define PUSH(numBytes) (pCurEvalStack += numBytes) //, dprintfn("PUSH %d: stackOfs = %d", numBytes, (U32)(pCurEvalStack - pCurrentMethodState->pEvalStack)), pCurEvalStack) +#define POP(numBytes) (pCurEvalStack -= numBytes) //, dprintfn("POP %d: stackOfs = %d", numBytes, (U32)(pCurEvalStack - pCurrentMethodState->pEvalStack)), pCurEvalStack) // Push a PTR value on the top of the stack -#define PUSH_PTR(ptr) *(PTR*)pCurEvalStack = (PTR)(ptr); pCurEvalStack += sizeof(void*) +#define PUSH_PTR(ptr) *(PTR*)pCurEvalStack = (PTR)(ptr); PUSH(sizeof(void*)) // Push an arbitrarily-sized value-type onto the top of the stack -#define PUSH_VALUETYPE(ptr, valueSize, stackInc) memcpy(pCurEvalStack, ptr, valueSize); pCurEvalStack += stackInc +#define PUSH_VALUETYPE(ptr, valueSize, stackInc) memcpy(pCurEvalStack, ptr, valueSize); PUSH(stackInc) // Push a U32 value on the top of the stack -#define PUSH_U32(value) *(U32*)pCurEvalStack = (U32)(value); pCurEvalStack += 4 +#define PUSH_U32(value) *(U32*)pCurEvalStack = (U32)(value); PUSH(4) // Push a U64 value on the top of the stack -#define PUSH_U64(value) *(U64*)pCurEvalStack = (U64)(value); pCurEvalStack += 8 +#define PUSH_U64(value) *(U64*)pCurEvalStack = (U64)(value); PUSH(8) // Push a float value on the top of the stack -#define PUSH_FLOAT(value) *(float*)pCurEvalStack = (float)(value); pCurEvalStack += 4; +#define PUSH_FLOAT(value) *(float*)pCurEvalStack = (float)(value); PUSH(4) // Push a double value on the top of the stack -#define PUSH_DOUBLE(value) *(double*)pCurEvalStack = (double)(value); pCurEvalStack += 8; +#define PUSH_DOUBLE(value) *(double*)pCurEvalStack = (double)(value); PUSH(8) // Push a 4-byte heap pointer on to the top of the stack -#define PUSH_O(pHeap) *(void**)pCurEvalStack = (void*)(pHeap); pCurEvalStack += sizeof(void*) +#define PUSH_O(pHeap) *(HEAP_PTR*)pCurEvalStack = (HEAP_PTR)(pHeap); PUSH(4) // DUP4() duplicates the top 4 bytes on the eval stack -#define DUP4() *(U32*)pCurEvalStack = *(U32*)(pCurEvalStack - 4); pCurEvalStack += 4 +#define DUP4() *(U32*)pCurEvalStack = *(U32*)(pCurEvalStack - 4); PUSH(4) // DUP8() duplicates the top 4 bytes on the eval stack -#define DUP8() *(U64*)pCurEvalStack = *(U64*)(pCurEvalStack - 8); pCurEvalStack += 8 +#define DUP8() *(U64*)pCurEvalStack = *(U64*)(pCurEvalStack - 8); PUSH(8) // DUP() duplicates numBytes bytes from the top of the stack -#define DUP(numBytes) memcpy(pCurEvalStack, pCurEvalStack - numBytes, numBytes); pCurEvalStack += numBytes +#define DUP(numBytes) memcpy(pCurEvalStack, pCurEvalStack - numBytes, numBytes); PUSH(numBytes) // Pop a U32 value from the stack -#define POP_U32() (*(U32*)(pCurEvalStack -= 4)) +#define POP_U32() (*(U32*)(POP(4))) // Pop a U64 value from the stack -#define POP_U64() (*(U64*)(pCurEvalStack -= 8)) +#define POP_U64() (*(U64*)(POP(8))) // Pop a float value from the stack -#define POP_FLOAT() (*(float*)(pCurEvalStack -= 4)) +#define POP_FLOAT() (*(float*)(POP(4))) // Pop a double value from the stack -#define POP_DOUBLE() (*(double*)(pCurEvalStack -= 8)) +#define POP_DOUBLE() (*(double*)(POP(8))) // Pop 2 U32's from the stack -#define POP_U32_U32(v1,v2) pCurEvalStack -= 8; v1 = *(U32*)pCurEvalStack; v2 = *(U32*)(pCurEvalStack + 4) +#define POP_U32_U32(v1,v2) POP(8); v1 = *(U32*)pCurEvalStack; v2 = *(U32*)(pCurEvalStack + 4) // Pop 2 U64's from the stack -#define POP_U64_U64(v1,v2) pCurEvalStack -= 16; v1 = *(U64*)pCurEvalStack; v2 = *(U64*)(pCurEvalStack + 8) +#define POP_U64_U64(v1,v2) POP(16); v1 = *(U64*)pCurEvalStack; v2 = *(U64*)(pCurEvalStack + 8) // Pop 2 F32's from the stack -#define POP_F32_F32(v1,v2) pCurEvalStack -= 8; v1 = *(float*)pCurEvalStack; v2 = *(float*)(pCurEvalStack + 4) +#define POP_F32_F32(v1,v2) POP(8); v1 = *(float*)pCurEvalStack; v2 = *(float*)(pCurEvalStack + 4) // Pop 2 F64's from the stack -#define POP_F64_F64(v1,v2) pCurEvalStack -= 16; v1 = *(double*)pCurEvalStack; v2 = *(double*)(pCurEvalStack + 8) +#define POP_F64_F64(v1,v2) POP(16); v1 = *(double*)pCurEvalStack; v2 = *(double*)(pCurEvalStack + 8) // Pop a PTR value from the stack -#define POP_PTR() (*(PTR*)(pCurEvalStack -= sizeof(void*))) +#define POP_PTR() (*(PTR*)(POP(sizeof(void*)))) // Pop an arbitrarily-sized value-type from the stack (copies it to the specified memory location) -#define POP_VALUETYPE(ptr, valueSize, stackDec) memcpy(ptr, pCurEvalStack -= stackDec, valueSize) +#define POP_VALUETYPE(ptr, valueSize, stackDec) memcpy(ptr, POP(stackDec), valueSize) // Pop a Object (heap) pointer value from the stack -#define POP_O() (*(HEAP_PTR*)(pCurEvalStack -= 4)) -// POP() returns nothing - it just alters the stack offset correctly -#define POP(numBytes) pCurEvalStack -= numBytes +#define POP_O() (*(HEAP_PTR*)(POP(4))) // POP_ALL() empties the evaluation stack #define POP_ALL() pCurEvalStack = pCurrentMethodState->pEvalStack #define STACK_ADDR(type) *(type*)(pCurEvalStack - sizeof(type)) // General binary ops #define BINARY_OP(returnType, type1, type2, op) \ - pCurEvalStack -= sizeof(type1) + sizeof(type2) - sizeof(returnType); \ + POP(sizeof(type1) + sizeof(type2) - sizeof(returnType)); \ *(returnType*)(pCurEvalStack - sizeof(returnType)) = \ *(type1*)(pCurEvalStack - sizeof(returnType)) op \ *(type2*)(pCurEvalStack - sizeof(returnType) + sizeof(type1)) @@ -106,7 +109,7 @@ tJITCodeInfo jitCodeGoNext; // Set the new method state (for use when the method state changes - in calls mainly) #define SAVE_METHOD_STATE() \ pCurrentMethodState->stackOfs = (U32)(pCurEvalStack - pCurrentMethodState->pEvalStack); \ - pCurrentMethodState->ipOffset = (U32)(pCurOp - pOps) + pCurrentMethodState->ipOffset = (U32)(pCurOp - pOps); \ #define LOAD_METHOD_STATE() \ pCurrentMethodState = pThread->pCurrentMethodState; \ @@ -115,7 +118,7 @@ tJITCodeInfo jitCodeGoNext; pJIT = pCurrentMethodState->pJIT; \ pOps = pJIT->pOps; \ pOpSequencePoints = pJIT->pOpSequencePoints; \ - pCurOp = pOps + pCurrentMethodState->ipOffset + pCurOp = pOps + pCurrentMethodState->ipOffset; #define CHANGE_METHOD_STATE(pNewMethodState) \ SAVE_METHOD_STATE(); \ @@ -190,7 +193,7 @@ U32 opcodeNumUses[JIT_OPCODE_MAXNUM]; #else -#define OPCODE_USE(op) +#define OPCODE_USE(op) //dprintfn("JIT op: 0x%03x (%s)", op, Sys_JIT_OpCodeName(op)) #endif @@ -437,6 +440,8 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { GET_LABELS_DYNAMIC(JIT_NOT_I32, 0); GET_LABELS_DYNAMIC(JIT_NEG_I64, 0); GET_LABELS_DYNAMIC(JIT_NOT_I64, 0); + GET_LABELS_DYNAMIC(JIT_NEG_F32, 0); + GET_LABELS_DYNAMIC(JIT_NEG_F64, 0); GET_LABELS(JIT_BOX_NULLABLE); GET_LABELS_DYNAMIC(JIT_LOAD_F64, 8); @@ -485,6 +490,11 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { GET_LABELS(JIT_BLE_UN_I32I32); GET_LABELS(JIT_BLT_UN_I32I32); + GET_LABELS(JIT_BGE_UN_I64I64); + GET_LABELS(JIT_BGT_UN_I64I64); + GET_LABELS(JIT_BLE_UN_I64I64); + GET_LABELS(JIT_BLT_UN_I64I64); + GET_LABELS_DYNAMIC(JIT_SHL_I32, 0); GET_LABELS_DYNAMIC(JIT_SHR_I32, 0); GET_LABELS_DYNAMIC(JIT_SHR_UN_I32, 0); @@ -494,6 +504,8 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { GET_LABELS(JIT_BRANCH_FALSE); GET_LABELS(JIT_BRANCH_TRUE); + GET_LABELS(JIT_BRANCH64_FALSE); + GET_LABELS(JIT_BRANCH64_TRUE); GET_LABELS(JIT_LOADTOKEN_TYPE); GET_LABELS(JIT_LOADTOKEN_FIELD); @@ -512,6 +524,9 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { GET_LABELS(JIT_STOREINDIRECT_U8); GET_LABELS(JIT_STOREINDIRECT_U16); GET_LABELS(JIT_STOREINDIRECT_U32); + GET_LABELS(JIT_STOREINDIRECT_U64); + GET_LABELS(JIT_STOREINDIRECT_R32); + GET_LABELS(JIT_STOREINDIRECT_R64); GET_LABELS_DYNAMIC(JIT_CONV_I32_I32, 4); GET_LABELS_DYNAMIC(JIT_CONV_I32_U32, 4); @@ -950,6 +965,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_STOREINDIRECT_U16_start: JIT_STOREINDIRECT_U32_start: JIT_STOREINDIRECT_REF_start: +JIT_STOREINDIRECT_R32_start: OPCODE_USE(JIT_STOREINDIRECT_U32); { U32 value = POP_U32(); // The value to store @@ -960,6 +976,19 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_STOREINDIRECT_U16_end: JIT_STOREINDIRECT_U32_end: JIT_STOREINDIRECT_REF_end: +JIT_STOREINDIRECT_R32_end: + GO_NEXT(); + +JIT_STOREINDIRECT_U64_start: +JIT_STOREINDIRECT_R64_start: + OPCODE_USE(JIT_STOREINDIRECT_U64); + { + U64 value = POP_U64(); // Value + PTR pMem = POP_PTR(); // The address to store to + *(U64*)pMem = value; + } +JIT_STOREINDIRECT_U64_end: +JIT_STOREINDIRECT_R64_end: GO_NEXT(); JIT_STORE_OBJECT_VALUETYPE_start: @@ -1026,7 +1055,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_RETURN_start: OPCODE_USE(JIT_RETURN); - //printf("Returned from %s() to %s()\n", pCurrentMethodState->pMethod->name, (pCurrentMethodState->pCaller)?pCurrentMethodState->pCaller->pMethod->name:""); + // dprintfn("Returned from %s() to %s()", pCurrentMethodState->pMethod->name, (pCurrentMethodState->pCaller)?pCurrentMethodState->pCaller->pMethod->name:(STRING)""); if (pCurrentMethodState->pCaller == NULL) { // End of thread! if (pCurrentMethodState->pMethod->pReturnType == types[TYPE_SYSTEM_INT32]) { @@ -1051,7 +1080,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { // Copy return value to callers evaluation stack if (u32Value > 0) { memmove(pCurEvalStack, pMem, u32Value); - pCurEvalStack += u32Value; + PUSH(u32Value); } // Delete the current method state and go back to callers method state MethodState_Delete(pThread, &pOldMethodState); @@ -1076,7 +1105,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { pDelegateMethod = (tMD_MethodDef*)GET_OP(); // Take the params off the stack. This is the pointer to the tDelegate & params //pCurrentMethodState->stackOfs -= pDelegateMethod->parameterStackSize; - pCurEvalStack -= pDelegateMethod->parameterStackSize; + POP(pDelegateMethod->parameterStackSize); // Allocate memory for delegate params pCurrentMethodState->pDelegateParams = malloc(pDelegateMethod->parameterStackSize - sizeof(void*)); memcpy( @@ -1089,7 +1118,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { } else { pDelegateMethod = Delegate_GetMethod(pCurrentMethodState->pNextDelegate); if (pDelegateMethod->pReturnType != NULL) { - pCurEvalStack -= pDelegateMethod->pReturnType->stackSize; + POP(pDelegateMethod->pReturnType->stackSize); } // Get the actual delegate heap pointer pDelegate = pCurrentMethodState->pNextDelegate; @@ -1122,7 +1151,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { tMD_MethodDef *pInvokeMethod = (tMD_MethodDef*)GET_OP(); // Take the MethodBase.Invoke params off the stack. - pCurEvalStack -= pInvokeMethod->parameterStackSize; + POP(pInvokeMethod->parameterStackSize); // Get a pointer to the MethodBase instance (e.g., a MethodInfo or ConstructorInfo), // and from that, determine which method we're going to invoke @@ -1134,30 +1163,22 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { pCurrentMethodState->pReflectionInvokeReturnType = pCallMethod->pReturnType; // Get the 'this' pointer for the call and the params array - PTR invocationThis = (PTR)(*(tMethodBase**)(pCurEvalStack + sizeof(HEAP_PTR))); - HEAP_PTR invocationParamsArray = *(HEAP_PTR*)(pCurEvalStack + sizeof(HEAP_PTR) + sizeof(PTR)); + PTR invocationThis = *(PTR*)(pCurEvalStack + sizeof(HEAP_PTR)); + HEAP_PTR invocationParamsArray = *(HEAP_PTR*)(pCurEvalStack + sizeof(HEAP_PTR) + sizeof(PTR)); // Put the new 'this' on the stack PTR pPrevEvalStack = pCurEvalStack; - PUSH_PTR(invocationThis); + if (invocationThis != NULL) { + PUSH_PTR(invocationThis); + } // Put any other params on the stack if (invocationParamsArray != NULL) { U32 invocationParamsArrayLength = SystemArray_GetLength(invocationParamsArray); - PTR invocationParamsArrayElements = SystemArray_GetElements(invocationParamsArray); + HEAP_PTR* invocationParamsArrayElements = (HEAP_PTR*)SystemArray_GetElements(invocationParamsArray); for (U32 paramIndex = 0; paramIndex < invocationParamsArrayLength; paramIndex++) { - HEAP_PTR currentParam = (HEAP_PTR)(((U32*)(invocationParamsArrayElements))[paramIndex]); - if (currentParam == NULL) { - PUSH_O(NULL); - } else { - tMD_TypeDef *currentParamType = Heap_GetType(currentParam); - - if (Type_IsValueType(currentParamType)) { - PUSH_VALUETYPE(currentParam, currentParamType->stackSize, currentParamType->stackSize); - } else { - PUSH_O(currentParam); - } - } + HEAP_PTR currentParam = invocationParamsArrayElements[paramIndex]; + PUSH_O(currentParam); } } pCurEvalStack = pPrevEvalStack; @@ -1208,7 +1229,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_CALL_INTERFACE_start: op = JIT_CALL_INTERFACE; allCallStart: - OPCODE_USE(JIT_CALL_O); + OPCODE_USE(op); { tMD_MethodDef *pCallMethod; tMethodState *pCallMethodState; @@ -1219,6 +1240,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { } pCallMethod = (tMD_MethodDef*)GET_OP(); + //dprintfn("Calling method: %s", Sys_GetMethodDesc(pCallMethod)); heapPtr = NULL; if (op == JIT_BOX_CALLVIRT) { @@ -1246,36 +1268,35 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { pThisType = Heap_GetType(heapPtr); if (METHOD_ISVIRTUAL(pCallMethod)) { pCallMethod = pThisType->pVTable[pCallMethod->vTableOfs]; + //dprintfn("Calling virtual method: %s", pCallMethod->name); } } else if (op == JIT_CALL_INTERFACE) { tMD_TypeDef *pInterface, *pThisType; - U32 vIndex; - I32 i; - pInterface = pCallMethod->pParentType; // Get the actual object that is becoming 'this' heapPtr = *(HEAP_PTR*)(pCurEvalStack - pCallMethod->parameterStackSize); pThisType = Heap_GetType(heapPtr); + // Find the interface mapping on the 'this' type. - vIndex = 0xffffffff; // This must be searched backwards so if an interface is implemented more than // once in the type hierarchy, the most recent definition gets called - for (i=(I32)pThisType->numInterfaces-1; i >= 0; i--) { + for (I32 i=(I32)pThisType->numInterfaces-1; i >= 0; i--) { if (pThisType->pInterfaceMaps[i].pInterface == pInterface) { // Found the right interface map if (pThisType->pInterfaceMaps[i].pVTableLookup != NULL) { - vIndex = pThisType->pInterfaceMaps[i].pVTableLookup[pCallMethod->vTableOfs]; - break; + U32 vIndex = pThisType->pInterfaceMaps[i].pVTableLookup[pCallMethod->vTableOfs]; + pCallMethod = pThisType->pVTable[vIndex]; + } else { + pCallMethod = pThisType->pInterfaceMaps[i].ppMethodVLookup[pCallMethod->vTableOfs]; } - pCallMethod = pThisType->pInterfaceMaps[i].ppMethodVLookup[pCallMethod->vTableOfs]; + //dprintfn("Calling interface method: %s", pCallMethod->name); goto callMethodSet; } } - Assert(vIndex != 0xffffffff); - pCallMethod = pThisType->pVTable[vIndex]; + Crash("%s.%s is missing interface method: %s", pThisType->nameSpace, pThisType->name, Sys_GetMethodDesc(pCallMethod)); + //dprintfn("Calling interface method: %s", pCallMethod->name); } callMethodSet: - //printf("Calling method: %s\n", Sys_GetMethodDesc(pCallMethod)); // Set up the new method state for the called method pCallMethodState = MethodState_Direct(pThread, pCallMethod, pCurrentMethodState, 0); // Set up the parameter stack for the method being called @@ -1345,6 +1366,30 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_BRANCH_FALSE_end: GO_NEXT_CHECK(); +JIT_BRANCH64_TRUE_start: + OPCODE_USE(JIT_BRANCH64_TRUE); + { + U64 value = POP_U64(); + U32 ofs = GET_OP(); + if (value != 0) { + pCurOp = pOps + ofs; + } + } +JIT_BRANCH64_TRUE_end: + GO_NEXT_CHECK(); + +JIT_BRANCH64_FALSE_start: + OPCODE_USE(JIT_BRANCH64_FALSE); + { + U64 value = POP_U64(); + U32 ofs = GET_OP(); + if (value == 0) { + pCurOp = pOps + ofs; + } + } +JIT_BRANCH64_FALSE_end: + GO_NEXT_CHECK(); + JIT_BEQ_I32I32_start: OPCODE_USE(JIT_BEQ_I32I32); { @@ -1746,6 +1791,60 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_BLT_UN_I32I32_end: GO_NEXT_CHECK(); + +JIT_BGE_UN_I64I64_start: + OPCODE_USE(JIT_BGE_UN_I64I64); + { + U64 v1, v2, ofs; + POP_U64_U64(v1, v2); + ofs = GET_OP(); + if (v1 >= v2) { + pCurOp = pOps + ofs; + } + } +JIT_BGE_UN_I64I64_end: + GO_NEXT_CHECK(); + +JIT_BGT_UN_I64I64_start: + OPCODE_USE(JIT_BGT_UN_I64I64); + { + U64 v1, v2, ofs; + POP_U64_U64(v1, v2); + ofs = GET_OP(); + if (v1 > v2) { + pCurOp = pOps + ofs; + } + } +JIT_BGT_UN_I64I64_end: + GO_NEXT_CHECK(); + +JIT_BLE_UN_I64I64_start: + OPCODE_USE(JIT_BLE_UN_I64I64); + { + U64 v1, v2, ofs; + POP_U64_U64(v1, v2); + ofs = GET_OP(); + if (v1 <= v2) { + pCurOp = pOps + ofs; + } + } +JIT_BLE_UN_I64I64_end: + GO_NEXT_CHECK(); + +JIT_BLT_UN_I64I64_start: + OPCODE_USE(JIT_BLT_UN_I64I64); + { + U64 v1, v2, ofs; + POP_U64_U64(v1, v2); + ofs = GET_OP(); + if (v1 < v2) { + pCurOp = pOps + ofs; + } + } +JIT_BLT_UN_I64I64_end: + GO_NEXT_CHECK(); + + JIT_CEQ_I32I32_start: // Handles I32 and O OPCODE_USE(JIT_CEQ_I32I32); BINARY_OP(U32, U32, U32, ==); @@ -2118,6 +2217,18 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { JIT_NEG_I64_end: GO_NEXT(); +JIT_NEG_F32_start: + OPCODE_USE(JIT_NEG_F32); + UNARY_OP(float, -); +JIT_NEG_F32_end: + GO_NEXT(); + +JIT_NEG_F64_start: + OPCODE_USE(JIT_NEG_F64); + UNARY_OP(double, -); +JIT_NEG_F64_end: + GO_NEXT(); + JIT_NOT_I32_start: OPCODE_USE(JIT_NOT_I32); UNARY_OP(U32, ~); @@ -2507,7 +2618,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { CreateParameters(pCallMethodState->pParamsLocals, pConstructorDef, &pTempPtr, pMem); pCurEvalStack = pTempPtr; // Set the stack state so it's correct for the constructor return - pCurEvalStack += pConstructorDef->pParentType->stackSize; + PUSH(pConstructorDef->pParentType->stackSize); // Set up the local variables for the new method state CHANGE_METHOD_STATE(pCallMethodState); // Run any pending Finalizers @@ -2667,7 +2778,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { U32 size = GET_OP(); // size of type on stack *(U32*)pCurEvalStack = 0; // This is required to zero out the stack for types that are stored in <4 bytes in arrays SystemArray_LoadElement(heapPtr, idx, pCurEvalStack); - pCurEvalStack += size; + PUSH(size); } JIT_LOAD_ELEMENT_end: GO_NEXT(); @@ -2771,7 +2882,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { PTR pMem; pFieldDef = (tMD_FieldDef*)GET_OP(); - pCurEvalStack -= pFieldDef->memSize; + POP(pFieldDef->memSize); pMem = pCurEvalStack; heapPtr = POP_O(); memcpy(heapPtr + pFieldDef->memOffset, pMem, pFieldDef->memSize); @@ -2818,7 +2929,7 @@ U32 JIT_Execute(tThread *pThread, U32 numInst) { // My guess is that at some point they refactored from using 'pEvalStack' to 'pCurEvalStack', but // didn't update this method (because nothing in corlib reads fields from structs). // I think the following line moves the stack pointer along correctly instead: - pCurEvalStack -= u32Value; + POP(u32Value); //pMem = pEvalStack + pCurrentMethodState->stackOfs + pFieldDef->memOffset; pMem = pCurEvalStack + pFieldDef->memOffset; @@ -3042,7 +3153,7 @@ OPCODE_USE(JIT_BOX_INT64); tMD_TypeDef *pType = (tMD_TypeDef*)GET_OP(); // Take the nullable type off the stack. The +4 is because the of the HasValue field (Bool, size = 4 bytes) - pCurEvalStack -= pType->stackSize + 4; + POP(pType->stackSize + 4); // If .HasValue if (*(U32*)pCurEvalStack) { // Box the underlying type @@ -3081,7 +3192,7 @@ OPCODE_USE(JIT_BOX_INT64); PUSH_U32(0); // And increase the stack pointer by the size of the underlying type // (the contents don't matter) - pCurEvalStack += pTypeDef->stackSize; + PUSH(pTypeDef->stackSize); } else { // Push .HasValue (= true) PUSH_U32(1); @@ -3202,6 +3313,7 @@ OPCODE_USE(JIT_BOX_INT64); // Set the IP to the catch handler pCurrentMethodState->ipOffset = pThread->pCatchExceptionHandler->handlerStart; // Set the current method state + pThread->pCurrentMethodState = pCurrentMethodState; LOAD_METHOD_STATE(); // Push onto this stack-frame's evaluation stack the opject thrown POP_ALL(); diff --git a/src/DNA/native/src/JIT_OpCodes.h b/src/DNA/native/src/JIT_OpCodes.h index 82b3cb22..7ee1e348 100644 --- a/src/DNA/native/src/JIT_OpCodes.h +++ b/src/DNA/native/src/JIT_OpCodes.h @@ -140,7 +140,7 @@ #define JIT_LOADSTATICFIELD_O (JIT_LOADSTATICFIELD_TYPEID + EVALSTACK_O) //#define JIT_LOADSTATICFIELD_TRANSPTR (JIT_LOADSTATICFIELD_TYPEID + EVALSTACK_TRANSPTR) #define JIT_LOADSTATICFIELD_F64 (JIT_LOADSTATICFIELD_TYPEID + EVALSTACK_F64) -#define JIT_LOADSTATICFIELD_VALUEPTYE (JIT_LOADSTATICFIELD_TYPEID + EVALSTACK_VALUETYPE) +#define JIT_LOADSTATICFIELD_VALUETYPE (JIT_LOADSTATICFIELD_TYPEID + EVALSTACK_VALUETYPE) #define JIT_STORESTATICFIELD_TYPEID 0x60 #define JIT_STORESTATICFIELD_INT64 (JIT_STORESTATICFIELD_TYPEID + EVALSTACK_INT64) @@ -199,9 +199,8 @@ #define JIT_NOT_I32 0x8b #define JIT_NEG_I64 0x8c #define JIT_NOT_I64 0x8d - -#define JIT_BOX_NULLABLE 0x8e -#define JIT_LOAD_F64 0x8f +#define JIT_NEG_F32 0x8e +#define JIT_NEG_F64 0x8f #define JIT_BEQ_I32I32 0x90 #define JIT_BGE_I32I32 0x91 @@ -225,15 +224,20 @@ #define JIT_BLE_UN_I64I64 0xa2 #define JIT_BLT_UN_I64I64 0xa3 -#define JIT_SHL_I32 0xa8 -#define JIT_SHR_I32 0xa9 -#define JIT_SHR_UN_I32 0xaa -#define JIT_SHL_I64 0xab -#define JIT_SHR_I64 0xac -#define JIT_SHR_UN_I64 0xad +#define JIT_SHL_I32 0xa4 +#define JIT_SHR_I32 0xa5 +#define JIT_SHR_UN_I32 0xa6 +#define JIT_SHL_I64 0xa7 +#define JIT_SHR_I64 0xa8 +#define JIT_SHR_UN_I64 0xa9 + +#define JIT_BRANCH_FALSE 0xaa +#define JIT_BRANCH_TRUE 0xab +#define JIT_BRANCH64_FALSE 0xac +#define JIT_BRANCH64_TRUE 0xad -#define JIT_BRANCH_FALSE 0xae -#define JIT_BRANCH_TRUE 0xaf +#define JIT_BOX_NULLABLE 0xae +#define JIT_LOAD_F64 0xaf #define JIT_LOADTOKEN_BASE 0xb0 #define JIT_LOADTOKEN_TYPE (JIT_LOADTOKEN_BASE + 0) diff --git a/src/DNA/native/src/MetaData.c b/src/DNA/native/src/MetaData.c index 5684de2c..dad92e86 100644 --- a/src/DNA/native/src/MetaData.c +++ b/src/DNA/native/src/MetaData.c @@ -180,7 +180,7 @@ static char* tableDefs[] = { // 0x0F "ssxsi*\x02*", // 0x10 - NULL, + "i*\x04*", // 0x11 "B*", // 0x12 @@ -226,9 +226,9 @@ static char* tableDefs[] = { // 0x26 NULL, // 0x27 - NULL, + "i*i*S*S*9*", // 0x28 - NULL, + "i*i*S*9*", // 0x29 "\x02*\x02*", // 0x2A @@ -248,7 +248,7 @@ static unsigned char* codedTags[] = { // HasConstant "\x04\x08\x17z", // HasCustomAttribute - "\x06\x04\x01\x02\x08\x09\x0A\x00\x0E\x17\x14\x11\x1A\x1B\x20\x23\x26\x27\x28zzzzzzzzzzzzz", + "\x06\x04\x01\x02\x08\x09\x0A\x00\x0E\x17\x14\x11\x1A\x1B\x20\x23\x26\x27\x28\x2A\x2C\x2Bzzzzzzzzzz", // HasFieldMarshall "\x04\x08", // HasDeclSecurity @@ -391,7 +391,7 @@ static void* LoadSingleTable(tMetaData *pThis, tRVA *pRVA, int tableID, void **p unsigned char tag = *pSource & ((1 << tagBits) - 1); int idxIntoTableID = pCoding[tag]; // The actual table index that we're looking for if (idxIntoTableID < 0 || idxIntoTableID > MAX_TABLES) { - printf("Error: Bad table index: 0x%02x\n", idxIntoTableID); + printf("Error: tableID=%02x, row=%d, i=%d, d=%c, tag=%d : Bad table index: 0x%02x\n", tableID, row, i, d, tag, idxIntoTableID); exit(1); } if (pThis->tables.codedIndex32Bit[ofs]) { diff --git a/src/DNA/native/src/MetaData.h b/src/DNA/native/src/MetaData.h index d59dd511..662b0290 100644 --- a/src/DNA/native/src/MetaData.h +++ b/src/DNA/native/src/MetaData.h @@ -109,8 +109,19 @@ struct tMetaData_ { #define FIELDATTRIBUTES_LITERAL 0x40 // compile-time constant #define FIELDATTRIBUTES_HASFIELDRVA 0x100 -#define SIG_METHODDEF_GENERIC 0x10 -#define SIG_METHODDEF_HASTHIS 0x20 +#define SIG_CALLCONV_DEFAULT 0x0 +#define SIG_CALLCONV_VARARG 0x5 +#define SIG_CALLCONV_FIELD 0x6 +#define SIG_CALLCONV_LOCAL_SIG 0x7 +#define SIG_CALLCONV_PROPERTY 0x8 +#define SIG_CALLCONV_UNMGD 0x9 +#define SIG_CALLCONV_GENERICINST 0xa +#define SIG_CALLCONV_NATIVEVARARG 0xb +#define SIG_CALLCONV_MAX 0xc +#define SIG_CALLCONV_MASK 0x0f +#define SIG_CALLCONV_GENERIC 0x10 +#define SIG_CALLCONV_HASTHIS 0x20 +#define SIG_CALLCONV_EXPLICITTHIS 0x40 #define IMPLMAP_FLAGS_CHARSETMASK 0x0006 #define IMPLMAP_FLAGS_CHARSETNOTSPEC 0x0000 @@ -178,6 +189,9 @@ void MetaData_Fill_TypeDef_(tMD_TypeDef *pTypeDef, tMD_TypeDef **ppClassTypeArgs void MetaData_Fill_FieldDef(tMD_TypeDef *pParentType, tMD_FieldDef *pFieldDef, U32 memOffset, tMD_TypeDef **ppClassTypeArgs); void MetaData_Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs); +tMD_MethodDef* FindVirtualOverriddenMethod(tMD_TypeDef *pTypeDef, tMD_MethodDef *pMethodDef); +tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMetaData *pSigMetaData, BLOB_ sigBlob, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs); + // Meta-data searching U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaData, tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs, tMD_TypeDef **ppMethodMethodTypeArgs); diff --git a/src/DNA/native/src/MetaData_Fill.c b/src/DNA/native/src/MetaData_Fill.c index b09347ee..1f64e10a 100644 --- a/src/DNA/native/src/MetaData_Fill.c +++ b/src/DNA/native/src/MetaData_Fill.c @@ -95,7 +95,7 @@ void MetaData_Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef sig = MetaData_GetBlob(pMethodDef->signature, NULL); entry = MetaData_DecodeSigEntry(&sig); - if (entry & SIG_METHODDEF_GENERIC) { + if (entry & SIG_CALLCONV_GENERIC) { // Has generic parameters. Read how many, but don't care about the answer MetaData_DecodeSigEntry(&sig); } @@ -139,47 +139,6 @@ void MetaData_Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef pMethodDef->parameterStackSize = totalSize; } -// Find the method that has been overridden by pMethodDef. -// This is to get the correct vTable offset for the method. -// This must search the MethodImpl table to see if the default inheritence rules are being overridden. -// Return NULL if this method does not override anything. -static tMD_MethodDef* FindVirtualOverriddenMethod(tMD_TypeDef *pTypeDef, tMD_MethodDef *pMethodDef) { - U32 i; - - do { - // Search MethodImpl table - for (i=pTypeDef->pMetaData->tables.numRows[MD_TABLE_METHODIMPL]; i>0; i--) { - tMD_MethodImpl *pMethodImpl; - - pMethodImpl = (tMD_MethodImpl*)MetaData_GetTableRow(pTypeDef->pMetaData, MAKE_TABLE_INDEX(MD_TABLE_METHODIMPL, i)); - if (pMethodImpl->class_ == pTypeDef->tableIndex) { - tMD_MethodDef *pMethodDeclDef; - - pMethodDeclDef = MetaData_GetMethodDefFromDefRefOrSpec(pTypeDef->pMetaData, pMethodImpl->methodDeclaration, pTypeDef->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs); - if (pMethodDeclDef->tableIndex == pMethodDef->tableIndex) { - IDX_TABLE methodToken; - tMD_MethodDef *pMethod; - - methodToken = pMethodImpl->methodBody; - pMethod = (tMD_MethodDef*)MetaData_GetTableRow(pTypeDef->pMetaData, methodToken); - return pMethod; - } - } - } - - // Use normal inheritence rules - // It must be a virtual method that's being overridden. - for (i=pTypeDef->numVirtualMethods - 1; i != 0xffffffff; i--) { - if (MetaData_CompareNameAndSig(pMethodDef->name, pMethodDef->signature, pMethodDef->pMetaData, pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs, pTypeDef->pVTable[i], pTypeDef->ppClassTypeArgs, NULL)) { - return pTypeDef->pVTable[i]; - } - } - pTypeDef = pTypeDef->pParent; - } while (pTypeDef != NULL); - - return NULL; -} - void MetaData_Fill_TypeDef_(tMD_TypeDef *pTypeDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { IDX_TABLE firstIdx, lastIdx, token; U32 instanceMemSize, staticMemSize, virtualOfs, i, j; @@ -241,8 +200,14 @@ void MetaData_Fill_TypeDef_(tMD_TypeDef *pTypeDef, tMD_TypeDef **ppClassTypeArgs tMD_MethodDef *pVirtualOveriddenMethod; pVirtualOveriddenMethod = FindVirtualOverriddenMethod(pTypeDef->pParent, pMethodDef); - Assert(pVirtualOveriddenMethod != NULL); - pMethodDef->vTableOfs = pVirtualOveriddenMethod->vTableOfs; + if (pVirtualOveriddenMethod != NULL) { + //Assert(pVirtualOveriddenMethod != NULL); + pMethodDef->vTableOfs = pVirtualOveriddenMethod->vTableOfs; + } + else { + // perhaps virtual methods in abstract classes? + pMethodDef->vTableOfs = virtualOfs++; + } } } else { // Dummy value - make it obvious it's not valid! diff --git a/src/DNA/native/src/MetaData_Search.c b/src/DNA/native/src/MetaData_Search.c index 847339de..da070607 100644 --- a/src/DNA/native/src/MetaData_Search.c +++ b/src/DNA/native/src/MetaData_Search.c @@ -29,7 +29,7 @@ U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaData, tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs, tMD_TypeDef **ppMethodMethodTypeArgs) { if (strcmp(name, pMethod->name) == 0) { SIG sig, thisSig; - U32 e, thisE, paramCount, i; + U32 e, thisE, paramCount, i, isGeneric; sig = MetaData_GetBlob(sigBlob, NULL); thisSig = MetaData_GetBlob(pMethod->signature, NULL); @@ -42,7 +42,8 @@ U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaDa } // If method has generic arguments, check the generic type argument count - if (e & SIG_METHODDEF_GENERIC) { + isGeneric = e & SIG_CALLCONV_GENERIC; + if (isGeneric) { e = MetaData_DecodeSigEntry(&sig); thisE = MetaData_DecodeSigEntry(&thisSig); // Generic argument count @@ -66,7 +67,9 @@ U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaDa pParamType = Type_GetTypeFromSig(pSigMetaData, &sig, ppSigClassTypeArgs, ppSigMethodTypeArgs); pThisParamType = Type_GetTypeFromSig(pMethod->pMetaData, &thisSig, ppMethodClassTypeArgs, ppMethodMethodTypeArgs); if (pParamType != pThisParamType) { - return 0; + if (!isGeneric || ppMethodMethodTypeArgs != NULL) { + return 0; + } } } // All parameters the same, so found the right method @@ -75,18 +78,20 @@ U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaDa return 0; } -static tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMetaData *pSigMetaData, BLOB_ sigBlob, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { - U32 i; - tMD_TypeDef *pLookInType = pTypeDef; +tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMetaData *pSigMetaData, BLOB_ sigBlob, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { - do { - for (i=0; inumMethods; i++) { - if (MetaData_CompareNameAndSig(name, sigBlob, pSigMetaData, ppClassTypeArgs, ppMethodTypeArgs, pLookInType->ppMethods[i], pLookInType->ppClassTypeArgs, ppMethodTypeArgs)) { - return pLookInType->ppMethods[i]; + //dprintfn("Find method %s in type %s.%s", name, pTypeDef->nameSpace, pTypeDef->name); + + tMD_TypeDef *pLookInType = pTypeDef; + while (pLookInType != NULL) { + for (U32 i=0; inumMethods; i++) { + tMD_MethodDef *pMethodDef = pLookInType->ppMethods[i]; + if (MetaData_CompareNameAndSig(name, sigBlob, pSigMetaData, ppClassTypeArgs, ppMethodTypeArgs, pMethodDef, pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs)) { + return pMethodDef; } } pLookInType = pLookInType->pParent; - } while (pLookInType != NULL); + } { // Error reporting!! @@ -99,10 +104,10 @@ static tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMeta *pMsg = 0; sig = MetaData_GetBlob(sigBlob, &i); entry = MetaData_DecodeSigEntry(&sig); - if ((entry & SIG_METHODDEF_HASTHIS) == 0) { + if ((entry & SIG_CALLCONV_HASTHIS) == 0) { sprintf(strchr(pMsg, 0), "static "); } - if (entry & SIG_METHODDEF_GENERIC) { + if (entry & SIG_CALLCONV_GENERIC) { // read number of generic type args - don't care what it is MetaData_DecodeSigEntry(&sig); } @@ -118,7 +123,7 @@ static tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMeta sprintf(strchr(pMsg, 0), ","); } if (pParamTypeDef != NULL) { - sprintf(strchr(pMsg, 0), pParamTypeDef->name); + sprintf(strchr(pMsg, 0), "%s", pParamTypeDef->name); } else { sprintf(strchr(pMsg, 0), "???"); } @@ -128,6 +133,39 @@ static tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMeta FAKE_RETURN; } +// Find the method that has been overridden by pMethodDef. +// This is to get the correct vTable offset for the method. +// This must search the MethodImpl table to see if the default inheritence rules are being overridden. +// Return NULL if this method does not override anything. +tMD_MethodDef* FindVirtualOverriddenMethod(tMD_TypeDef *pTypeDef, tMD_MethodDef *pMethodDef) { + do { + // Search MethodImpl table + U32 top = pTypeDef->pMetaData->tables.numRows[MD_TABLE_METHODIMPL]; + for (U32 i = top; i > 0; i--) { + tMD_MethodImpl *pMethodImpl = (tMD_MethodImpl*)MetaData_GetTableRow(pTypeDef->pMetaData, MAKE_TABLE_INDEX(MD_TABLE_METHODIMPL, i)); + if (pMethodImpl->class_ == pTypeDef->tableIndex) { + tMD_MethodDef *pMethodDeclDef = MetaData_GetMethodDefFromDefRefOrSpec(pTypeDef->pMetaData, pMethodImpl->methodDeclaration, pTypeDef->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs); + if (pMethodDeclDef->tableIndex == pMethodDef->tableIndex) { + IDX_TABLE methodToken = pMethodImpl->methodBody; + tMD_MethodDef *pMethod = (tMD_MethodDef*)MetaData_GetTableRow(pTypeDef->pMetaData, methodToken); + return pMethod; + } + } + } + + // Use normal inheritence rules + // It must be a virtual method that's being overridden. + for (U32 i = pTypeDef->numVirtualMethods - 1; i != 0xffffffff; i--) { + if (MetaData_CompareNameAndSig(pMethodDef->name, pMethodDef->signature, pMethodDef->pMetaData, pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs, pTypeDef->pVTable[i], pTypeDef->ppClassTypeArgs, pTypeDef->pVTable[i]->ppMethodTypeArgs)) { + return pTypeDef->pVTable[i]; + } + } + pTypeDef = pTypeDef->pParent; + } while (pTypeDef != NULL); + + return NULL; +} + static tMD_FieldDef* FindFieldInType(tMD_TypeDef *pTypeDef, STRING name) { U32 i; diff --git a/src/DNA/native/src/PInvoke.c b/src/DNA/native/src/PInvoke.c index 011672ad..cfa2b514 100644 --- a/src/DNA/native/src/PInvoke.c +++ b/src/DNA/native/src/PInvoke.c @@ -174,9 +174,9 @@ U32 PInvoke_Call(tJITCallPInvoke *pCall, PTR pParams, PTR pReturnValue, tThread U32 _tempMemOfs = 0; U32 i; U32 funcParams = DEFAULT; - U64 u64Ret; - float fRet; - double dRet; + U64 u64Ret = 0; + float fRet = 0; + double dRet = 0; // [Steve edit] Before we issue the call into JS code, we need to set the calling .NET thread's state // to 'suspended' so that, if the JS code makes other calls into .NET, the DNA runtime doesn't try to diff --git a/src/DNA/native/src/Sys.c b/src/DNA/native/src/Sys.c index 8ac46604..306ce1e7 100644 --- a/src/DNA/native/src/Sys.c +++ b/src/DNA/native/src/Sys.c @@ -74,7 +74,7 @@ char* Sys_GetMethodDesc(tMD_MethodDef *pMethod) { if (i > (U32)(METHOD_ISSTATIC(pMethod)?0:1)) { sprintf(strchr(methodName, 0), ","); } - sprintf(strchr(methodName, 0), pMethod->pParams[i].pTypeDef->name); + sprintf(strchr(methodName, 0), "%s", pMethod->pParams[i].pTypeDef->name); } sprintf(strchr(methodName, 0), ")"); return methodName; @@ -147,4 +147,702 @@ void SleepMS(U32 ms) { sleep(ms / 1000); usleep((ms % 1000) * 1000); #endif -} \ No newline at end of file +} + +#ifdef DEBUG_PRINT + +#define _CIL_OPDEF(str, op, action) case op: return str; + +char* Sys_CIL_OpCodeName(U32 op) { + switch (op) { + +_CIL_OPDEF("nop", 0x00, NEXT) +_CIL_OPDEF("break", 0x01, BREAK) +_CIL_OPDEF("ldarg.0", 0x02, NEXT) +_CIL_OPDEF("ldarg.1", 0x03, NEXT) +_CIL_OPDEF("ldarg.2", 0x04, NEXT) +_CIL_OPDEF("ldarg.3", 0x05, NEXT) +_CIL_OPDEF("ldloc.0", 0x06, NEXT) +_CIL_OPDEF("ldloc.1", 0x07, NEXT) +_CIL_OPDEF("ldloc.2", 0x08, NEXT) +_CIL_OPDEF("ldloc.3", 0x09, NEXT) +_CIL_OPDEF("stloc.0", 0x0A, NEXT) +_CIL_OPDEF("stloc.1", 0x0B, NEXT) +_CIL_OPDEF("stloc.2", 0x0C, NEXT) +_CIL_OPDEF("stloc.3", 0x0D, NEXT) +_CIL_OPDEF("ldarg.s", 0x0E, NEXT) +_CIL_OPDEF("ldarga.s", 0x0F, NEXT) +_CIL_OPDEF("starg.s", 0x10, NEXT) +_CIL_OPDEF("ldloc.s", 0x11, NEXT) +_CIL_OPDEF("ldloca.s", 0x12, NEXT) +_CIL_OPDEF("stloc.s", 0x13, NEXT) +_CIL_OPDEF("ldnull", 0x14, NEXT) +_CIL_OPDEF("ldc.i4.m1", 0x15, NEXT) +_CIL_OPDEF("ldc.i4.0", 0x16, NEXT) +_CIL_OPDEF("ldc.i4.1", 0x17, NEXT) +_CIL_OPDEF("ldc.i4.2", 0x18, NEXT) +_CIL_OPDEF("ldc.i4.3", 0x19, NEXT) +_CIL_OPDEF("ldc.i4.4", 0x1A, NEXT) +_CIL_OPDEF("ldc.i4.5", 0x1B, NEXT) +_CIL_OPDEF("ldc.i4.6", 0x1C, NEXT) +_CIL_OPDEF("ldc.i4.7", 0x1D, NEXT) +_CIL_OPDEF("ldc.i4.8", 0x1E, NEXT) +_CIL_OPDEF("ldc.i4.s", 0x1F, NEXT) +_CIL_OPDEF("ldc.i4", 0x20, NEXT) +_CIL_OPDEF("ldc.i8", 0x21, NEXT) +_CIL_OPDEF("ldc.r4", 0x22, NEXT) +_CIL_OPDEF("ldc.r8", 0x23, NEXT) +_CIL_OPDEF("unused", 0x24, NEXT) +_CIL_OPDEF("dup", 0x25, NEXT) +_CIL_OPDEF("pop", 0x26, NEXT) +_CIL_OPDEF("jmp", 0x27, CALL) +_CIL_OPDEF("call", 0x28, CALL) +_CIL_OPDEF("calli", 0x29, CALL) +_CIL_OPDEF("ret", 0x2A, RETURN) +_CIL_OPDEF("br.s", 0x2B, BRANCH) +_CIL_OPDEF("brfalse.s", 0x2C, COND_BRANCH) +_CIL_OPDEF("brtrue.s", 0x2D, COND_BRANCH) +_CIL_OPDEF("beq.s", 0x2E, COND_BRANCH) +_CIL_OPDEF("bge.s", 0x2F, COND_BRANCH) +_CIL_OPDEF("bgt.s", 0x30, COND_BRANCH) +_CIL_OPDEF("ble.s", 0x31, COND_BRANCH) +_CIL_OPDEF("blt.s", 0x32, COND_BRANCH) +_CIL_OPDEF("bne.un.s", 0x33, COND_BRANCH) +_CIL_OPDEF("bge.un.s", 0x34, COND_BRANCH) +_CIL_OPDEF("bgt.un.s", 0x35, COND_BRANCH) +_CIL_OPDEF("ble.un.s", 0x36, COND_BRANCH) +_CIL_OPDEF("blt.un.s", 0x37, COND_BRANCH) +_CIL_OPDEF("br", 0x38, BRANCH) +_CIL_OPDEF("brfalse", 0x39, COND_BRANCH) +_CIL_OPDEF("brtrue", 0x3A, COND_BRANCH) +_CIL_OPDEF("beq", 0x3B, COND_BRANCH) +_CIL_OPDEF("bge", 0x3C, COND_BRANCH) +_CIL_OPDEF("bgt", 0x3D, COND_BRANCH) +_CIL_OPDEF("ble", 0x3E, COND_BRANCH) +_CIL_OPDEF("blt", 0x3F, COND_BRANCH) +_CIL_OPDEF("bne.un", 0x40, COND_BRANCH) +_CIL_OPDEF("bge.un", 0x41, COND_BRANCH) +_CIL_OPDEF("bgt.un", 0x42, COND_BRANCH) +_CIL_OPDEF("ble.un", 0x43, COND_BRANCH) +_CIL_OPDEF("blt.un", 0x44, COND_BRANCH) +_CIL_OPDEF("switch", 0x45, COND_BRANCH) +_CIL_OPDEF("ldind.i1", 0x46, NEXT) +_CIL_OPDEF("ldind.u1", 0x47, NEXT) +_CIL_OPDEF("ldind.i2", 0x48, NEXT) +_CIL_OPDEF("ldind.u2", 0x49, NEXT) +_CIL_OPDEF("ldind.i4", 0x4A, NEXT) +_CIL_OPDEF("ldind.u4", 0x4B, NEXT) +_CIL_OPDEF("ldind.i8", 0x4C, NEXT) +_CIL_OPDEF("ldind.i", 0x4D, NEXT) +_CIL_OPDEF("ldind.r4", 0x4E, NEXT) +_CIL_OPDEF("ldind.r8", 0x4F, NEXT) +_CIL_OPDEF("ldind.ref", 0x50, NEXT) +_CIL_OPDEF("stind.ref", 0x51, NEXT) +_CIL_OPDEF("stind.i1", 0x52, NEXT) +_CIL_OPDEF("stind.i2", 0x53, NEXT) +_CIL_OPDEF("stind.i4", 0x54, NEXT) +_CIL_OPDEF("stind.i8", 0x55, NEXT) +_CIL_OPDEF("stind.r4", 0x56, NEXT) +_CIL_OPDEF("stind.r8", 0x57, NEXT) +_CIL_OPDEF("add", 0x58, NEXT) +_CIL_OPDEF("sub", 0x59, NEXT) +_CIL_OPDEF("mul", 0x5A, NEXT) +_CIL_OPDEF("div", 0x5B, NEXT) +_CIL_OPDEF("div.un", 0x5C, NEXT) +_CIL_OPDEF("rem", 0x5D, NEXT) +_CIL_OPDEF("rem.un", 0x5E, NEXT) +_CIL_OPDEF("and", 0x5F, NEXT) +_CIL_OPDEF("or", 0x60, NEXT) +_CIL_OPDEF("xor", 0x61, NEXT) +_CIL_OPDEF("shl", 0x62, NEXT) +_CIL_OPDEF("shr", 0x63, NEXT) +_CIL_OPDEF("shr.un", 0x64, NEXT) +_CIL_OPDEF("neg", 0x65, NEXT) +_CIL_OPDEF("not", 0x66, NEXT) +_CIL_OPDEF("conv.i1", 0x67, NEXT) +_CIL_OPDEF("conv.i2", 0x68, NEXT) +_CIL_OPDEF("conv.i4", 0x69, NEXT) +_CIL_OPDEF("conv.i8", 0x6A, NEXT) +_CIL_OPDEF("conv.r4", 0x6B, NEXT) +_CIL_OPDEF("conv.r8", 0x6C, NEXT) +_CIL_OPDEF("conv.u4", 0x6D, NEXT) +_CIL_OPDEF("conv.u8", 0x6E, NEXT) +_CIL_OPDEF("callvirt", 0x6F, CALL) +_CIL_OPDEF("cpobj", 0x70, NEXT) +_CIL_OPDEF("ldobj", 0x71, NEXT) +_CIL_OPDEF("ldstr", 0x72, NEXT) +_CIL_OPDEF("newobj", 0x73, CALL) +_CIL_OPDEF("castclass", 0x74, NEXT) +_CIL_OPDEF("isinst", 0x75, NEXT) +_CIL_OPDEF("conv.r.un", 0x76, NEXT) +_CIL_OPDEF("unused", 0x77, NEXT) +_CIL_OPDEF("unused", 0x78, NEXT) +_CIL_OPDEF("unbox", 0x79, NEXT) +_CIL_OPDEF("throw", 0x7A, THROW) +_CIL_OPDEF("ldfld", 0x7B, NEXT) +_CIL_OPDEF("ldflda", 0x7C, NEXT) +_CIL_OPDEF("stfld", 0x7D, NEXT) +_CIL_OPDEF("ldsfld", 0x7E, NEXT) +_CIL_OPDEF("ldsflda", 0x7F, NEXT) +_CIL_OPDEF("stsfld", 0x80, NEXT) +_CIL_OPDEF("stobj", 0x81, NEXT) +_CIL_OPDEF("conv.ovf.i1.un", 0x82, NEXT) +_CIL_OPDEF("conv.ovf.i2.un", 0x83, NEXT) +_CIL_OPDEF("conv.ovf.i4.un", 0x84, NEXT) +_CIL_OPDEF("conv.ovf.i8.un", 0x85, NEXT) +_CIL_OPDEF("conv.ovf.u1.un", 0x86, NEXT) +_CIL_OPDEF("conv.ovf.u2.un", 0x87, NEXT) +_CIL_OPDEF("conv.ovf.u4.un", 0x88, NEXT) +_CIL_OPDEF("conv.ovf.u8.un", 0x89, NEXT) +_CIL_OPDEF("conv.ovf.i.un", 0x8A, NEXT) +_CIL_OPDEF("conv.ovf.u.un", 0x8B, NEXT) +_CIL_OPDEF("box", 0x8C, NEXT) +_CIL_OPDEF("newarr", 0x8D, NEXT) +_CIL_OPDEF("ldlen", 0x8E, NEXT) +_CIL_OPDEF("ldelema", 0x8F, NEXT) +_CIL_OPDEF("ldelem.i1", 0x90, NEXT) +_CIL_OPDEF("ldelem.u1", 0x91, NEXT) +_CIL_OPDEF("ldelem.i2", 0x92, NEXT) +_CIL_OPDEF("ldelem.u2", 0x93, NEXT) +_CIL_OPDEF("ldelem.i4", 0x94, NEXT) +_CIL_OPDEF("ldelem.u4", 0x95, NEXT) +_CIL_OPDEF("ldelem.i8", 0x96, NEXT) +_CIL_OPDEF("ldelem.i", 0x97, NEXT) +_CIL_OPDEF("ldelem.r4", 0x98, NEXT) +_CIL_OPDEF("ldelem.r8", 0x99, NEXT) +_CIL_OPDEF("ldelem.ref", 0x9A, NEXT) +_CIL_OPDEF("stelem.i", 0x9B, NEXT) +_CIL_OPDEF("stelem.i1", 0x9C, NEXT) +_CIL_OPDEF("stelem.i2", 0x9D, NEXT) +_CIL_OPDEF("stelem.i4", 0x9E, NEXT) +_CIL_OPDEF("stelem.i8", 0x9F, NEXT) +_CIL_OPDEF("stelem.r4", 0xA0, NEXT) +_CIL_OPDEF("stelem.r8", 0xA1, NEXT) +_CIL_OPDEF("stelem.ref", 0xA2, NEXT) +_CIL_OPDEF("unused", 0xA3, NEXT) +_CIL_OPDEF("unused", 0xA4, NEXT) +_CIL_OPDEF("unused", 0xA5, NEXT) +_CIL_OPDEF("unused", 0xA6, NEXT) +_CIL_OPDEF("unused", 0xA7, NEXT) +_CIL_OPDEF("unused", 0xA8, NEXT) +_CIL_OPDEF("unused", 0xA9, NEXT) +_CIL_OPDEF("unused", 0xAA, NEXT) +_CIL_OPDEF("unused", 0xAB, NEXT) +_CIL_OPDEF("unused", 0xAC, NEXT) +_CIL_OPDEF("unused", 0xAD, NEXT) +_CIL_OPDEF("unused", 0xAE, NEXT) +_CIL_OPDEF("unused", 0xAF, NEXT) +_CIL_OPDEF("unused", 0xB0, NEXT) +_CIL_OPDEF("unused", 0xB1, NEXT) +_CIL_OPDEF("unused", 0xB2, NEXT) +_CIL_OPDEF("conv.ovf.i1", 0xB3, NEXT) +_CIL_OPDEF("conv.ovf.u1", 0xB4, NEXT) +_CIL_OPDEF("conv.ovf.i2", 0xB5, NEXT) +_CIL_OPDEF("conv.ovf.u2", 0xB6, NEXT) +_CIL_OPDEF("conv.ovf.i4", 0xB7, NEXT) +_CIL_OPDEF("conv.ovf.u4", 0xB8, NEXT) +_CIL_OPDEF("conv.ovf.i8", 0xB9, NEXT) +_CIL_OPDEF("conv.ovf.u8", 0xBA, NEXT) +_CIL_OPDEF("unused", 0xBB, NEXT) +_CIL_OPDEF("unused", 0xBC, NEXT) +_CIL_OPDEF("unused", 0xBD, NEXT) +_CIL_OPDEF("unused", 0xBE, NEXT) +_CIL_OPDEF("unused", 0xBF, NEXT) +_CIL_OPDEF("unused", 0xC0, NEXT) +_CIL_OPDEF("unused", 0xC1, NEXT) +_CIL_OPDEF("refanyval", 0xC2, NEXT) +_CIL_OPDEF("ckfinite", 0xC3, NEXT) +_CIL_OPDEF("unused", 0xC4, NEXT) +_CIL_OPDEF("unused", 0xC5, NEXT) +_CIL_OPDEF("mkrefany", 0xC6, NEXT) +_CIL_OPDEF("unused", 0xC7, NEXT) +_CIL_OPDEF("unused", 0xC8, NEXT) +_CIL_OPDEF("unused", 0xC9, NEXT) +_CIL_OPDEF("unused", 0xCA, NEXT) +_CIL_OPDEF("unused", 0xCB, NEXT) +_CIL_OPDEF("unused", 0xCC, NEXT) +_CIL_OPDEF("unused", 0xCD, NEXT) +_CIL_OPDEF("unused", 0xCE, NEXT) +_CIL_OPDEF("unused", 0xCF, NEXT) +_CIL_OPDEF("ldtoken", 0xD0, NEXT) +_CIL_OPDEF("conv.u2", 0xD1, NEXT) +_CIL_OPDEF("conv.u1", 0xD2, NEXT) +_CIL_OPDEF("conv.i", 0xD3, NEXT) +_CIL_OPDEF("conv.ovf.i", 0xD4, NEXT) +_CIL_OPDEF("conv.ovf.u", 0xD5, NEXT) +_CIL_OPDEF("add.ovf", 0xD6, NEXT) +_CIL_OPDEF("add.ovf.un", 0xD7, NEXT) +_CIL_OPDEF("mul.ovf", 0xD8, NEXT) +_CIL_OPDEF("mul.ovf.un", 0xD9, NEXT) +_CIL_OPDEF("sub.ovf", 0xDA, NEXT) +_CIL_OPDEF("sub.ovf.un", 0xDB, NEXT) +_CIL_OPDEF("endfinally", 0xDC, RETURN) +_CIL_OPDEF("leave", 0xDD, BRANCH) +_CIL_OPDEF("leave.s", 0xDE, BRANCH) +_CIL_OPDEF("stind.i", 0xDF, NEXT) +_CIL_OPDEF("conv.u", 0xE0, NEXT) +_CIL_OPDEF("unused", 0xE1, NEXT) +_CIL_OPDEF("unused", 0xE2, NEXT) +_CIL_OPDEF("unused", 0xE3, NEXT) +_CIL_OPDEF("unused", 0xE4, NEXT) +_CIL_OPDEF("unused", 0xE5, NEXT) +_CIL_OPDEF("unused", 0xE6, NEXT) +_CIL_OPDEF("unused", 0xE7, NEXT) +_CIL_OPDEF("unused", 0xE8, NEXT) +_CIL_OPDEF("unused", 0xE9, NEXT) +_CIL_OPDEF("unused", 0xEA, NEXT) +_CIL_OPDEF("unused", 0xEB, NEXT) +_CIL_OPDEF("unused", 0xEC, NEXT) +_CIL_OPDEF("unused", 0xED, NEXT) +_CIL_OPDEF("unused", 0xEE, NEXT) +_CIL_OPDEF("unused", 0xEF, NEXT) +_CIL_OPDEF("unused", 0xF0, NEXT) +_CIL_OPDEF("unused", 0xF1, NEXT) +_CIL_OPDEF("unused", 0xF2, NEXT) +_CIL_OPDEF("unused", 0xF3, NEXT) +_CIL_OPDEF("unused", 0xF4, NEXT) +_CIL_OPDEF("unused", 0xF5, NEXT) +_CIL_OPDEF("unused", 0xF6, NEXT) +_CIL_OPDEF("unused", 0xF7, NEXT) +_CIL_OPDEF("prefix7", 0xF8, META) +_CIL_OPDEF("prefix6", 0xF9, META) +_CIL_OPDEF("prefix5", 0xFA, META) +_CIL_OPDEF("prefix4", 0xFB, META) +_CIL_OPDEF("prefix3", 0xFC, META) +_CIL_OPDEF("prefix2", 0xFD, META) +_CIL_OPDEF("prefix1", 0xFE, META) +_CIL_OPDEF("prefixref", 0xFF, META) +_CIL_OPDEF("arglist", 0x100, NEXT) +_CIL_OPDEF("ceq", 0x101, NEXT) +_CIL_OPDEF("cgt", 0x102, NEXT) +_CIL_OPDEF("cgt.un", 0x103, NEXT) +_CIL_OPDEF("clt", 0x104, NEXT) +_CIL_OPDEF("clt.un", 0x105, NEXT) +_CIL_OPDEF("ldftn", 0x106, NEXT) +_CIL_OPDEF("ldvirtftn", 0x107, NEXT) +_CIL_OPDEF("unused", 0x108, NEXT) +_CIL_OPDEF("ldarg", 0x109, NEXT) +_CIL_OPDEF("ldarga", 0x10A, NEXT) +_CIL_OPDEF("starg", 0x10B, NEXT) +_CIL_OPDEF("ldloc", 0x10C, NEXT) +_CIL_OPDEF("ldloca", 0x10D, NEXT) +_CIL_OPDEF("stloc", 0x10E, NEXT) +_CIL_OPDEF("localloc", 0x10F, NEXT) +_CIL_OPDEF("unused", 0x110, NEXT) +_CIL_OPDEF("endfilter", 0x111, RETURN) +_CIL_OPDEF("unaligned.", 0x112, META) +_CIL_OPDEF("volatile.", 0x113, META) +_CIL_OPDEF("tail.", 0x114, META) +_CIL_OPDEF("initobj", 0x115, NEXT) +_CIL_OPDEF("unused", 0x116, NEXT) +_CIL_OPDEF("cpblk", 0x117, NEXT) +_CIL_OPDEF("initblk", 0x118, NEXT) +_CIL_OPDEF("unused", 0x119, NEXT) +_CIL_OPDEF("rethrow", 0x11A, THROW) +_CIL_OPDEF("unused", 0x11B, NEXT) +_CIL_OPDEF("sizeof", 0x11C, NEXT) +_CIL_OPDEF("refanytype", 0x11D, NEXT) +_CIL_OPDEF("unused", 0x11E, NEXT) + + default: return "undefined"; + } +} + + +#define _JIT_OPDEF(str, op) case op: return str; + +char* Sys_JIT_OpCodeName(U32 op) { + switch (op) { + +_JIT_OPDEF("NOP", 0x0) +_JIT_OPDEF("RETURN", 0x1) +_JIT_OPDEF("LOAD_I32", 0x2) +_JIT_OPDEF("BRANCH", 0x3) +_JIT_OPDEF("LOAD_STRING", 0x4) +_JIT_OPDEF("CALLVIRT_O", 0x5) +_JIT_OPDEF("CALL_NATIVE", 0x6) +_JIT_OPDEF("CALL_O", 0x7) +_JIT_OPDEF("NEWOBJECT", 0x8) +_JIT_OPDEF("LOAD_PARAMLOCAL_ADDR", 0x9) +_JIT_OPDEF("CALL_PTR", 0xa) +_JIT_OPDEF("BOX_CALLVIRT", 0xb) +_JIT_OPDEF("INIT_VALUETYPE", 0xc) +_JIT_OPDEF("NEW_VECTOR", 0xd) +_JIT_OPDEF("NEWOBJECT_VALUETYPE", 0xe) +_JIT_OPDEF("IS_INSTANCE", 0xf) +_JIT_OPDEF("LOAD_NULL", 0x10) +_JIT_OPDEF("UNBOX2VALUETYPE", 0x11) +_JIT_OPDEF("UNBOX2OBJECT", 0x12) +_JIT_OPDEF("LOAD_FIELD_ADDR", 0x13) +_JIT_OPDEF("DUP_GENERAL", 0x14) +_JIT_OPDEF("POP", 0x15) +_JIT_OPDEF("STORE_OBJECT_VALUETYPE", 0x16) +_JIT_OPDEF("DEREF_CALLVIRT", 0x17) +_JIT_OPDEF("STORE_ELEMENT", 0x18) +_JIT_OPDEF("LEAVE", 0x19) +_JIT_OPDEF("END_FINALLY", 0x1a) +_JIT_OPDEF("THROW", 0x1b) +_JIT_OPDEF("RETHROW", 0x1c) +_JIT_OPDEF("LOADOBJECT", 0x1d) +_JIT_OPDEF("LOAD_VECTOR_LEN", 0x1e) +_JIT_OPDEF("SWITCH", 0x1f) +_JIT_OPDEF("LOAD_ELEMENT_ADDR", 0x20) +_JIT_OPDEF("CALL_INTERFACE", 0x21) +_JIT_OPDEF("CAST_CLASS", 0x22) +_JIT_OPDEF("LOAD_ELEMENT", 0x23) +_JIT_OPDEF("LOADFIELD_VALUETYPE", 0x24) +_JIT_OPDEF("LOADFIELD", 0x25) +_JIT_OPDEF("LOADFUNCTION", 0x26) +_JIT_OPDEF("INVOKE_DELEGATE", 0x27) +_JIT_OPDEF("CALL_PINVOKE", 0x28) +_JIT_OPDEF("LOAD_I64", 0x29) +_JIT_OPDEF("INIT_OBJECT", 0x2a) +_JIT_OPDEF("DUP_4", 0x2b) +_JIT_OPDEF("DUP_8", 0x2c) +_JIT_OPDEF("LOADSTATICFIELDADDRESS_CHECKTYPEINIT", 0x2d) +_JIT_OPDEF("POP_4", 0x2e) +_JIT_OPDEF("LOAD_F32", 0x2f) + +_JIT_OPDEF("LOADPARAMLOCAL_INT64", 0x30) +_JIT_OPDEF("LOADPARAMLOCAL_INT32", 0x31) +_JIT_OPDEF("LOADPARAMLOCAL_INTNATIVE", 0x32) +_JIT_OPDEF("LOADPARAMLOCAL_F64", 0x33) +_JIT_OPDEF("LOADPARAMLOCAL_PTR", 0x34) +_JIT_OPDEF("LOADPARAMLOCAL_O", 0x35) +_JIT_OPDEF("LOADPARAMLOCAL_F32", 0x36) +_JIT_OPDEF("LOADPARAMLOCAL_VALUETYPE", 0x37) + +_JIT_OPDEF("STOREPARAMLOCAL_INT64", 0x38) +_JIT_OPDEF("STOREPARAMLOCAL_INT32", 0x39) +_JIT_OPDEF("STOREPARAMLOCAL_INTNATIVE", 0x3a) +_JIT_OPDEF("STOREPARAMLOCAL_F64", 0x3b) +_JIT_OPDEF("STOREPARAMLOCAL_PTR", 0x3c) +_JIT_OPDEF("STOREPARAMLOCAL_O", 0x3d) +_JIT_OPDEF("STOREPARAMLOCAL_F32", 0x3e) +_JIT_OPDEF("STOREPARAMLOCAL_VALUETYPE", 0x3f) + +_JIT_OPDEF("STOREFIELD_INT64", 0x48) +_JIT_OPDEF("STOREFIELD_INT32", 0x49) +_JIT_OPDEF("STOREFIELD_INTNATIVE", 0x4a) +_JIT_OPDEF("STOREFIELD_F64", 0x4b) +_JIT_OPDEF("STOREFIELD_PTR", 0x4c) +_JIT_OPDEF("STOREFIELD_O", 0x4d) +_JIT_OPDEF("STOREFIELD_F32", 0x4e) +_JIT_OPDEF("STOREFIELD_VALUETYPE", 0x4f) + +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_INT64", 0x50) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_INT32", 0x51) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_INTNATIVE", 0x52) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_F64", 0x53) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_PTR", 0x54) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_O", 0x55) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_F32", 0x56) +_JIT_OPDEF("LOADSTATICFIELD_CHECKTYPEINIT_VALUETYPE", 0x57) + +_JIT_OPDEF("LOADSTATICFIELD_INT64", 0x58) +_JIT_OPDEF("LOADSTATICFIELD_INT32", 0x59) +_JIT_OPDEF("LOADSTATICFIELD_INTNATIVE", 0x5a) +_JIT_OPDEF("LOADSTATICFIELD_F64", 0x5b) +_JIT_OPDEF("LOADSTATICFIELD_PTR", 0x5c) +_JIT_OPDEF("LOADSTATICFIELD_O", 0x5d) +_JIT_OPDEF("LOADSTATICFIELD_F32", 0x5e) +_JIT_OPDEF("LOADSTATICFIELD_VALUETYPE", 0x5f) + +_JIT_OPDEF("STORESTATICFIELD_INT64", 0x60) +_JIT_OPDEF("STORESTATICFIELD_INT32", 0x61) +_JIT_OPDEF("STORESTATICFIELD_INTNATIVE", 0x62) +_JIT_OPDEF("STORESTATICFIELD_F64", 0x63) +_JIT_OPDEF("STORESTATICFIELD_PTR", 0x64) +_JIT_OPDEF("STORESTATICFIELD_O", 0x65) +_JIT_OPDEF("STORESTATICFIELD_F32", 0x66) +_JIT_OPDEF("STORESTATICFIELD_VALUETYPE", 0x67) + +_JIT_OPDEF("BOX_INT64", 0x68) +_JIT_OPDEF("BOX_INT32", 0x69) +_JIT_OPDEF("BOX_INTNATIVE", 0x6a) +_JIT_OPDEF("BOX_F64", 0x6b) +_JIT_OPDEF("BOX_PTR", 0x6c) +_JIT_OPDEF("BOX_O", 0x6d) +_JIT_OPDEF("BOX_F32", 0x6e) +_JIT_OPDEF("BOX_VALUETYPE", 0x6f) + +_JIT_OPDEF("CEQ_I32I32", 0x70) +_JIT_OPDEF("CGT_I32I32", 0x71) +_JIT_OPDEF("CGT_UN_I32I32", 0x72) +_JIT_OPDEF("CLT_I32I32", 0x73) +_JIT_OPDEF("CLT_UN_I32I32", 0x74) + +_JIT_OPDEF("CEQ_I64I64", 0x75) +_JIT_OPDEF("CGT_I64I64", 0x76) +_JIT_OPDEF("CGT_UN_I64I64", 0x77) +_JIT_OPDEF("CLT_I64I64", 0x78) +_JIT_OPDEF("CLT_UN_I64I64", 0x79) + +_JIT_OPDEF("ADD_OVF_I32I32", 0x7a) +_JIT_OPDEF("ADD_OVF_UN_I32I32", 0x7b) +_JIT_OPDEF("MUL_OVF_I32I32", 0x7c) +_JIT_OPDEF("MUL_OVF_UN_I32I32", 0x7d) +_JIT_OPDEF("SUB_OVF_I32I32", 0x7e) +_JIT_OPDEF("SUB_OVF_UN_I32I32", 0x7f) +_JIT_OPDEF("ADD_I32I32", 0x80) +_JIT_OPDEF("SUB_I32I32", 0x81) +_JIT_OPDEF("MUL_I32I32", 0x82) +_JIT_OPDEF("DIV_I32I32", 0x83) +_JIT_OPDEF("DIV_UN_I32I32", 0x84) +_JIT_OPDEF("REM_I32I32", 0x85) +_JIT_OPDEF("REM_UN_I32I32", 0x86) +_JIT_OPDEF("AND_I32I32", 0x87) +_JIT_OPDEF("OR_I32I32", 0x88) +_JIT_OPDEF("XOR_I32I32", 0x89) + +_JIT_OPDEF("NEG_I32", 0x8a) +_JIT_OPDEF("NOT_I32", 0x8b) +_JIT_OPDEF("NEG_I64", 0x8c) +_JIT_OPDEF("NOT_I64", 0x8d) +_JIT_OPDEF("NEG_F32", 0x8e) +_JIT_OPDEF("NEG_F64", 0x8f) + +_JIT_OPDEF("BEQ_I32I32", 0x90) +_JIT_OPDEF("BGE_I32I32", 0x91) +_JIT_OPDEF("BGT_I32I32", 0x92) +_JIT_OPDEF("BLE_I32I32", 0x93) +_JIT_OPDEF("BLT_I32I32", 0x94) +_JIT_OPDEF("BNE_UN_I32I32", 0x95) +_JIT_OPDEF("BGE_UN_I32I32", 0x96) +_JIT_OPDEF("BGT_UN_I32I32", 0x97) +_JIT_OPDEF("BLE_UN_I32I32", 0x98) +_JIT_OPDEF("BLT_UN_I32I32", 0x99) + +_JIT_OPDEF("BEQ_I64I64", 0x9a) +_JIT_OPDEF("BGE_I64I64", 0x9b) +_JIT_OPDEF("BGT_I64I64", 0x9c) +_JIT_OPDEF("BLE_I64I64", 0x9d) +_JIT_OPDEF("BLT_I64I64", 0x9e) +_JIT_OPDEF("BNE_UN_I64I64", 0x9f) +_JIT_OPDEF("BGE_UN_I64I64", 0xa0) +_JIT_OPDEF("BGT_UN_I64I64", 0xa1) +_JIT_OPDEF("BLE_UN_I64I64", 0xa2) +_JIT_OPDEF("BLT_UN_I64I64", 0xa3) + +_JIT_OPDEF("SHL_I32", 0xa4) +_JIT_OPDEF("SHR_I32", 0xa5) +_JIT_OPDEF("SHR_UN_I32", 0xa6) +_JIT_OPDEF("SHL_I64", 0xa7) +_JIT_OPDEF("SHR_I64", 0xa8) +_JIT_OPDEF("SHR_UN_I64", 0xa9) + +_JIT_OPDEF("BRANCH_FALSE", 0xaa) +_JIT_OPDEF("BRANCH_TRUE", 0xab) +_JIT_OPDEF("BRANCH64_FALSE", 0xac) +_JIT_OPDEF("BRANCH64_TRUE", 0xad) + +_JIT_OPDEF("BOX_NULLABLE", 0xae) +_JIT_OPDEF("LOAD_F64", 0xaf) + +_JIT_OPDEF("LOADTOKEN_TYPE", 0xb0) +_JIT_OPDEF("LOADTOKEN_METHOD", 0xb1) +_JIT_OPDEF("LOADTOKEN_FIELD", 0xb2) + +_JIT_OPDEF("LOADINDIRECT_I8", 0xb3) +_JIT_OPDEF("LOADINDIRECT_U8", 0xb4) +_JIT_OPDEF("LOADINDIRECT_I16", 0xb5) +_JIT_OPDEF("LOADINDIRECT_U16", 0xb6) +_JIT_OPDEF("LOADINDIRECT_I32", 0xb7) +_JIT_OPDEF("LOADINDIRECT_U32", 0xb8) +_JIT_OPDEF("LOADINDIRECT_I64", 0xb9) +_JIT_OPDEF("LOADINDIRECT_I", 0xba) +_JIT_OPDEF("LOADINDIRECT_R32", 0xbb) +_JIT_OPDEF("LOADINDIRECT_R64", 0xbc) +_JIT_OPDEF("LOADINDIRECT_REF", 0xbd) + +_JIT_OPDEF("STOREINDIRECT_REF", 0xbe) +_JIT_OPDEF("STOREINDIRECT_U8", 0xbf) +_JIT_OPDEF("STOREINDIRECT_U16", 0xc0) +_JIT_OPDEF("STOREINDIRECT_U32", 0xc1) +_JIT_OPDEF("STOREINDIRECT_U64", 0xc2) +_JIT_OPDEF("STOREINDIRECT_R32", 0xc3) +_JIT_OPDEF("STOREINDIRECT_R64", 0xc4) + +//_JIT_OPDEF("CONV_SIGNED32", 0xc5) +//_JIT_OPDEF("CONV_UNSIGNED32", 0xc6) +//_JIT_OPDEF("CONV_INT_I64", 0xc7) + +//_JIT_OPDEF("CONV_I1", 0xc5) +//_JIT_OPDEF("CONV_I2", 0xc6) +//_JIT_OPDEF("CONV_I4", 0xc7) +//_JIT_OPDEF("CONV_I8", 0xc8) +//_JIT_OPDEF("CONV_R4", 0xc9) +//_JIT_OPDEF("CONV_R8", 0xca) +//_JIT_OPDEF("CONV_U4", 0xcb) +//_JIT_OPDEF("CONV_U8", 0xcc) +//_JIT_OPDEF("CONV_U2", 0xcd) +//_JIT_OPDEF("CONV_U1", 0xce) +//_JIT_OPDEF("CONV_I_NATIVE", 0xcf) +//_JIT_OPDEF("CONV_U_NATIVE", 0xd0) + +//_JIT_OPDEF("CONV_OVF_I1", 0xd1) +//_JIT_OPDEF("CONV_OVF_U1", 0xd2) +//_JIT_OPDEF("CONV_OVF_I2", 0xd3) +//_JIT_OPDEF("CONV_OVF_U2", 0xd4) +//_JIT_OPDEF("CONV_OVF_I4", 0xd5) +//_JIT_OPDEF("CONV_OVF_U4", 0xd6) +//_JIT_OPDEF("CONV_OVF_I8", 0xd7) +//_JIT_OPDEF("CONV_OVF_U8", 0xd8) + +_JIT_OPDEF("UNBOX_NULLABLE", 0xda) + +_JIT_OPDEF("STORE_ELEMENT_32", 0xde) +_JIT_OPDEF("STORE_ELEMENT_64", 0xdf) + +_JIT_OPDEF("LOAD_ELEMENT_I8", 0xe0) +_JIT_OPDEF("LOAD_ELEMENT_U8", 0xe1) +_JIT_OPDEF("LOAD_ELEMENT_I16", 0xe2) +_JIT_OPDEF("LOAD_ELEMENT_U16", 0xe3) +_JIT_OPDEF("LOAD_ELEMENT_I32", 0xe4) +_JIT_OPDEF("LOAD_ELEMENT_U32", 0xe5) +_JIT_OPDEF("LOAD_ELEMENT_I64", 0xe6) +_JIT_OPDEF("LOAD_ELEMENT_R32", 0xe7) +_JIT_OPDEF("LOAD_ELEMENT_R64", 0xe8) + +_JIT_OPDEF("ADD_OVF_I64I64", 0xea) +_JIT_OPDEF("ADD_OVF_UN_I64I64", 0xeb) +_JIT_OPDEF("MUL_OVF_I64I64", 0xec) +_JIT_OPDEF("MUL_OVF_UN_I64I64", 0xed) +_JIT_OPDEF("SUB_OVF_I64I64", 0xee) +_JIT_OPDEF("SUB_OVF_UN_I64I64", 0xef) +_JIT_OPDEF("ADD_I64I64", 0xf0) +_JIT_OPDEF("SUB_I64I64", 0xf1) +_JIT_OPDEF("MUL_I64I64", 0xf2) +_JIT_OPDEF("DIV_I64I64", 0xf3) +_JIT_OPDEF("DIV_UN_I64I64", 0xf4) +_JIT_OPDEF("REM_I64I64", 0xf5) +_JIT_OPDEF("REM_UN_I64I64", 0xf6) +_JIT_OPDEF("AND_I64I64", 0xf7) +_JIT_OPDEF("OR_I64I64", 0xf8) +_JIT_OPDEF("XOR_I64I64", 0xf9) + +_JIT_OPDEF("CEQ_F32F32", 0xfa) +_JIT_OPDEF("CGT_F32F32", 0xfb) +_JIT_OPDEF("CGT_UN_F32F32", 0xfc) +_JIT_OPDEF("CLT_F32F32", 0xfd) +_JIT_OPDEF("CLT_UN_F32F32", 0xfe) + +_JIT_OPDEF("BEQ_F32F32", 0xff) +_JIT_OPDEF("BGE_F32F32", 0x100) +_JIT_OPDEF("BGT_F32F32", 0x101) +_JIT_OPDEF("BLE_F32F32", 0x102) +_JIT_OPDEF("BLT_F32F32", 0x103) +_JIT_OPDEF("BNE_UN_F32F32", 0x104) +_JIT_OPDEF("BGE_UN_F32F32", 0x105) +_JIT_OPDEF("BGT_UN_F32F32", 0x106) +_JIT_OPDEF("BLE_UN_F32F32", 0x107) +_JIT_OPDEF("BLT_UN_F32F32", 0x108) + +_JIT_OPDEF("ADD_F32F32", 0x109) +_JIT_OPDEF("SUB_F32F32", 0x10a) +_JIT_OPDEF("MUL_F32F32", 0x10b) +_JIT_OPDEF("DIV_F32F32", 0x10c) +_JIT_OPDEF("DIV_UN_F32F32", 0x10d) // Not used +_JIT_OPDEF("REM_F32F32", 0x10e) +_JIT_OPDEF("REM_UN_F32F32", 0x10f) // Not used + +_JIT_OPDEF("CEQ_F64F64", 0x110) +_JIT_OPDEF("CGT_F64F64", 0x111) +_JIT_OPDEF("CGT_UN_F64F64", 0x112) +_JIT_OPDEF("CLT_F64F64", 0x113) +_JIT_OPDEF("CLT_UN_F64F64", 0x114) + +_JIT_OPDEF("BEQ_F64F64", 0x115) +_JIT_OPDEF("BGE_F64F64", 0x116) +_JIT_OPDEF("BGT_F64F64", 0x117) +_JIT_OPDEF("BLE_F64F64", 0x118) +_JIT_OPDEF("BLT_F64F64", 0x119) +_JIT_OPDEF("BNE_UN_F64F64", 0x11a) +_JIT_OPDEF("BGE_UN_F64F64", 0x11b) +_JIT_OPDEF("BGT_UN_F64F64", 0x11c) +_JIT_OPDEF("BLE_UN_F64F64", 0x11d) +_JIT_OPDEF("BLT_UN_F64F64", 0x11e) + +_JIT_OPDEF("ADD_F64F64", 0x11f) +_JIT_OPDEF("SUB_F64F64", 0x120) +_JIT_OPDEF("MUL_F64F64", 0x121) +_JIT_OPDEF("DIV_F64F64", 0x122) +_JIT_OPDEF("DIV_UN_F64F64", 0x123) // Not used +_JIT_OPDEF("REM_F64F64", 0x124) +_JIT_OPDEF("REM_UN_F64F64", 0x125) // Not used + +_JIT_OPDEF("LOADPARAMLOCAL_0", 0x127) // Load 4-byte param/local at offset 0) +_JIT_OPDEF("LOADPARAMLOCAL_1", 0x128) // Load 4-byte param/local at offset 4) +_JIT_OPDEF("LOADPARAMLOCAL_2", 0x129) // Load 4-byte param/local at offset 8) +_JIT_OPDEF("LOADPARAMLOCAL_3", 0x12a) // Load 4-byte param/local at offset 12) +_JIT_OPDEF("LOADPARAMLOCAL_4", 0x12b) // Load 4-byte param/local at offset 16) +_JIT_OPDEF("LOADPARAMLOCAL_5", 0x12c) // Load 4-byte param/local at offset 20) +_JIT_OPDEF("LOADPARAMLOCAL_6", 0x12d) // Load 4-byte param/local at offset 24) +_JIT_OPDEF("LOADPARAMLOCAL_7", 0x12e) // Load 4-byte param/local at offset 28) + +_JIT_OPDEF("STOREPARAMLOCAL_0", 0x12f) // Store 4-byte param/local at offset 0) +_JIT_OPDEF("STOREPARAMLOCAL_1", 0x130) // Store 4-byte param/local at offset 4) +_JIT_OPDEF("STOREPARAMLOCAL_2", 0x131) // Store 4-byte param/local at offset 8) +_JIT_OPDEF("STOREPARAMLOCAL_3", 0x132) // Store 4-byte param/local at offset 12) +_JIT_OPDEF("STOREPARAMLOCAL_4", 0x133) // Store 4-byte param/local at offset 16) +_JIT_OPDEF("STOREPARAMLOCAL_5", 0x134) // Store 4-byte param/local at offset 20) +_JIT_OPDEF("STOREPARAMLOCAL_6", 0x135) // Store 4-byte param/local at offset 24) +_JIT_OPDEF("STOREPARAMLOCAL_7", 0x136) // Store 4-byte param/local at offset 28) + +_JIT_OPDEF("LOAD_I4_M1", 0x137) +_JIT_OPDEF("LOAD_I4_0", 0x138) +_JIT_OPDEF("LOAD_I4_1", 0x139) +_JIT_OPDEF("LOAD_I4_2", 0x13a) + +_JIT_OPDEF("LOADFIELD_4", 0x13b) + +_JIT_OPDEF("CONV_I32_I32", 0x140) +_JIT_OPDEF("CONV_I32_U32", 0x141) +_JIT_OPDEF("CONV_I32_I64", 0x142) +_JIT_OPDEF("CONV_I32_U64", 0x143) +_JIT_OPDEF("CONV_I32_R32", 0x144) +_JIT_OPDEF("CONV_I32_R64", 0x145) + +_JIT_OPDEF("CONV_U32_I32", 0x146) +_JIT_OPDEF("CONV_U32_U32", 0x147) +_JIT_OPDEF("CONV_U32_I64", 0x148) +_JIT_OPDEF("CONV_U32_U64", 0x149) +_JIT_OPDEF("CONV_U32_R32", 0x14a) +_JIT_OPDEF("CONV_U32_R64", 0x14b) + +_JIT_OPDEF("CONV_I64_I32", 0x14c) +_JIT_OPDEF("CONV_I64_U32", 0x14d) +_JIT_OPDEF("CONV_I64_I64", 0x14e) // Not used +_JIT_OPDEF("CONV_I64_U64", 0x14f) // Not used +_JIT_OPDEF("CONV_I64_R32", 0x150) +_JIT_OPDEF("CONV_I64_R64", 0x151) + +_JIT_OPDEF("CONV_U64_I32", 0x152) +_JIT_OPDEF("CONV_U64_U32", 0x153) +_JIT_OPDEF("CONV_U64_I64", 0x154) // Not used +_JIT_OPDEF("CONV_U64_U64", 0x155) // Not used +_JIT_OPDEF("CONV_U64_R32", 0x156) +_JIT_OPDEF("CONV_U64_R64", 0x157) + +_JIT_OPDEF("CONV_R32_I32", 0x158) +_JIT_OPDEF("CONV_R32_U32", 0x159) +_JIT_OPDEF("CONV_R32_I64", 0x15a) +_JIT_OPDEF("CONV_R32_U64", 0x15b) +_JIT_OPDEF("CONV_R32_R32", 0x15c) +_JIT_OPDEF("CONV_R32_R64", 0x15d) + +_JIT_OPDEF("CONV_R64_I32", 0x15e) +_JIT_OPDEF("CONV_R64_U32", 0x15f) +_JIT_OPDEF("CONV_R64_I64", 0x160) +_JIT_OPDEF("CONV_R64_U64", 0x161) +_JIT_OPDEF("CONV_R64_R32", 0x162) +_JIT_OPDEF("CONV_R64_R64", 0x163) + +_JIT_OPDEF("INVOKE_SYSTEM_REFLECTION_METHODBASE", 0x164) +_JIT_OPDEF("REFLECTION_DYNAMICALLY_BOX_RETURN_VALUE", 0x165) + + default: return "undefined"; + } +} + +#endif diff --git a/src/DNA/native/src/Sys.h b/src/DNA/native/src/Sys.h index 1c188d37..abf24af2 100644 --- a/src/DNA/native/src/Sys.h +++ b/src/DNA/native/src/Sys.h @@ -34,6 +34,14 @@ void* mallocTrace(int s, char *pFile, int line); #define Assert(cond) #endif +#ifdef DEBUG_PRINT +#define dprintf(format, ...) printf(format, __VA_ARGS__) +#define dprintfn(format, ...) printf(format "\n", __VA_ARGS__) +#else +#define dprintf(format, ...) 0 +#define dprintfn(format, ...) 0 +#endif + #define FAKE_RETURN exit(101) #define INTERNALCALL_PARAM(ofs, type) *(type*)(pParams + ofs) @@ -55,4 +63,9 @@ U64 microTime(); #endif void SleepMS(U32 ms); +#ifdef DEBUG_PRINT +char* Sys_CIL_OpCodeName(U32 op); +char* Sys_JIT_OpCodeName(U32 op); +#endif + #endif diff --git a/src/DNA/native/src/System.Console.c b/src/DNA/native/src/System.Console.c index 61de03a1..f36c0b92 100644 --- a/src/DNA/native/src/System.Console.c +++ b/src/DNA/native/src/System.Console.c @@ -45,7 +45,7 @@ tAsyncCall* System_Console_Write(PTR pThis_, PTR pParams, PTR pReturnValue) { str8[i] = c?c:'?'; } str8[i] = 0; - printf(str8); + printf("%s", str8); strLen -= thisLen; start += thisLen; } diff --git a/src/DNA/native/src/System.Environment.c b/src/DNA/native/src/System.Environment.c index 83860ea9..4f689e9d 100644 --- a/src/DNA/native/src/System.Environment.c +++ b/src/DNA/native/src/System.Environment.c @@ -62,7 +62,7 @@ tAsyncCall* System_Environment_get_Platform(PTR pThis_, PTR pParams, PTR pReturn OSVERSIONINFO osVer; osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osVer); - *(U32*)pReturnValue = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)?2:1; // _WIN32NT:_WIN32Windows + *(U32*)pReturnValue = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)?2:1; // Win32NT:Win32Windows #else *(U32*)pReturnValue = 4; // UNIX #endif diff --git a/src/DNA/native/src/System.Math.c b/src/DNA/native/src/System.Math.c index 32a1d831..cda38b70 100644 --- a/src/DNA/native/src/System.Math.c +++ b/src/DNA/native/src/System.Math.c @@ -54,3 +54,21 @@ tAsyncCall* System_Math_Sqrt(PTR pThis_, PTR pParams, PTR pReturnValue) { return NULL; } + +tAsyncCall* System_Math_Ceiling(PTR pThis_, PTR pParams, PTR pReturnValue) { + *(double*)pReturnValue = ceil(INTERNALCALL_PARAM(0, double)); + + return NULL; +} + +tAsyncCall* System_Math_Floor(PTR pThis_, PTR pParams, PTR pReturnValue) { + *(double*)pReturnValue = floor(INTERNALCALL_PARAM(0, double)); + + return NULL; +} + +tAsyncCall* System_Math_Round(PTR pThis_, PTR pParams, PTR pReturnValue) { + *(double*)pReturnValue = round(INTERNALCALL_PARAM(0, double)); + + return NULL; +} diff --git a/src/DNA/native/src/System.Math.h b/src/DNA/native/src/System.Math.h index 74ad53dc..1b3223b2 100644 --- a/src/DNA/native/src/System.Math.h +++ b/src/DNA/native/src/System.Math.h @@ -28,5 +28,8 @@ tAsyncCall* System_Math_Cos(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Math_Tan(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Math_Pow(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Math_Sqrt(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_Math_Ceiling(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_Math_Floor(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_Math_Round(PTR pThis_, PTR pParams, PTR pReturnValue); #endif \ No newline at end of file diff --git a/src/DNA/native/src/System.Reflection.MethodBase.h b/src/DNA/native/src/System.Reflection.MethodBase.h index 0025073e..88799c9d 100644 --- a/src/DNA/native/src/System.Reflection.MethodBase.h +++ b/src/DNA/native/src/System.Reflection.MethodBase.h @@ -3,10 +3,11 @@ typedef struct tMethodBase_ tMethodBase; struct tMethodBase_ { - // Keep in sync with MethodBase class in .NET corlib code + // Keep in sync with System.Reflection.MethodBase.cs class in .NET corlib code HEAP_PTR ownerType; HEAP_PTR name; - tMD_MethodDef *methodDef; // Not accessed from .NET code + U32 flags; + tMD_MethodDef *methodDef; // Not accessed from .NET code }; #endif \ No newline at end of file diff --git a/src/DNA/native/src/System.Reflection.MethodInfo.h b/src/DNA/native/src/System.Reflection.MethodInfo.h index 7a529f1c..6b62a977 100644 --- a/src/DNA/native/src/System.Reflection.MethodInfo.h +++ b/src/DNA/native/src/System.Reflection.MethodInfo.h @@ -8,4 +8,6 @@ struct tMethodInfo_ { tMethodBase methodBase; }; +tAsyncCall* System_Reflection_MethodInfo_MakeGenericMethod(PTR pThis_, PTR pParams, PTR pReturnValue); + #endif \ No newline at end of file diff --git a/src/DNA/native/src/System.Reflection.PropertyInfo.h b/src/DNA/native/src/System.Reflection.PropertyInfo.h index bd1dfb17..74e8c22e 100644 --- a/src/DNA/native/src/System.Reflection.PropertyInfo.h +++ b/src/DNA/native/src/System.Reflection.PropertyInfo.h @@ -3,7 +3,7 @@ typedef struct tPropertyInfo_ tPropertyInfo; struct tPropertyInfo_ { - // Keep in sync with System.Reflection.PropertyInfo.cs + // Keep in sync with System.Reflection.PropertyInfo.cs in .NET corlib code HEAP_PTR ownerType; HEAP_PTR name; HEAP_PTR propertyType; diff --git a/src/DNA/native/src/System.RuntimeType.c b/src/DNA/native/src/System.RuntimeType.c index 14c70aed..3c28671f 100644 --- a/src/DNA/native/src/System.RuntimeType.c +++ b/src/DNA/native/src/System.RuntimeType.c @@ -146,6 +146,16 @@ tAsyncCall* System_RuntimeType_GetGenericArguments(PTR pThis_, PTR pParams, PTR return NULL; } +tAsyncCall* System_RuntimeType_IsDefined(PTR pThis_, PTR pParams, PTR pReturnValue) { + tMD_TypeDef *pType = ((tRuntimeType*)pThis_)->pTypeDef; + return NULL; +} + +tAsyncCall* System_RuntimeType_GetCustomAttributes(PTR pThis_, PTR pParams, PTR pReturnValue) { + tMD_TypeDef *pType = ((tRuntimeType*)pThis_)->pTypeDef; + return NULL; +} + tMD_TypeDef* RuntimeType_DeRef(PTR type) { return ((tRuntimeType*)type)->pTypeDef; } diff --git a/src/DNA/native/src/System.RuntimeType.h b/src/DNA/native/src/System.RuntimeType.h index d99b5a26..25916a83 100644 --- a/src/DNA/native/src/System.RuntimeType.h +++ b/src/DNA/native/src/System.RuntimeType.h @@ -38,6 +38,8 @@ tAsyncCall* System_RuntimeType_get_IsEnum(PTR pThis_, PTR pParams, PTR pReturnVa tAsyncCall* System_RuntimeType_get_IsGenericType(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_RuntimeType_Internal_GetGenericTypeDefinition(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_RuntimeType_GetGenericArguments(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_RuntimeType_IsDefined(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_RuntimeType_GetCustomAttributes(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_RuntimeType_GetElementType(PTR pThis_, PTR pParams, PTR pReturnValue); // Create a new heap object which is the RuntimeType object for the given type. diff --git a/src/DNA/native/src/System.String.c b/src/DNA/native/src/System.String.c index 13952a9e..f06675c9 100644 --- a/src/DNA/native/src/System.String.c +++ b/src/DNA/native/src/System.String.c @@ -19,6 +19,7 @@ // THE SOFTWARE. #include +#include #include "Compat.h" #include "Sys.h" @@ -67,6 +68,22 @@ tAsyncCall* System_String_ctor_CharInt32(PTR pThis_, PTR pParams, PTR pReturnVal return NULL; } +tAsyncCall* System_String_ctor_CharA(PTR pThis_, PTR pParams, PTR pReturnValue) { + tSystemString *pSystemString; + HEAP_PTR charArray; + PTR charElements; + U32 startIndex = 0, length = SystemArray_GetLength(((HEAP_PTR*)pParams)[0]); + + charArray = ((HEAP_PTR*)pParams)[0]; + + charElements = SystemArray_GetElements(charArray); + pSystemString = CreateStringHeapObj(length); + memcpy(pSystemString->chars, charElements + (startIndex << 1), length << 1); + *(HEAP_PTR*)pReturnValue = (HEAP_PTR)pSystemString; + + return NULL; +} + tAsyncCall* System_String_ctor_CharAIntInt(PTR pThis_, PTR pParams, PTR pReturnValue) { tSystemString *pSystemString; HEAP_PTR charArray; @@ -398,4 +415,10 @@ STRING2 SystemString_GetString(HEAP_PTR pThis_, U32 *pLength) { U32 SystemString_GetNumBytes(HEAP_PTR pThis_) { return (((tSystemString*)pThis_)->length << 1) + sizeof(tSystemString); -} \ No newline at end of file +} + +tAsyncCall* System_String_ToDouble(PTR pThis_, PTR pParams, PTR pReturnValue) { + tSystemString *pThis = (tSystemString*)pThis_; + *(double*)pReturnValue = wcstod((const wchar_t *)pThis->chars, NULL); + return NULL; +} diff --git a/src/DNA/native/src/System.String.h b/src/DNA/native/src/System.String.h index d6689e5c..96a4b5b5 100644 --- a/src/DNA/native/src/System.String.h +++ b/src/DNA/native/src/System.String.h @@ -25,6 +25,7 @@ #include "Types.h" tAsyncCall* System_String_ctor_CharInt32(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_String_ctor_CharA(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_String_ctor_CharAIntInt(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_String_ctor_StringIntInt(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_String_get_Chars(PTR pThis_, PTR pParams, PTR pReturnValue); @@ -42,4 +43,6 @@ HEAP_PTR SystemString_FromCharPtrUTF16(U16 *pStr); STRING2 SystemString_GetString(HEAP_PTR pThis_, U32 *pLength); U32 SystemString_GetNumBytes(HEAP_PTR pThis_); +tAsyncCall* System_String_ToDouble(PTR pThis_, PTR pParams, PTR pReturnValue); + #endif \ No newline at end of file diff --git a/src/DNA/native/src/System.Type.c b/src/DNA/native/src/System.Type.c index 9701cc9f..5a661584 100644 --- a/src/DNA/native/src/System.Type.c +++ b/src/DNA/native/src/System.Type.c @@ -135,10 +135,8 @@ tAsyncCall* System_Type_GetProperties(PTR pThis_, PTR pParams, PTR pReturnValue) tPropertyInfo *pPropertyInfo = (tPropertyInfo*)Heap_AllocType(types[TYPE_SYSTEM_REFLECTION_PROPERTYINFO]); SystemArray_StoreElement(ret, i, (PTR)&pPropertyInfo); - // Assign ownerType + // Assign ownerType and name pPropertyInfo->ownerType = pThis_; - - // Assign name pPropertyInfo->name = SystemString_FromCharPtrASCII(pPropertyMetadata->name); // Assign propertyType @@ -158,6 +156,38 @@ tAsyncCall* System_Type_GetProperties(PTR pThis_, PTR pParams, PTR pReturnValue) return NULL; } +tAsyncCall* System_Type_GetMethods(PTR pThis_, PTR pParams, PTR pReturnValue) +{ + // Get metadata for the 'this' type + tRuntimeType *pRuntimeType = (tRuntimeType*)pThis_; + tMD_TypeDef *pTypeDef = pRuntimeType->pTypeDef; + + // Instantiate a MethodInfo[] + tMD_TypeDef *pArrayType = Type_GetArrayTypeDef(types[TYPE_SYSTEM_REFLECTION_METHODINFO], NULL, NULL); + HEAP_PTR ret = SystemArray_NewVector(pArrayType, pTypeDef->numMethods); + // Allocate to return value straight away, so it cannot be GCed + *(HEAP_PTR*)pReturnValue = ret; + + // Search for the method by name + for (U32 i = 0; inumMethods; i++) { + tMD_MethodDef *pMethodDef = pTypeDef->ppMethods[i]; + + // Instantiate a MethodInfo and put it in the array + tMethodInfo *pMethodInfo = (tMethodInfo*)Heap_AllocType(types[TYPE_SYSTEM_REFLECTION_METHODINFO]); + SystemArray_StoreElement(ret, i, (PTR)&pMethodInfo); + + // Assign ownerType, name and flags + pMethodInfo->methodBase.ownerType = pThis_; + pMethodInfo->methodBase.name = SystemString_FromCharPtrASCII(pMethodDef->name); + pMethodInfo->methodBase.flags = pMethodDef->flags; + + // Assign method def + pMethodInfo->methodBase.methodDef = pMethodDef; + } + + return NULL; +} + tAsyncCall* System_Type_GetMethod(PTR pThis_, PTR pParams, PTR pReturnValue) { // Read param @@ -176,11 +206,10 @@ tAsyncCall* System_Type_GetMethod(PTR pThis_, PTR pParams, PTR pReturnValue) // Instantiate a MethodInfo tMethodInfo *pMethodInfo = (tMethodInfo*)Heap_AllocType(types[TYPE_SYSTEM_REFLECTION_METHODINFO]); - // Assign ownerType + // Assign ownerType, name and flags pMethodInfo->methodBase.ownerType = pThis_; - - // Assign name pMethodInfo->methodBase.name = SystemString_FromCharPtrASCII(pMethodDef->name); + pMethodInfo->methodBase.flags = pMethodDef->flags; // Assign method def pMethodInfo->methodBase.methodDef = pMethodDef; @@ -194,3 +223,39 @@ tAsyncCall* System_Type_GetMethod(PTR pThis_, PTR pParams, PTR pReturnValue) *(HEAP_PTR*)pReturnValue = NULL; return NULL; } + +tAsyncCall* System_Reflection_MethodInfo_MakeGenericMethod(PTR pThis_, PTR pParams, PTR pReturnValue) +{ + // get type arguments + HEAP_PTR pTypeArgs = ((HEAP_PTR*)pParams)[0]; + U32 argCount = SystemArray_GetLength(pTypeArgs); + HEAP_PTR* pArray = (HEAP_PTR*)SystemArray_GetElements(pTypeArgs); + + // Get metadata for the 'this' type + tMethodInfo *pMethodInfoThis = (tMethodInfo*)pThis_; + tMD_MethodDef *pCoreMethod = pMethodInfoThis->methodBase.methodDef; + + // get arg types + tMD_TypeDef **ppTypeArgs = malloc(argCount * sizeof(tMD_TypeDef*)); + for (U32 i = 0; i < argCount; i++) { + ppTypeArgs[i] = Heap_GetType(pArray[i]); + } + + // specialize generic method + tMD_MethodDef *pMethodDef = Generics_GetMethodDefFromCoreMethod(pCoreMethod, pCoreMethod->pParentType, argCount, ppTypeArgs); + free(ppTypeArgs); + + // Instantiate a MethodInfo + tMethodInfo *pMethodInfo = (tMethodInfo*)Heap_AllocType(types[TYPE_SYSTEM_REFLECTION_METHODINFO]); + + // Assign ownerType, name and flags + pMethodInfo->methodBase.ownerType = pThis_; + pMethodInfo->methodBase.name = SystemString_FromCharPtrASCII(pMethodDef->name); + pMethodInfo->methodBase.flags = pMethodDef->flags; + + // Assign method def + pMethodInfo->methodBase.methodDef = pMethodDef; + + *(HEAP_PTR*)pReturnValue = (HEAP_PTR)pMethodInfo; + return NULL; +} diff --git a/src/DNA/native/src/System.Type.h b/src/DNA/native/src/System.Type.h index d75441dd..6afdedc4 100644 --- a/src/DNA/native/src/System.Type.h +++ b/src/DNA/native/src/System.Type.h @@ -29,6 +29,7 @@ tAsyncCall* System_Type_get_IsValueType(PTR pThis_, PTR pParams, PTR pReturnValu tAsyncCall* System_Type_GetTypeFromName(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Type_EnsureAssemblyLoaded(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Type_GetProperties(PTR pThis_, PTR pParams, PTR pReturnValue); +tAsyncCall* System_Type_GetMethods(PTR pThis_, PTR pParams, PTR pReturnValue); tAsyncCall* System_Type_GetMethod(PTR pThis_, PTR pParams, PTR pReturnValue); #endif \ No newline at end of file diff --git a/src/DNA/native/src/Thread.h b/src/DNA/native/src/Thread.h index db22e9af..3005d307 100644 --- a/src/DNA/native/src/Thread.h +++ b/src/DNA/native/src/Thread.h @@ -29,7 +29,7 @@ typedef struct tThreadStack_ tThreadStack; #include "Heap.h" #include "Types.h" -#define THREADSTACK_CHUNK_SIZE 10000 +#define THREADSTACK_CHUNK_SIZE 20000 struct tThreadStack_ { // This chunk of stack memory diff --git a/src/DNA/native/src/Type.c b/src/DNA/native/src/Type.c index 37750ec6..82a58c2b 100644 --- a/src/DNA/native/src/Type.c +++ b/src/DNA/native/src/Type.c @@ -321,11 +321,15 @@ tMD_TypeDef* Type_GetTypeFromSig(tMetaData *pMetaData, SIG *pSig, tMD_TypeDef ** case ELEMENT_TYPE_MVAR: entry = MetaData_DecodeSigEntry(pSig); // This is the argument number - if (ppMethodTypeArgs == NULL) { - // Can't do anything sensible, as we don't have any type args - return NULL; - } else { + if (ppMethodTypeArgs != NULL) { return ppMethodTypeArgs[entry]; + } else { + if (ppClassTypeArgs != NULL) { + return ppClassTypeArgs[entry]; + } else { + // Can't do anything sensible, as we don't have any type args + return NULL; + } } default: @@ -461,7 +465,7 @@ U32 Type_IsMethod(tMD_MethodDef *pMethod, STRING name, tMD_TypeDef *pReturnType, sig = MetaData_GetBlob(pMethod->signature, &sigLen); i = MetaData_DecodeSigEntry(&sig); // Don't care about this - if (i & SIG_METHODDEF_GENERIC) { + if (i & SIG_CALLCONV_GENERIC) { MetaData_DecodeSigEntry(&sig); } numSigParams = MetaData_DecodeSigEntry(&sig); @@ -527,4 +531,4 @@ HEAP_PTR Type_GetTypeObject(tMD_TypeDef *pTypeDef) { pTypeDef->typeObject = RuntimeType_New(pTypeDef); } return pTypeDef->typeObject; -} \ No newline at end of file +}