/// <summary> /// Pushs an empty element onto the stack. /// </summary> /// <param name="type">Type of empty value to push onto stack.</param> public RuntimeValue PushEmpty(RuntimeValueType type) { if (_topIndex >= _stack.Length - 1) Resize(_stack.Length + 1); _stack[_topIndex] = new RuntimeValue(type); return _stack[_topIndex++]; }
/// <summary> /// Allocates a chunk of data on the heap. /// </summary> /// <param name="size">Size of data to allocate.</param> /// <param name="type">Data type the allocated memory should store.</param> /// <param name="value">Data type this heap is stored as (differs from the type paramter 'type' as it keeps track of arrays and references to)</param> /// <returns>Starting index of data on the heap.</returns> public int AllocateHeap(int size, RuntimeValueType type, DataTypeValue value) { // Check if there is any space on the stack. // Ignore the constant and global memory index as they are persistant. int allocatableIndex = 0, allocatableSize = 0; // First element is reserved to capture null-to-zero-cast-to-memory-index (XD) errors. for (int i = 1; i < _memoryHeap.Length; i++) { if (_memoryHeap[i] != null) { allocatableSize = 0; allocatableIndex = i + 1; if (_memoryHeap[i].ValueType == RuntimeValueType.MemoryBoundry) { i += _memoryHeap[i].IntegerLiteral; allocatableIndex = i + 1; continue; } i++; continue; } else allocatableSize++; if (allocatableSize >= (size + 1)) break; } if (allocatableSize < (size + 1))// || (allocatableIndex + allocatableSize) >= _memoryHeap.Length) { CollectGarbage(); // Desperatly try and free some space :S. if (allocatableSize + _lastCollectionMemoryCount < (size + 1)) { // If all else fails, resize. Its better than crashing. Array.Resize(ref _memoryHeap, _memoryHeap.Length * 2 < _memoryHeap.Length + size ? _memoryHeap.Length + size : _memoryHeap.Length * 2); // Double the size. DebugLogger.WriteLog("Memory heap of script '"+_url.ToString()+"' was resized due to overflow."); return AllocateHeap(size, type, value); } else return AllocateHeap(size, type, value); } // Actually allocate the data. for (int i = allocatableIndex; i <= (allocatableIndex + allocatableSize); i++) _memoryHeap[i] = new RuntimeValue(type); // Set the first data block as a memory boundry so the GC can look after it. _memoryHeap[allocatableIndex].ValueType = RuntimeValueType.MemoryBoundry; _memoryHeap[allocatableIndex].IntegerLiteral = size; _memoryHeap[allocatableIndex].ReferenceCount = 0; _memoryHeap[allocatableIndex].DataType = value; return allocatableIndex + 1; }
/// <summary> /// Initializes an instance of this class. /// </summary> /// <param name="type">Type of value this runtime value should store.</param> public RuntimeValue(RuntimeValueType type) { _valueType = type; }
/// <summary> /// Nullifys all values in this instance. /// </summary> public void Clear() { _values.BooleanLiteral = false; _values.ByteLiteral = 0; _values.DoubleLiteral = 0; _values.FloatLiteral = 0; _values.IntegerLiteral = 0; _values.LongLiteral = 0; _memoryIndex = -1; _values.ShortLiteral = 0; _stringLiteralValue = ""; _objectIndex = -1; _referenceCount = 0; _valueType = RuntimeValueType.Invalid; _dataType = null; }
/// <summary> /// Nullifys all values in this instance. /// </summary> public void Clear() { _booleanLiteral = false; _byteLiteral = 0; _doubleLiteral = 0; _floatLiteral = 0; _integerLiteral = 0; _longLiteral = 0; _memoryIndex = -1; _shortLiteral = 0; _stringLiteral = ""; _objectIndex = -1; _referenceCount = 0; _valueType = RuntimeValueType.Invalid; _dataType = null; }