diff --git a/Assets/XIL/ILSource/ILRuntime/Other/ThreadSafeDictionary.cs b/Assets/XIL/ILSource/ILRuntime/Other/ThreadSafeDictionary.cs index 1b480d2d..2b6e4f1c 100644 --- a/Assets/XIL/ILSource/ILRuntime/Other/ThreadSafeDictionary.cs +++ b/Assets/XIL/ILSource/ILRuntime/Other/ThreadSafeDictionary.cs @@ -1,132 +1,130 @@ -#if USE_HOT using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Runtime.Versioning; -using System.Threading; - -namespace ILRuntime.Other -{ - /// - /// A thread safe dictionary for internal use - /// - /// - /// - class ThreadSafeDictionary : IDictionary - { - Dictionary dic = new Dictionary(); - - public Dictionary InnerDictionary { get { return dic; } } - public V this[K key] - { - get - { - lock(dic) - return dic[key]; - } - - set - { - lock(dic) - dic[key] = value; - } - } - - public int Count - { - get - { - lock(dic) - return dic.Count; - } - } - - public bool IsReadOnly - { - get - { - lock(dic) - return IsReadOnly; - } - } - - public ICollection Keys - { - get - { - throw new NotImplementedException(); - } - } - - public ICollection Values - { - get - { - throw new NotImplementedException(); - } - } - - public void Add(KeyValuePair item) - { - lock (dic) - dic.Add(item.Key, item.Value); - } - - public void Add(K key, V value) - { - lock(dic) - dic.Add(key, value); - } - - public void Clear() - { - lock(dic) - dic.Clear(); - } - - public bool Contains(KeyValuePair item) - { - lock(dic) - return dic.ContainsKey(item.Key); - } - - public bool ContainsKey(K key) - { - lock(dic) - return dic.ContainsKey(key); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - public IEnumerator> GetEnumerator() - { - throw new NotImplementedException(); - } - - public bool Remove(KeyValuePair item) - { - throw new NotImplementedException(); - } - - public bool Remove(K key) - { - lock(dic) - return dic.Remove(key); - } - - public bool TryGetValue(K key, out V value) - { - lock(dic) - return dic.TryGetValue(key, out value); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - } -} #endif \ No newline at end of file +#if USE_HOT +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Runtime.Versioning; +using System.Threading; + +namespace ILRuntime.Other +{ + /// + /// A thread safe dictionary for internal use + /// + /// + /// + class ThreadSafeDictionary : IDictionary + { + Dictionary dic = new Dictionary(); + + public Dictionary InnerDictionary { get { return dic; } } + public V this[K key] + { + get + { + return dic[key]; + } + + set + { + lock(dic) + dic[key] = value; + } + } + + public int Count + { + get + { + lock(dic) + return dic.Count; + } + } + + public bool IsReadOnly + { + get + { + lock(dic) + return IsReadOnly; + } + } + + public ICollection Keys + { + get + { + throw new NotImplementedException(); + } + } + + public ICollection Values + { + get + { + throw new NotImplementedException(); + } + } + + public void Add(KeyValuePair item) + { + lock (dic) + dic.Add(item.Key, item.Value); + } + + public void Add(K key, V value) + { + lock(dic) + dic.Add(key, value); + } + + public void Clear() + { + lock(dic) + dic.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return dic.ContainsKey(item.Key); + } + + public bool ContainsKey(K key) + { + return dic.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public IEnumerator> GetEnumerator() + { + throw new NotImplementedException(); + } + + public bool Remove(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public bool Remove(K key) + { + lock(dic) + return dic.Remove(key); + } + + public bool TryGetValue(K key, out V value) + { + return dic.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/XIL/ILSource/ILRuntime/Other/UncheckedList.cs b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedList.cs index de0568a2..3e4974d8 100644 --- a/Assets/XIL/ILSource/ILRuntime/Other/UncheckedList.cs +++ b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedList.cs @@ -1,999 +1,996 @@ -#if USE_HOT using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Runtime.Versioning; -using System.Threading; - -namespace ILRuntime.Other -{ - /// - /// This is a copy of the latest .NET framework 4.5 List implementation, with all extraneous checking removed. - /// - /// - [Serializable] - public class UncheckedList : IList, ICollection, IEnumerable, IEnumerable, IList, ICollection - { - - private const int _defaultCapacity = 4; - - private T[] _items; - private int _size; - private int _version; - [NonSerialized] - private Object _syncRoot; - - private static readonly T[] _emptyArray = new T[0]; - - // Constructs a UncheckedList. The list is initially empty and has a capacity - // of zero. Upon adding the first element to the list the capacity is - // increased to _defaultCapacity, and then increased in multiples of two - // as required. - public UncheckedList() - { - _items = _emptyArray; - } - - // Constructs a UncheckedList with a given initial capacity. The list is - // initially empty, but will have room for the given number of elements - // before any reallocations are required. - // - public UncheckedList(int capacity) - { - if (capacity == 0) - _items = _emptyArray; - else - _items = new T[capacity]; - } - - // Constructs a UncheckedList, copying the contents of the given collection. The - // size and capacity of the new list will both be equal to the size of the - // given collection. - // - public UncheckedList(IEnumerable collection) - { - ICollection c = collection as ICollection; - if (c != null) - { - int count = c.Count; - if (count == 0) - { - _items = _emptyArray; - } - else - { - _items = new T[count]; - c.CopyTo(_items, 0); - _size = count; - } - } - else - { - _size = 0; - _items = _emptyArray; - AddEnumerable(collection); - } - } - - // Gets and sets the capacity of this list. The capacity is the size of - // the internal array used to hold items. When set, the internal - // array of the list is reallocated to the given capacity. - // - public int Capacity - { - get - { - return _items.Length; - } - set - { - if (value != _items.Length) - { - if (value > 0) - { - T[] newItems = new T[value]; - if (_size > 0) - { - Array.Copy(_items, 0, newItems, 0, _size); - } - _items = newItems; - } - else - { - _items = _emptyArray; - } - } - } - } - - // Read-only property describing how many elements are in the UncheckedList. - public int Count - { - get - { - return _size; - } - } - - bool System.Collections.IList.IsFixedSize - { - get { return false; } - } - - - // Is this UncheckedList read-only? - bool ICollection.IsReadOnly - { - get { return false; } - } - - bool System.Collections.IList.IsReadOnly - { - get { return false; } - } - - // Is this UncheckedList synchronized (thread-safe)? - bool System.Collections.ICollection.IsSynchronized - { - get { return false; } - } - - // Synchronization root for this object. - Object System.Collections.ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); - } - return _syncRoot; - } - } - // Sets or Gets the element at the given index. - // - public T this[int index] - { - get - { - return _items[index]; - } - - set - { - _items[index] = value; - _version++; - } - } - - private static bool IsCompatibleObject(object value) - { - // Non-null values are fine. Only accept nulls if T is a class or Nullable. - // Note that default(T) is not equal to null for value types except when T is Nullable. - return ((value is T) || (value == null && default(T) == null)); - } - - Object System.Collections.IList.this[int index] - { - get - { - return this[index]; - } - set - { - try - { - this[index] = (T)value; - } - catch (InvalidCastException) - { - } - } - } - - // Adds the given object to the end of this list. The size of the list is - // increased by one. If required, the capacity of the list is doubled - // before adding the new element. - public void Add(T item) - { - var array = _items; - var size = _size; - _version++; - if ((uint)size < (uint)array.Length) - { - _size = size + 1; - array[size] = item; - } - else - { - AddWithResize(item); - } - } - - // Non-inline from UncheckedList.Add to improve its code quality as uncommon path - private void AddWithResize(T item) - { - var size = _size; - EnsureCapacity(size + 1); - _size = size + 1; - _items[size] = item; - } - - int System.Collections.IList.Add(Object item) - { - try - { - Add((T)item); - } - catch (InvalidCastException) - { - } - - return Count - 1; - } - - - // Adds the elements of the given collection to the end of this list. If - // required, the capacity of the list is increased to twice the previous - // capacity or the new size, whichever is larger. - // - public void AddRange(IEnumerable collection) - { - InsertRange(_size, collection); - } - - public ReadOnlyCollection AsReadOnly() - { - return new ReadOnlyCollection(this); - } - - // Searches a section of the list for a given element using a binary search - // algorithm. Elements of the list are compared to the search value using - // the given IComparer interface. If comparer is null, elements of - // the list are compared to the search value using the IComparable - // interface, which in that case must be implemented by all elements of the - // list and the given search value. This method assumes that the given - // section of the list is already sorted; if this is not the case, the - // result will be incorrect. - // - // The method returns the index of the given value in the list. If the - // list does not contain the given value, the method returns a negative - // integer. The bitwise complement operator (~) can be applied to a - // negative result to produce the index of the first element (if any) that - // is larger than the given search value. This is also the index at which - // the search value should be inserted into the list in order for the list - // to remain sorted. - // - // The method uses the Array.BinarySearch method to perform the - // search. - // - public int BinarySearch(int index, int count, T item, IComparer comparer) - { - if (index < 0) return -1; - return Array.BinarySearch(_items, index, count, item, comparer); - } - - public int BinarySearch(T item) - { - return BinarySearch(0, Count, item, null); - } - - public int BinarySearch(T item, IComparer comparer) - { - return BinarySearch(0, Count, item, comparer); - } - - - // Clears the contents of UncheckedList. - public void Clear() - { - if (!typeof(T).IsValueType) - { - int size = _size; - _size = 0; - _version++; - if (size > 0) - { - Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references. - } - } - else - { - _size = 0; - _version++; - } - } - - // Contains returns true if the specified element is in the UncheckedList. - // It does a linear, O(n) search. Equality is determined by calling - // EqualityComparer.Default.Equals(). - - public bool Contains(T item) - { - // PERF: IndexOf calls Array.IndexOf, which internally - // calls EqualityComparer.Default.IndexOf, which - // is specialized for different types. This - // boosts performance since instead of making a - // virtual method call each iteration of the loop, - // via EqualityComparer.Default.Equals, we - // only make one virtual call to EqualityComparer.IndexOf. - - return _size != 0 && IndexOf(item) != -1; - } - - bool System.Collections.IList.Contains(Object item) - { - if (IsCompatibleObject(item)) - { - return Contains((T)item); - } - return false; - } - - public UncheckedList ConvertAll(Converter converter) - { - UncheckedList list = new UncheckedList(_size); - for (int i = 0; i < _size; i++) - { - list._items[i] = converter(_items[i]); - } - list._size = _size; - return list; - } - - // Copies this UncheckedList into array, which must be of a - // compatible array type. - // - public void CopyTo(T[] array) - { - CopyTo(array, 0); - } - - // Copies this UncheckedList into array, which must be of a - // compatible array type. - // - void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) - { - try - { - // Array.Copy will check for NULL. - Array.Copy(_items, 0, array, arrayIndex, _size); - } - catch (ArrayTypeMismatchException) - { - } - } - - // Copies a section of this list to the given array at the given index. - // - // The method uses the Array.Copy method to copy the elements. - // - public void CopyTo(int index, T[] array, int arrayIndex, int count) - { - // Delegate rest of error checking to Array.Copy. - Array.Copy(_items, index, array, arrayIndex, count); - } - - public void CopyTo(T[] array, int arrayIndex) - { - // Delegate rest of error checking to Array.Copy. - Array.Copy(_items, 0, array, arrayIndex, _size); - } - - // Ensures that the capacity of this list is at least the given minimum - // value. If the current capacity of the list is less than min, the - // capacity is increased to twice the current capacity or to min, - // whichever is larger. - private void EnsureCapacity(int min) - { - if (_items.Length < min) - { - int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2; - // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - if ((uint) newCapacity > Int32.MaxValue) newCapacity = Int32.MaxValue; - if (newCapacity < min) newCapacity = min; - Capacity = newCapacity; - } - } - - public bool Exists(Predicate match) - { - return FindIndex(match) != -1; - } - - public T Find(Predicate match) - { - for (int i = 0; i < _size; i++) - { - if (match(_items[i])) - { - return _items[i]; - } - } - return default(T); - } - - public UncheckedList FindAll(Predicate match) - { - UncheckedList list = new UncheckedList(); - for (int i = 0; i < _size; i++) - { - if (match(_items[i])) - { - list.Add(_items[i]); - } - } - return list; - } - - public int FindIndex(Predicate match) - { - return FindIndex(0, _size, match); - } - - public int FindIndex(int startIndex, Predicate match) - { - return FindIndex(startIndex, _size - startIndex, match); - } - - public int FindIndex(int startIndex, int count, Predicate match) - { - int endIndex = startIndex + count; - for (int i = startIndex; i < endIndex; i++) - { - if (match(_items[i])) return i; - } - return -1; - } - - public T FindLast(Predicate match) - { - for (int i = _size - 1; i >= 0; i--) - { - if (match(_items[i])) - { - return _items[i]; - } - } - return default(T); - } - - public int FindLastIndex(Predicate match) - { - return FindLastIndex(_size - 1, _size, match); - } - - public int FindLastIndex(int startIndex, Predicate match) - { - return FindLastIndex(startIndex, startIndex + 1, match); - } - - public int FindLastIndex(int startIndex, int count, Predicate match) - { - int endIndex = startIndex - count; - for (int i = startIndex; i > endIndex; i--) - { - if (match(_items[i])) - { - return i; - } - } - return -1; - } - - public void ForEach(Action action) - { - int version = _version; - - for (int i = 0; i < _size; i++) - { - if (version != _version) - { - break; - } - action(_items[i]); - } - } - - // Returns an enumerator for this list with the given - // permission for removal of elements. If modifications made to the list - // while an enumeration is in progress, the MoveNext and - // GetObject methods of the enumerator will throw an exception. - // - public Enumerator GetEnumerator() - { - return new Enumerator(this); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - public UncheckedList GetRange(int index, int count) - { - UncheckedList list = new UncheckedList(count); - Array.Copy(_items, index, list._items, 0, count); - list._size = count; - return list; - } - - - // Returns the index of the first occurrence of a given value in a range of - // this list. The list is searched forwards from beginning to end. - // The elements of the list are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item) - { - return Array.IndexOf(_items, item, 0, _size); - } - - int System.Collections.IList.IndexOf(Object item) - { - if (IsCompatibleObject(item)) - { - return IndexOf((T)item); - } - return -1; - } - - // Returns the index of the first occurrence of a given value in a range of - // this list. The list is searched forwards, starting at index - // index and ending at count number of elements. The - // elements of the list are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item, int index) - { - return Array.IndexOf(_items, item, index, _size - index); - } - - // Returns the index of the first occurrence of a given value in a range of - // this list. The list is searched forwards, starting at index - // index and upto count number of elements. The - // elements of the list are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item, int index, int count) - { - return Array.IndexOf(_items, item, index, count); - } - - // Inserts an element into this list at a given index. The size of the list - // is increased by one. If required, the capacity of the list is doubled - // before inserting the new element. - // - public void Insert(int index, T item) - { - if (_size == _items.Length) EnsureCapacity(_size + 1); - if (index < _size) - { - Array.Copy(_items, index, _items, index + 1, _size - index); - } - _items[index] = item; - _size++; - _version++; - } - - void System.Collections.IList.Insert(int index, Object item) - { - try - { - Insert(index, (T)item); - } - catch (InvalidCastException) - { - } - } - - // Inserts the elements of the given collection at a given index. If - // required, the capacity of the list is increased to twice the previous - // capacity or the new size, whichever is larger. Ranges may be added - // to the end of the list by setting index to the UncheckedList's size. - // - public void InsertRange(int index, IEnumerable collection) - { - ICollection c = collection as ICollection; - if (c != null) - { // if collection is ICollection - int count = c.Count; - if (count > 0) - { - EnsureCapacity(_size + count); - if (index < _size) - { - Array.Copy(_items, index, _items, index + count, _size - index); - } - - // If we're inserting a UncheckedList into itself, we want to be able to deal with that. - if (this == c) - { - // Copy first part of _items to insert location - Array.Copy(_items, 0, _items, index, index); - // Copy last part of _items back to inserted location - Array.Copy(_items, index + count, _items, index * 2, _size - index); - } - else - { - c.CopyTo(_items, index); - } - _size += count; - } - } - else if (index < _size) - { - // We're inserting a lazy enumerable. Call Insert on each of the constituent items. - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Insert(index++, en.Current); - } - } - } - else - { - // We're adding a lazy enumerable because the index is at the end of this list. - AddEnumerable(collection); - } - _version++; - } - - // Returns the index of the last occurrence of a given value in a range of - // this list. The list is searched backwards, starting at the end - // and ending at the first element in the list. The elements of the list - // are compared to the given value using the Object.Equals method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item) - { - if (_size == 0) - { // Special case for empty list - return -1; - } - else - { - return LastIndexOf(item, _size - 1, _size); - } - } - - // Returns the index of the last occurrence of a given value in a range of - // this list. The list is searched backwards, starting at index - // index and ending at the first element in the list. The - // elements of the list are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item, int index) - { - return LastIndexOf(item, index, index + 1); - } - - // Returns the index of the last occurrence of a given value in a range of - // this list. The list is searched backwards, starting at index - // index and upto count elements. The elements of - // the list are compared to the given value using the Object.Equals - // method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item, int index, int count) - { - if (_size == 0) - { // Special case for empty list - return -1; - } - - return Array.LastIndexOf(_items, item, index, count); - } - - // Removes the element at the given index. The size of the list is - // decreased by one. - // - public bool Remove(T item) - { - int index = IndexOf(item); - if (index >= 0) - { - RemoveAt(index); - return true; - } - - return false; - } - - void System.Collections.IList.Remove(Object item) - { - if (IsCompatibleObject(item)) - { - Remove((T)item); - } - } - - // This method removes all items which matches the predicate. - // The complexity is O(n). - public int RemoveAll(Predicate match) - { - int freeIndex = 0; // the first free slot in items array - - // Find the first item which needs to be removed. - while (freeIndex < _size && !match(_items[freeIndex])) freeIndex++; - if (freeIndex >= _size) return 0; - - int current = freeIndex + 1; - while (current < _size) - { - // Find the first item which needs to be kept. - while (current < _size && match(_items[current])) current++; - - if (current < _size) - { - // copy item to the free slot. - _items[freeIndex++] = _items[current++]; - } - } - - if (!typeof(T).IsValueType) - { - Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references. - } - - int result = _size - freeIndex; - _size = freeIndex; - _version++; - return result; - } - - // Removes the element at the given index. The size of the list is - // decreased by one. - // - public void RemoveAt(int index) - { - _size--; - if (index < _size) - { - Array.Copy(_items, index + 1, _items, index, _size - index); - } - if (!typeof(T).IsValueType) - { - _items[_size] = default(T); - } - _version++; - } - - // Removes a range of elements from this list. - // - public void RemoveRange(int index, int count) - { - if (count > 0) - { - int i = _size; - _size -= count; - if (index < _size) - { - Array.Copy(_items, index + count, _items, index, _size - index); - } - - _version++; - if (!typeof(T).IsValueType) - { - Array.Clear(_items, _size, count); - } - } - } - - // Reverses the elements in this list. - public void Reverse() - { - Reverse(0, Count); - } - - // Reverses the elements in a range of this list. Following a call to this - // method, an element in the range given by index and count - // which was previously located at index i will now be located at - // index index + (index + count - i - 1). - // - public void Reverse(int index, int count) - { - if (count > 1) - { - Array.Reverse(_items, index, count); - } - _version++; - } - - // Sorts the elements in this list. Uses the default comparer and - // Array.Sort. - public void Sort() - { - Sort(0, Count, null); - } - - // Sorts the elements in this list. Uses Array.Sort with the - // provided comparer. - public void Sort(IComparer comparer) - { - Sort(0, Count, comparer); - } - - // Sorts the elements in a section of this list. The sort compares the - // elements to each other using the given IComparer interface. If - // comparer is null, the elements are compared to each other using - // the IComparable interface, which in that case must be implemented by all - // elements of the list. - // - // This method uses the Array.Sort method to sort the elements. - // - public void Sort(int index, int count, IComparer comparer) - { - if (count > 1) - { - Array.Sort(_items, index, count, comparer); - } - _version++; - } - - public void Sort(Comparison comparison) - { - throw new NotImplementedException(); - /*if (_size > 1) - { - ArraySortHelper.Sort(_items, 0, _size, comparison); - } - _version++;*/ - } - - // ToArray returns an array containing the contents of the UncheckedList. - // This requires copying the UncheckedList, which is an O(n) operation. - public T[] ToArray() - { - if (_size == 0) - { - return _emptyArray; - } - - T[] array = new T[_size]; - Array.Copy(_items, 0, array, 0, _size); - return array; - } - - // Sets the capacity of this list to the size of the list. This method can - // be used to minimize a list's memory overhead once it is known that no - // new elements will be added to the list. To completely clear a list and - // release all memory referenced by the list, execute the following - // statements: - // - // list.Clear(); - // list.TrimExcess(); - // - public void TrimExcess() - { - int threshold = (int)(((double)_items.Length) * 0.9); - if (_size < threshold) - { - Capacity = _size; - } - } - - public bool TrueForAll(Predicate match) - { - for (int i = 0; i < _size; i++) - { - if (!match(_items[i])) - { - return false; - } - } - return true; - } - - private void AddEnumerable(IEnumerable enumerable) - { - Debug.Assert(enumerable != null); - Debug.Assert(!(enumerable is ICollection), "We should have optimized for this beforehand."); - - using (IEnumerator en = enumerable.GetEnumerator()) - { - _version++; // Even if the enumerable has no items, we can update _version. - - while (en.MoveNext()) - { - // Capture Current before doing anything else. If this throws - // an exception, we want to make a clean break. - T current = en.Current; - - if (_size == _items.Length) - { - EnsureCapacity(_size + 1); - } - - _items[_size++] = current; - } - } - } - - public struct Enumerator : IEnumerator, System.Collections.IEnumerator - { - private UncheckedList list; - private int index; - private int version; - private T current; - - internal Enumerator(UncheckedList list) - { - this.list = list; - index = 0; - version = list._version; - current = default(T); - } - - public void Dispose() - { - } - - public bool MoveNext() - { - UncheckedList localUncheckedList = list; - - if (version == localUncheckedList._version && ((uint)index < (uint)localUncheckedList._size)) - { - current = localUncheckedList._items[index]; - index++; - return true; - } - return MoveNextRare(); - } - - private bool MoveNextRare() - { - index = list._size + 1; - current = default(T); - return false; - } - - public T Current - { - get - { - return current; - } - } - - Object System.Collections.IEnumerator.Current - { - get - { - return Current; - } - } - - void System.Collections.IEnumerator.Reset() - { - index = 0; - current = default(T); - } - } - } -} #endif \ No newline at end of file +#if USE_HOT +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Runtime.Versioning; +using System.Threading; + +namespace ILRuntime.Other +{ + /// + /// This is a copy of the latest .NET framework 4.5 List implementation, with all extraneous checking removed. + /// + /// + [Serializable] + public class UncheckedList : IList, ICollection, IEnumerable, IEnumerable, IList, ICollection + { + + private const int _defaultCapacity = 4; + + private T[] _items; + private int _size; + private int _version; + [NonSerialized] + private Object _syncRoot; + + private static readonly T[] _emptyArray = new T[0]; + + // Constructs a UncheckedList. The list is initially empty and has a capacity + // of zero. Upon adding the first element to the list the capacity is + // increased to _defaultCapacity, and then increased in multiples of two + // as required. + public UncheckedList() + { + _items = _emptyArray; + } + + // Constructs a UncheckedList with a given initial capacity. The list is + // initially empty, but will have room for the given number of elements + // before any reallocations are required. + // + public UncheckedList(int capacity) + { + if (capacity == 0) + _items = _emptyArray; + else + _items = new T[capacity]; + } + + // Constructs a UncheckedList, copying the contents of the given collection. The + // size and capacity of the new list will both be equal to the size of the + // given collection. + // + public UncheckedList(IEnumerable collection) + { + ICollection c = collection as ICollection; + if (c != null) + { + int count = c.Count; + if (count == 0) + { + _items = _emptyArray; + } + else + { + _items = new T[count]; + c.CopyTo(_items, 0); + _size = count; + } + } + else + { + _size = 0; + _items = _emptyArray; + AddEnumerable(collection); + } + } + + // Gets and sets the capacity of this list. The capacity is the size of + // the internal array used to hold items. When set, the internal + // array of the list is reallocated to the given capacity. + // + public int Capacity + { + get + { + return _items.Length; + } + set + { + if (value != _items.Length) + { + if (value > 0) + { + T[] newItems = new T[value]; + if (_size > 0) + { + Array.Copy(_items, 0, newItems, 0, _size); + } + _items = newItems; + } + else + { + _items = _emptyArray; + } + } + } + } + + // Read-only property describing how many elements are in the UncheckedList. + public int Count + { + get + { + return _size; + } + } + + bool System.Collections.IList.IsFixedSize + { + get { return false; } + } + + + // Is this UncheckedList read-only? + bool ICollection.IsReadOnly + { + get { return false; } + } + + bool System.Collections.IList.IsReadOnly + { + get { return false; } + } + + // Is this UncheckedList synchronized (thread-safe)? + bool System.Collections.ICollection.IsSynchronized + { + get { return false; } + } + + // Synchronization root for this object. + Object System.Collections.ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); + } + return _syncRoot; + } + } + // Sets or Gets the element at the given index. + // + public T this[int index] + { + get + { + return _items[index]; + } + + set + { + _items[index] = value; + _version++; + } + } + + private static bool IsCompatibleObject(object value) + { + // Non-null values are fine. Only accept nulls if T is a class or Nullable. + // Note that default(T) is not equal to null for value types except when T is Nullable. + return ((value is T) || (value == null && default(T) == null)); + } + + Object System.Collections.IList.this[int index] + { + get + { + return this[index]; + } + set + { + try + { + this[index] = (T)value; + } + catch (InvalidCastException) + { + } + } + } + + // Adds the given object to the end of this list. The size of the list is + // increased by one. If required, the capacity of the list is doubled + // before adding the new element. + public void Add(T item) + { + var array = _items; + var size = _size; + if ((uint)size < (uint)array.Length) + { + _size = size + 1; + array[size] = item; + } + else + { + AddWithResize(item); + } + } + + // Non-inline from UncheckedList.Add to improve its code quality as uncommon path + private void AddWithResize(T item) + { + var size = _size; + EnsureCapacity(size + 1); + _size = size + 1; + _items[size] = item; + } + + int System.Collections.IList.Add(Object item) + { + try + { + Add((T)item); + } + catch (InvalidCastException) + { + } + + return Count - 1; + } + + + // Adds the elements of the given collection to the end of this list. If + // required, the capacity of the list is increased to twice the previous + // capacity or the new size, whichever is larger. + // + public void AddRange(IEnumerable collection) + { + InsertRange(_size, collection); + } + + public ReadOnlyCollection AsReadOnly() + { + return new ReadOnlyCollection(this); + } + + // Searches a section of the list for a given element using a binary search + // algorithm. Elements of the list are compared to the search value using + // the given IComparer interface. If comparer is null, elements of + // the list are compared to the search value using the IComparable + // interface, which in that case must be implemented by all elements of the + // list and the given search value. This method assumes that the given + // section of the list is already sorted; if this is not the case, the + // result will be incorrect. + // + // The method returns the index of the given value in the list. If the + // list does not contain the given value, the method returns a negative + // integer. The bitwise complement operator (~) can be applied to a + // negative result to produce the index of the first element (if any) that + // is larger than the given search value. This is also the index at which + // the search value should be inserted into the list in order for the list + // to remain sorted. + // + // The method uses the Array.BinarySearch method to perform the + // search. + // + public int BinarySearch(int index, int count, T item, IComparer comparer) + { + if (index < 0) return -1; + return Array.BinarySearch(_items, index, count, item, comparer); + } + + public int BinarySearch(T item) + { + return BinarySearch(0, Count, item, null); + } + + public int BinarySearch(T item, IComparer comparer) + { + return BinarySearch(0, Count, item, comparer); + } + + + // Clears the contents of UncheckedList. + public void Clear() + { + if (!typeof(T).IsValueType) + { + int size = _size; + _size = 0; + _version++; + if (size > 0) + { + Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references. + } + } + else + { + _size = 0; + _version++; + } + } + + // Contains returns true if the specified element is in the UncheckedList. + // It does a linear, O(n) search. Equality is determined by calling + // EqualityComparer.Default.Equals(). + + public bool Contains(T item) + { + // PERF: IndexOf calls Array.IndexOf, which internally + // calls EqualityComparer.Default.IndexOf, which + // is specialized for different types. This + // boosts performance since instead of making a + // virtual method call each iteration of the loop, + // via EqualityComparer.Default.Equals, we + // only make one virtual call to EqualityComparer.IndexOf. + + return _size != 0 && IndexOf(item) != -1; + } + + bool System.Collections.IList.Contains(Object item) + { + if (IsCompatibleObject(item)) + { + return Contains((T)item); + } + return false; + } + + public UncheckedList ConvertAll(Converter converter) + { + UncheckedList list = new UncheckedList(_size); + for (int i = 0; i < _size; i++) + { + list._items[i] = converter(_items[i]); + } + list._size = _size; + return list; + } + + // Copies this UncheckedList into array, which must be of a + // compatible array type. + // + public void CopyTo(T[] array) + { + CopyTo(array, 0); + } + + // Copies this UncheckedList into array, which must be of a + // compatible array type. + // + void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) + { + try + { + // Array.Copy will check for NULL. + Array.Copy(_items, 0, array, arrayIndex, _size); + } + catch (ArrayTypeMismatchException) + { + } + } + + // Copies a section of this list to the given array at the given index. + // + // The method uses the Array.Copy method to copy the elements. + // + public void CopyTo(int index, T[] array, int arrayIndex, int count) + { + // Delegate rest of error checking to Array.Copy. + Array.Copy(_items, index, array, arrayIndex, count); + } + + public void CopyTo(T[] array, int arrayIndex) + { + // Delegate rest of error checking to Array.Copy. + Array.Copy(_items, 0, array, arrayIndex, _size); + } + + // Ensures that the capacity of this list is at least the given minimum + // value. If the current capacity of the list is less than min, the + // capacity is increased to twice the current capacity or to min, + // whichever is larger. + private void EnsureCapacity(int min) + { + if (_items.Length < min) + { + int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2; + // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. + // Note that this check works even when _items.Length overflowed thanks to the (uint) cast + if ((uint) newCapacity > Int32.MaxValue) newCapacity = Int32.MaxValue; + if (newCapacity < min) newCapacity = min; + Capacity = newCapacity; + } + } + + public bool Exists(Predicate match) + { + return FindIndex(match) != -1; + } + + public T Find(Predicate match) + { + for (int i = 0; i < _size; i++) + { + if (match(_items[i])) + { + return _items[i]; + } + } + return default(T); + } + + public UncheckedList FindAll(Predicate match) + { + UncheckedList list = new UncheckedList(); + for (int i = 0; i < _size; i++) + { + if (match(_items[i])) + { + list.Add(_items[i]); + } + } + return list; + } + + public int FindIndex(Predicate match) + { + return FindIndex(0, _size, match); + } + + public int FindIndex(int startIndex, Predicate match) + { + return FindIndex(startIndex, _size - startIndex, match); + } + + public int FindIndex(int startIndex, int count, Predicate match) + { + int endIndex = startIndex + count; + for (int i = startIndex; i < endIndex; i++) + { + if (match(_items[i])) return i; + } + return -1; + } + + public T FindLast(Predicate match) + { + for (int i = _size - 1; i >= 0; i--) + { + if (match(_items[i])) + { + return _items[i]; + } + } + return default(T); + } + + public int FindLastIndex(Predicate match) + { + return FindLastIndex(_size - 1, _size, match); + } + + public int FindLastIndex(int startIndex, Predicate match) + { + return FindLastIndex(startIndex, startIndex + 1, match); + } + + public int FindLastIndex(int startIndex, int count, Predicate match) + { + int endIndex = startIndex - count; + for (int i = startIndex; i > endIndex; i--) + { + if (match(_items[i])) + { + return i; + } + } + return -1; + } + + public void ForEach(Action action) + { + int version = _version; + + for (int i = 0; i < _size; i++) + { + if (version != _version) + { + break; + } + action(_items[i]); + } + } + + // Returns an enumerator for this list with the given + // permission for removal of elements. If modifications made to the list + // while an enumeration is in progress, the MoveNext and + // GetObject methods of the enumerator will throw an exception. + // + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(this); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return new Enumerator(this); + } + + public UncheckedList GetRange(int index, int count) + { + UncheckedList list = new UncheckedList(count); + Array.Copy(_items, index, list._items, 0, count); + list._size = count; + return list; + } + + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards from beginning to end. + // The elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item) + { + return Array.IndexOf(_items, item, 0, _size); + } + + int System.Collections.IList.IndexOf(Object item) + { + if (IsCompatibleObject(item)) + { + return IndexOf((T)item); + } + return -1; + } + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards, starting at index + // index and ending at count number of elements. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item, int index) + { + return Array.IndexOf(_items, item, index, _size - index); + } + + // Returns the index of the first occurrence of a given value in a range of + // this list. The list is searched forwards, starting at index + // index and upto count number of elements. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.IndexOf method to perform the + // search. + // + public int IndexOf(T item, int index, int count) + { + return Array.IndexOf(_items, item, index, count); + } + + // Inserts an element into this list at a given index. The size of the list + // is increased by one. If required, the capacity of the list is doubled + // before inserting the new element. + // + public void Insert(int index, T item) + { + if (_size == _items.Length) EnsureCapacity(_size + 1); + if (index < _size) + { + Array.Copy(_items, index, _items, index + 1, _size - index); + } + _items[index] = item; + _size++; + _version++; + } + + void System.Collections.IList.Insert(int index, Object item) + { + try + { + Insert(index, (T)item); + } + catch (InvalidCastException) + { + } + } + + // Inserts the elements of the given collection at a given index. If + // required, the capacity of the list is increased to twice the previous + // capacity or the new size, whichever is larger. Ranges may be added + // to the end of the list by setting index to the UncheckedList's size. + // + public void InsertRange(int index, IEnumerable collection) + { + ICollection c = collection as ICollection; + if (c != null) + { // if collection is ICollection + int count = c.Count; + if (count > 0) + { + EnsureCapacity(_size + count); + if (index < _size) + { + Array.Copy(_items, index, _items, index + count, _size - index); + } + + // If we're inserting a UncheckedList into itself, we want to be able to deal with that. + if (this == c) + { + // Copy first part of _items to insert location + Array.Copy(_items, 0, _items, index, index); + // Copy last part of _items back to inserted location + Array.Copy(_items, index + count, _items, index * 2, _size - index); + } + else + { + c.CopyTo(_items, index); + } + _size += count; + } + } + else if (index < _size) + { + // We're inserting a lazy enumerable. Call Insert on each of the constituent items. + using (IEnumerator en = collection.GetEnumerator()) + { + while (en.MoveNext()) + { + Insert(index++, en.Current); + } + } + } + else + { + // We're adding a lazy enumerable because the index is at the end of this list. + AddEnumerable(collection); + } + _version++; + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at the end + // and ending at the first element in the list. The elements of the list + // are compared to the given value using the Object.Equals method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item) + { + if (_size == 0) + { // Special case for empty list + return -1; + } + else + { + return LastIndexOf(item, _size - 1, _size); + } + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at index + // index and ending at the first element in the list. The + // elements of the list are compared to the given value using the + // Object.Equals method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item, int index) + { + return LastIndexOf(item, index, index + 1); + } + + // Returns the index of the last occurrence of a given value in a range of + // this list. The list is searched backwards, starting at index + // index and upto count elements. The elements of + // the list are compared to the given value using the Object.Equals + // method. + // + // This method uses the Array.LastIndexOf method to perform the + // search. + // + public int LastIndexOf(T item, int index, int count) + { + if (_size == 0) + { // Special case for empty list + return -1; + } + + return Array.LastIndexOf(_items, item, index, count); + } + + // Removes the element at the given index. The size of the list is + // decreased by one. + // + public bool Remove(T item) + { + int index = IndexOf(item); + if (index >= 0) + { + RemoveAt(index); + return true; + } + + return false; + } + + void System.Collections.IList.Remove(Object item) + { + if (IsCompatibleObject(item)) + { + Remove((T)item); + } + } + + // This method removes all items which matches the predicate. + // The complexity is O(n). + public int RemoveAll(Predicate match) + { + int freeIndex = 0; // the first free slot in items array + + // Find the first item which needs to be removed. + while (freeIndex < _size && !match(_items[freeIndex])) freeIndex++; + if (freeIndex >= _size) return 0; + + int current = freeIndex + 1; + while (current < _size) + { + // Find the first item which needs to be kept. + while (current < _size && match(_items[current])) current++; + + if (current < _size) + { + // copy item to the free slot. + _items[freeIndex++] = _items[current++]; + } + } + + if (!typeof(T).IsValueType) + { + Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references. + } + + int result = _size - freeIndex; + _size = freeIndex; + _version++; + return result; + } + + // Removes the element at the given index. The size of the list is + // decreased by one. + // + public void RemoveAt(int index) + { + _size--; + if (index < _size) + { + Array.Copy(_items, index + 1, _items, index, _size - index); + } +#if DEBUG + _items[_size] = default(T); +#endif + } + + // Removes a range of elements from this list. + // + public void RemoveRange(int index, int count) + { + if (count > 0) + { + int i = _size; + _size -= count; + if (index < _size) + { + Array.Copy(_items, index + count, _items, index, _size - index); + } + +#if DEBUG + Array.Clear(_items, _size, count); +#endif + } + } + + // Reverses the elements in this list. + public void Reverse() + { + Reverse(0, Count); + } + + // Reverses the elements in a range of this list. Following a call to this + // method, an element in the range given by index and count + // which was previously located at index i will now be located at + // index index + (index + count - i - 1). + // + public void Reverse(int index, int count) + { + if (count > 1) + { + Array.Reverse(_items, index, count); + } + _version++; + } + + // Sorts the elements in this list. Uses the default comparer and + // Array.Sort. + public void Sort() + { + Sort(0, Count, null); + } + + // Sorts the elements in this list. Uses Array.Sort with the + // provided comparer. + public void Sort(IComparer comparer) + { + Sort(0, Count, comparer); + } + + // Sorts the elements in a section of this list. The sort compares the + // elements to each other using the given IComparer interface. If + // comparer is null, the elements are compared to each other using + // the IComparable interface, which in that case must be implemented by all + // elements of the list. + // + // This method uses the Array.Sort method to sort the elements. + // + public void Sort(int index, int count, IComparer comparer) + { + if (count > 1) + { + Array.Sort(_items, index, count, comparer); + } + _version++; + } + + public void Sort(Comparison comparison) + { + throw new NotImplementedException(); + /*if (_size > 1) + { + ArraySortHelper.Sort(_items, 0, _size, comparison); + } + _version++;*/ + } + + // ToArray returns an array containing the contents of the UncheckedList. + // This requires copying the UncheckedList, which is an O(n) operation. + public T[] ToArray() + { + if (_size == 0) + { + return _emptyArray; + } + + T[] array = new T[_size]; + Array.Copy(_items, 0, array, 0, _size); + return array; + } + + // Sets the capacity of this list to the size of the list. This method can + // be used to minimize a list's memory overhead once it is known that no + // new elements will be added to the list. To completely clear a list and + // release all memory referenced by the list, execute the following + // statements: + // + // list.Clear(); + // list.TrimExcess(); + // + public void TrimExcess() + { + int threshold = (int)(((double)_items.Length) * 0.9); + if (_size < threshold) + { + Capacity = _size; + } + } + + public bool TrueForAll(Predicate match) + { + for (int i = 0; i < _size; i++) + { + if (!match(_items[i])) + { + return false; + } + } + return true; + } + + private void AddEnumerable(IEnumerable enumerable) + { + Debug.Assert(enumerable != null); + Debug.Assert(!(enumerable is ICollection), "We should have optimized for this beforehand."); + + using (IEnumerator en = enumerable.GetEnumerator()) + { + _version++; // Even if the enumerable has no items, we can update _version. + + while (en.MoveNext()) + { + // Capture Current before doing anything else. If this throws + // an exception, we want to make a clean break. + T current = en.Current; + + if (_size == _items.Length) + { + EnsureCapacity(_size + 1); + } + + _items[_size++] = current; + } + } + } + + public struct Enumerator : IEnumerator, System.Collections.IEnumerator + { + private UncheckedList list; + private int index; + private int version; + private T current; + + internal Enumerator(UncheckedList list) + { + this.list = list; + index = 0; + version = list._version; + current = default(T); + } + + public void Dispose() + { + } + + public bool MoveNext() + { + UncheckedList localUncheckedList = list; + + if (version == localUncheckedList._version && ((uint)index < (uint)localUncheckedList._size)) + { + current = localUncheckedList._items[index]; + index++; + return true; + } + return MoveNextRare(); + } + + private bool MoveNextRare() + { + index = list._size + 1; + current = default(T); + return false; + } + + public T Current + { + get + { + return current; + } + } + + Object System.Collections.IEnumerator.Current + { + get + { + return Current; + } + } + + void System.Collections.IEnumerator.Reset() + { + index = 0; + current = default(T); + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs new file mode 100644 index 00000000..d3814e36 --- /dev/null +++ b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs @@ -0,0 +1,263 @@ +#if USE_HOT +// System.Collections.Generic.Stack +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Threading; + +[Serializable] +[DebuggerDisplay("Count = {Count}")] +[ComVisible(false)] +public class UncheckedStack : IEnumerable, IEnumerable, ICollection, IReadOnlyCollection +{ + [Serializable] + public struct Enumerator : IEnumerator, IDisposable, IEnumerator + { + private UncheckedStack _stack; + + private int _index; + + private int _version; + + private T currentElement; + + public T Current + { + get + { + return currentElement; + } + } + + object IEnumerator.Current + { + get + { + return currentElement; + } + } + + internal Enumerator(UncheckedStack stack) + { + _stack = stack; + _version = _stack._version; + _index = -2; + currentElement = default(T); + } + + public void Dispose() + { + _index = -1; + } + + public bool MoveNext() + { + bool flag; + if (_index == -2) + { + _index = _stack._size - 1; + flag = (_index >= 0); + if (flag) + { + currentElement = _stack._array[_index]; + } + return flag; + } + if (_index == -1) + { + return false; + } + flag = (--_index >= 0); + if (flag) + { + currentElement = _stack._array[_index]; + } + else + { + currentElement = default(T); + } + return flag; + } + void IEnumerator.Reset() + { + _index = -2; + currentElement = default(T); + } + } + + private T[] _array; + + private int _size; + + private int _version; + + [NonSerialized] + private object _syncRoot; + + private const int _defaultCapacity = 4; + + private static T[] _emptyArray = new T[0]; + + public int Count + { + get + { + return _size; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + Interlocked.CompareExchange(ref _syncRoot, new object(), (object)null); + } + return _syncRoot; + } + } + + public UncheckedStack() + { + _array = _emptyArray; + _size = 0; + _version = 0; + } + + public UncheckedStack(int capacity) + { + _array = new T[capacity]; + _size = 0; + _version = 0; + } + + public UncheckedStack(IEnumerable collection) + { + ICollection collection2 = collection as ICollection; + if (collection2 != null) + { + int count = collection2.Count; + _array = new T[count]; + collection2.CopyTo(_array, 0); + _size = count; + return; + } + _size = 0; + _array = new T[4]; + foreach (T item in collection) + { + T local = item; + Push(ref local); + } + } + + public void Clear() + { + Array.Clear(_array, 0, _size); + _size = 0; + _version++; + } + + public bool Contains(T item) + { + int size = _size; + EqualityComparer @default = EqualityComparer.Default; + while (size-- > 0) + { + if (item == null) + { + if (_array[size] == null) + { + return true; + } + } + else if (_array[size] != null && @default.Equals(_array[size], item)) + { + return true; + } + } + return false; + } + + public void CopyTo(T[] array, int arrayIndex) + { + Array.Copy(_array, 0, array, arrayIndex, _size); + Array.Reverse(array, arrayIndex, _size); + } + + void ICollection.CopyTo(Array array, int arrayIndex) + { + Array.Copy(_array, 0, array, arrayIndex, _size); + Array.Reverse(array, arrayIndex, _size); + } + + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(this); + } +public void TrimExcess() + { + int num = (int)((double)_array.Length * 0.9); + if (_size < num) + { + T[] array = new T[_size]; + Array.Copy(_array, 0, array, 0, _size); + _array = array; + _version++; + } + } + + public T Peek() + { + return _array[_size - 1]; + } + + public ref T Pop() + { + ref T result = ref _array[--_size]; + return ref result; + } + + public void Push(ref T item) + { + if (_size == _array.Length) + { + T[] array = new T[(_array.Length == 0) ? 4 : (2 * _array.Length)]; + Array.Copy(_array, 0, array, 0, _size); + _array = array; + } + _array[_size++] = item; + } + + public T[] ToArray() + { + T[] array = new T[_size]; + for (int i = 0; i < _size; i++) + { + array[i] = _array[_size - i - 1]; + } + return array; + } +} +#endif \ No newline at end of file diff --git a/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs.meta b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs.meta new file mode 100644 index 00000000..c2a2d306 --- /dev/null +++ b/Assets/XIL/ILSource/ILRuntime/Other/UncheckedStack.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab2dd8df5718f8b48982bd9a8e39aaca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XIL/ILSource/ILRuntime/Runtime/CLRBinding/MethodBindingGenerator.cs b/Assets/XIL/ILSource/ILRuntime/Runtime/CLRBinding/MethodBindingGenerator.cs index 095df3d0..f69f105c 100644 --- a/Assets/XIL/ILSource/ILRuntime/Runtime/CLRBinding/MethodBindingGenerator.cs +++ b/Assets/XIL/ILSource/ILRuntime/Runtime/CLRBinding/MethodBindingGenerator.cs @@ -503,8 +503,11 @@ internal static string GenerateMethodWraperCode(this Type type, MethodInfo[] met if (!i.IsStatic && ((type.IsValueType && !type.IsPrimitive) || hasByRef))//need to write back value type instance { sb.AppendLine(string.Format(" ptr_of_this_method = ILIntepreter.Minus(__esp, {0});", paramCnt)); - - if (type.IsValueType && !type.IsPrimitive) + bool noWriteback = false; +#if NET_4_6 || NET_STANDARD_2_0 + noWriteback = type == typeof(System.Runtime.CompilerServices.AsyncTaskMethodBuilder) && i.Name == "Start"; +#endif + if (type.IsValueType && !type.IsPrimitive && !noWriteback) { if (valueTypeBinders != null && valueTypeBinders.Contains(type)) { diff --git a/Assets/XIL/ILSource/ILRuntime/Runtime/Intepreter/ILIntepreter.cs b/Assets/XIL/ILSource/ILRuntime/Runtime/Intepreter/ILIntepreter.cs index 577154e6..ee568048 100644 --- a/Assets/XIL/ILSource/ILRuntime/Runtime/Intepreter/ILIntepreter.cs +++ b/Assets/XIL/ILSource/ILRuntime/Runtime/Intepreter/ILIntepreter.cs @@ -107,8 +107,10 @@ public object Run(ILMethod method, object instance, object[] p) } internal StackObject* Execute(ILMethod method, StackObject* esp, out bool unhandledException) { +#if DEBUG if (method == null) throw new NullReferenceException(); +#endif #if DEBUG && (UNITY_EDITOR || UNITY_ANDROID || UNITY_IPHONE) if (System.Threading.Thread.CurrentThread.ManagedThreadId == AppDomain.UnityMainThreadID) @@ -191,13 +193,20 @@ public object Run(ILMethod method, object instance, object[] p) { var v = method.Variables[i]; bool isEnum = false; - if (v.VariableType is Mono.Cecil.TypeDefinition td) + var vt = v.VariableType; + IType t; + if (vt.IsGenericParameter) + { + t = method.FindGenericArgument(vt.Name); + } + else { - isEnum = ((Mono.Cecil.TypeDefinition)td).IsEnum; + t = AppDomain.GetType(v.VariableType, method.DeclearingType, method); } - if (v.VariableType.IsValueType && !v.VariableType.IsPrimitive && !isEnum) + isEnum = t.IsEnum; + + if (t.IsValueType && !t.IsPrimitive && !isEnum) { - var t = AppDomain.GetType(v.VariableType, method.DeclearingType, method); if (t is ILType) { //var obj = ((ILType)t).Instantiate(false); @@ -228,9 +237,8 @@ public object Run(ILMethod method, object instance, object[] p) } else { - if (v.VariableType.IsPrimitive || isEnum) + if (t.IsPrimitive || isEnum) { - var t = AppDomain.GetType(v.VariableType, method.DeclearingType, method); var loc = Add(v1, i); StackObject.Initialized(loc, t); } @@ -264,7 +272,7 @@ public object Run(ILMethod method, object instance, object[] p) code = ip->Code; switch (code) { - #region Arguments and Local Variable +#region Arguments and Local Variable case OpCodeEnum.Ldarg_0: CopyToStack(esp, arg, mStack); esp++; @@ -568,9 +576,9 @@ public object Run(ILMethod method, object instance, object[] p) esp = esp - 1 - 1; } break; - #endregion +#endregion - #region Load Constants +#region Load Constants case OpCodeEnum.Ldc_I4_M1: esp->Value = -1; esp->ObjectType = ObjectTypes.Integer; @@ -955,9 +963,9 @@ public object Run(ILMethod method, object instance, object[] p) case OpCodeEnum.Ldstr: esp = PushObject(esp, mStack, AppDomain.GetString(ip->TokenLong)); break; - #endregion +#endregion - #region Althemetics +#region Althemetics case OpCodeEnum.Add: { b = esp - 1; @@ -1276,9 +1284,9 @@ public object Run(ILMethod method, object instance, object[] p) } } break; - #endregion +#endregion - #region Control Flows +#region Control Flows case OpCodeEnum.Ret: returned = true; break; @@ -1863,9 +1871,9 @@ public object Run(ILMethod method, object instance, object[] p) } } break; - #endregion +#endregion - #region FieldOperation +#region FieldOperation case OpCodeEnum.Stfld: { objRef = GetObjectAndResolveReference(esp - 1 - 1); @@ -2227,9 +2235,9 @@ public object Run(ILMethod method, object instance, object[] p) esp = PushObject(objRef, mStack, m); } break; - #endregion +#endregion - #region Compare +#region Compare case OpCodeEnum.Ceq: { StackObject* obj1 = esp - 1 - 1; @@ -2396,9 +2404,9 @@ public object Run(ILMethod method, object instance, object[] p) esp = PushZero(esp - 1 - 1); } break; - #endregion +#endregion - #region Initialization & Instantiation +#region Initialization & Instantiation case OpCodeEnum.Newobj: { IMethod m = domain.GetMethod(ip->TokenInteger); @@ -3112,6 +3120,14 @@ public object Run(ILMethod method, object instance, object[] p) { case ObjectTypes.Null: throw new NullReferenceException(); + case ObjectTypes.Integer: + case ObjectTypes.Float: + objRef->Value = 0; + break; + case ObjectTypes.Long: + case ObjectTypes.Double: + *(long*)&objRef->Value = 0; + break; case ObjectTypes.ValueTypeObjectReference: stack.ClearValueTypeObject(type, ILIntepreter.ResolveReference(objRef)); break; @@ -3226,6 +3242,17 @@ public object Run(ILMethod method, object instance, object[] p) { stack.ClearValueTypeObject(type, ILIntepreter.ResolveReference(objRef)); } + else if (objRef->ObjectType == ObjectTypes.FieldReference) + { + var instance = mStack[objRef->Value] as ILTypeInstance; + if (instance != null) + { + PushNull(esp); + instance.AssignFromStack(objRef->ValueLow, esp, AppDomain, mStack); + } + else + throw new NotImplementedException(); + } else if (type.IsPrimitive) StackObject.Initialized(objRef, type); } @@ -3346,9 +3373,9 @@ public object Run(ILMethod method, object instance, object[] p) throw new NullReferenceException(); } break; - #endregion +#endregion - #region Array +#region Array case OpCodeEnum.Newarr: { var cnt = (esp - 1); @@ -3817,9 +3844,9 @@ public object Run(ILMethod method, object instance, object[] p) esp--; } break; - #endregion +#endregion - #region Conversion +#region Conversion case OpCodeEnum.Conv_U1: case OpCodeEnum.Conv_Ovf_U1: case OpCodeEnum.Conv_Ovf_U1_Un: @@ -4119,9 +4146,9 @@ public object Run(ILMethod method, object instance, object[] p) } } break; - #endregion +#endregion - #region Stack operation +#region Stack operation case OpCodeEnum.Pop: { Free(esp - 1); @@ -4147,7 +4174,7 @@ public object Run(ILMethod method, object instance, object[] p) esp++; } break; - #endregion +#endregion case OpCodeEnum.Throw: { diff --git a/Assets/XIL/ILSource/ILRuntime/Runtime/Stack/RuntimeStack.cs b/Assets/XIL/ILSource/ILRuntime/Runtime/Stack/RuntimeStack.cs index b056c95e..298b7ddc 100644 --- a/Assets/XIL/ILSource/ILRuntime/Runtime/Stack/RuntimeStack.cs +++ b/Assets/XIL/ILSource/ILRuntime/Runtime/Stack/RuntimeStack.cs @@ -7,7 +7,6 @@ using ILRuntime.CLR.TypeSystem; using ILRuntime.Other; using ILRuntime.Runtime.Intepreter; - namespace ILRuntime.Runtime.Stack { unsafe class RuntimeStack : IDisposable @@ -25,10 +24,10 @@ unsafe class RuntimeStack : IDisposable IList managedStack = new UncheckedList(32); #endif - Stack frames = new Stack(); + UncheckedStack frames = new UncheckedStack(); public const int MAXIMAL_STACK_OBJECTS = 1024 * 16; - public Stack Frames { get { return frames; } } + public UncheckedStack Frames { get { return frames; } } public RuntimeStack(ILIntepreter intepreter) { this.intepreter = intepreter; @@ -83,10 +82,12 @@ public void ResetValueTypePointer() public void InitializeFrame(ILMethod method, StackObject* esp, out StackFrame res) { +#if DEBUG if (esp < pointer || esp >= endOfMemory) throw new StackOverflowException(); if (frames.Count > 0 && frames.Peek().BasePointer > esp) throw new StackOverflowException(); +#endif res = new StackFrame(); res.LocalVarPointer = esp; res.Method = method; @@ -105,15 +106,19 @@ public void InitializeFrame(ILMethod method, StackObject* esp, out StackFrame re } public void PushFrame(ref StackFrame frame) { - frames.Push(frame); + frames.Push(ref frame); } public StackObject* PopFrame(ref StackFrame frame, StackObject* esp) { +#if DEBUG if (frames.Count > 0 && frames.Peek().BasePointer == frame.BasePointer) +#endif frames.Pop(); +#if DEBUG else throw new NotSupportedException(); +#endif StackObject* returnVal = esp - 1; var method = frame.Method; StackObject* ret = ILIntepreter.Minus(frame.LocalVarPointer, method.ParameterCount);