public static unsafe void Throw(Testing2.Exception ex) { Testing2.GC.IncrementRefCount(ex); BasicConsole.WriteLine("Exception thrown:"); BasicConsole.WriteLine(ex.Message); if (State->CurrentHandlerPtr->Ex != null) { //GC ref count remains consistent because the Ex pointer below is going to be replaced but // same pointer stored in InnerException. // Result is ref count goes: +1 here, -1 below ex.InnerException = (Testing2.Exception)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex); } if (ex.InstructionAddress == 0) { ex.InstructionAddress = *((uint *)BasePointer + 1); } State->CurrentHandlerPtr->Ex = Utilities.ObjectUtilities.GetHandle(ex); State->CurrentHandlerPtr->ExPending = 1; HandleException(); // We never expect to get here... HaltReason = "HandleException returned!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte *)0xDEADBEEF) = 0; }
public static void Write(Testing2.String str) { for (int i = 0; i < str.length; i++) { Write(str[i]); } }
public Testing2.String PadLeft(int totalLength, char padChar) { Testing2.String result = New(totalLength); if (this.length >= totalLength) { for (int i = 0; i < result.length; i++) { result[i] = this[i]; } return(result); } int offset = totalLength - this.length; for (int i = 0; i < this.length; i++) { result[i + offset] = this[i]; } for (int i = 0; i < offset; i++) { result[i] = padChar; } return(result); }
public static void Disable(Testing2.String caller) { //BasicConsole.Write(caller); //BasicConsole.WriteLine(" disabling GC."); //BasicConsole.DelayOutput(2); GC.Enabled = false; }
public static void Throw_IndexOutOfRangeException() { HaltReason = "Index out of range exception."; UART.Write(HaltReason); //Testing2.Exception ex = new Testing2.Exceptions.IndexOutOfRangeException(0, 0); //ex.InstructionAddress = *((uint*)BasePointer + 1); //Throw(ex); }
public static void *AllocZeroed(UInt32 size, UInt32 boundary, Testing2.String caller) { void *result = Alloc(size, boundary, caller); if (result == null) { return(null); } return(Utilities.MemoryUtils.ZeroMem(result, size)); }
public static void Throw_NullReferenceException(uint address) { HaltReason = "Null reference exception. Instruction: 0x "; FillString(address, 48, HaltReason); UART.Write(HaltReason); //Testing2.Exception ex = new Testing2.Exceptions.NullReferenceException(); //ex.InstructionAddress = address; //Throw(ex); }
public static unsafe void PrintTestString() { if (!Initialised) { return; } //This does not use the Write functions as it is a test function to // test that strings and the video memory output work. Testing2.String str = "1234567890!\"£$%^&*()qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM[];'#,./{}:@~<>?\\|`¬¦"; UART.Write(str); }
public Testing2.String PadRight(int totalLength, char padChar) { Testing2.String result = New(totalLength); for (int i = 0; i < this.length && i < totalLength; i++) { result[i] = this[i]; } for (int i = this.length; i < totalLength; i++) { result[i] = padChar; } return(result); }
public static unsafe Testing2.String Concat(Testing2.String str1, Testing2.String str2) { Testing2.String newStr = New(str1.length + str2.length); for (int i = 0; i < str1.length; i++) { newStr[i] = str1[i]; } for (int i = 0; i < str2.length; i++) { newStr[i + str1.length] = str2[i]; } return(newStr); }
public static unsafe void WriteLine(Testing2.String str) { if (!Initialised) { return; } if (str == null) { return; } //This outputs the string Write(str); Write("\n"); }
public static unsafe Testing2.String New(int length) { if (length < 0) { UART.Write("ArgumentException! String.New, length less than zero."); //ExceptionMethods.Throw(new Exceptions.ArgumentException("Parameter \"length\" cannot be less than 0 in Testing2.String.New(int length).")); } Testing2.String result = (Testing2.String)Utilities.ObjectUtilities.GetObject(GC.NewString(length)); if (result == null) { UART.Write("NullReferenceException! String.New, result is null."); //ExceptionMethods.Throw(new Exceptions.NullReferenceException()); } return(result); }
public Testing2.String ToLower() { Testing2.String result = New(this.length); for (int i = 0; i < result.length; i++) { char cChar = this[i]; if (cChar >= 'A' && cChar <= 'Z') { cChar = (char)('a' + (cChar - 'A')); } result[i] = cChar; } return(result); }
public static unsafe void Write(Testing2.String str) { if (!Initialised) { return; } //If string is null, just don't write anything if (str == null) { //Do not make this throw an exception. The BasicConsole // is largely a debugging tool - it should be reliable, // robust and not throw exceptions. return; } UART.Write(str); }
public Testing2.String Trim() { Testing2.String TrimChars = "\n\r "; int removeStart = 0; int removeEnd = 0; for (int i = 0; i < this.length; removeStart++, i++) { bool ShouldBreak = true; for (int j = 0; j < TrimChars.length; j++) { if (this[i] == TrimChars[j]) { ShouldBreak = false; } } if (ShouldBreak) { break; } } for (int i = this.length - 1; i > removeStart; removeEnd++, i--) { bool ShouldBreak = true; for (int j = 0; j < TrimChars.length; j++) { if (this[i] == TrimChars[j]) { ShouldBreak = false; } } if (ShouldBreak) { break; } } Testing2.String result = New(this.length - removeStart - removeEnd); for (int i = removeStart; i < this.length - removeEnd; i++) { result[i - removeStart] = this[i]; } return(result); }
public bool StartsWith(Testing2.String prefix) { if (this.length < prefix.length) { return(false); } else { for (int i = 0; i < prefix.length; i++) { if (this[i] != prefix[i]) { return(false); } } return(true); } }
public bool EndsWith(Testing2.String postfix) { if (this.length < postfix.length) { return(false); } else { int offset = this.length - postfix.length; for (int i = this.length - 1; i >= offset; i--) { if (this[i] != postfix[i - offset]) { return(false); } } return(true); } }
public static void *AllocZeroedAPB(UInt32 size, UInt32 boundary, Testing2.String caller) { void * result = null; void * oldValue = null; UInt32 resultAddr; do { oldValue = result; result = AllocZeroed(size, boundary, caller); resultAddr = (UInt32)result; if (oldValue != null) { Free(oldValue); } }while (resultAddr / 0x1000 != (resultAddr + size - 1) / 0x1000); return(result); }
public Testing2.String TrimEnd() { int removeEnd = 0; for (int i = this.length - 1; i > -1; removeEnd++, i--) { if (this[i] != ' ') { break; } } Testing2.String result = New(this.length - removeEnd); for (int i = 0; i < this.length - removeEnd; i++) { result[i] = this[i]; } return(result); }
public static unsafe void HandleException() { if (State != null) { if (State->CurrentHandlerPtr != null) { if (State->CurrentHandlerPtr->InHandler != 0) { State->CurrentHandlerPtr->InHandler = 0; if (State->CurrentHandlerPtr->PrevHandlerPtr != null) { State->CurrentHandlerPtr->PrevHandlerPtr->Ex = State->CurrentHandlerPtr->Ex; State->CurrentHandlerPtr->PrevHandlerPtr->ExPending = State->CurrentHandlerPtr->ExPending; } State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; } } ExceptionHandlerInfo *CurrHandlerPtr = State->CurrentHandlerPtr; if (CurrHandlerPtr != null) { if ((uint)CurrHandlerPtr->HandlerAddress != 0x00000000u) { if ((uint)CurrHandlerPtr->FilterAddress != 0x00000000u) { //Catch handler CurrHandlerPtr->ExPending = 0; } CurrHandlerPtr->InHandler = 1; ArbitaryReturn(CurrHandlerPtr->EBP, CurrHandlerPtr->ESP, CurrHandlerPtr->HandlerAddress); } } } // If we get to here, it's an unhandled exception HaltReason = "Unhandled / improperly handled exception!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte *)0xDEADBEEF) = 0; }
public static unsafe void HandleEndFinally() { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = "Cannot end finally on null handler!"; BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(5); // Try to cause fault *((byte *)0xDEADBEEF) = 0; } // Leaving a "finally" critical section cleanly // We need to handle 2 cases: // Case 1 : Pending exception // Case 2 : No pending exception if (State->CurrentHandlerPtr->ExPending != 0) { // Case 1 : Pending exception HandleException(); } else { // Case 2 : No pending exception State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte *)*((uint *)(BasePointer + 4))); } }
public Testing2.String ToUpper() { if (this.length == 0) { return(""); } Testing2.String result = New(this.length); for (int i = 0; i < result.length; i++) { char cChar = this[i]; if (cChar >= 'a' && cChar <= 'z') { cChar = (char)('A' + (cChar - 'a')); } result[i] = cChar; } return(result); }
public Testing2.String Substring(int startIndex, int aLength) { if (startIndex >= this.length) { if (aLength == 0) { return(New(0)); } UART.Write("IndexOutOfRangeException! Substring."); //ExceptionMethods.Throw(new Exceptions.IndexOutOfRangeException(startIndex, this.length)); } else if (aLength > length - startIndex) { aLength = length - startIndex; } Testing2.String result = New(aLength); for (int i = startIndex; i < aLength + startIndex; i++) { result[i - startIndex] = this[i]; } return(result); }
/// <summary> /// Creates a new exception with specified message. /// </summary> /// <param name="aMessage">The exception message.</param> public Exception(Testing2.String aMessage) : base() { Message = aMessage; }
public static void *Alloc(UInt32 size, UInt32 boundary, Testing2.String caller) { #if HEAP_TRACE BasicConsole.SetTextColour(BasicConsole.warning_colour); BasicConsole.WriteLine("Attempt to alloc mem...."); BasicConsole.SetTextColour(BasicConsole.default_colour); #endif HeapBlock *b; byte * bm; UInt32 bcnt; UInt32 x, y, z; UInt32 bneed; byte nid; if (boundary > 1) { size += (boundary - 1); } /* iterate blocks */ for (b = fblock; (UInt32)b != 0; b = b->next) { /* check if block has enough room */ if (b->size - (b->used * b->bsize) >= size) { bcnt = b->size / b->bsize; bneed = (size / b->bsize) * b->bsize < size ? size / b->bsize + 1 : size / b->bsize; bm = (byte *)&b[1]; for (x = (b->lfb + 1 >= bcnt ? 0 : b->lfb + 1); x != b->lfb; ++x) { /* just wrap around */ if (x >= bcnt) { x = 0; } if (bm[x] == 0) { /* count free blocks */ for (y = 0; bm[x + y] == 0 && y < bneed && (x + y) < bcnt; ++y) { ; } /* we have enough, now allocate them */ if (y == bneed) { /* find ID that does not match left or right */ nid = GetNID(bm[x - 1], bm[x + y]); /* allocate by setting id */ for (z = 0; z < y; ++z) { bm[x + z] = nid; } /* optimization */ b->lfb = (x + bneed) - 2; /* count used blocks NOT bytes */ b->used += y; void *result = (void *)(x * b->bsize + (UInt32)(&b[1])); if (boundary > 1) { result = (void *)((((UInt32)result) + (boundary - 1)) & ~(boundary - 1)); #if HEAP_TRACE ExitCritical(); BasicConsole.WriteLine(((Testing2.String) "Allocated address ") + (uint)result + " on boundary " + boundary + " for " + caller); EnterCritical("Alloc:Boundary condition"); #endif } return(result); } /* x will be incremented by one ONCE more in our FOR loop */ x += (y - 1); continue; } } } } #if HEAP_TRACE BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("!!Heap out of memory!!"); BasicConsole.SetTextColour(BasicConsole.default_colour); BasicConsole.DelayOutput(2); #endif return(null); }
public static unsafe void Throw(Testing2.Exception ex) { Testing2.GC.IncrementRefCount(ex); BasicConsole.WriteLine("Exception thrown:"); BasicConsole.WriteLine(ex.Message); if (State->CurrentHandlerPtr->Ex != null) { //GC ref count remains consistent because the Ex pointer below is going to be replaced but // same pointer stored in InnerException. // Result is ref count goes: +1 here, -1 below ex.InnerException = (Testing2.Exception)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex); } if (ex.InstructionAddress == 0) { ex.InstructionAddress = *((uint*)BasePointer + 1); } State->CurrentHandlerPtr->Ex = Utilities.ObjectUtilities.GetHandle(ex); State->CurrentHandlerPtr->ExPending = 1; HandleException(); // We never expect to get here... HaltReason = "HandleException returned!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte*)0xDEADBEEF) = 0; }
public static unsafe void HandleException() { if (State != null) { if (State->CurrentHandlerPtr != null) { if (State->CurrentHandlerPtr->InHandler != 0) { State->CurrentHandlerPtr->InHandler = 0; if (State->CurrentHandlerPtr->PrevHandlerPtr != null) { State->CurrentHandlerPtr->PrevHandlerPtr->Ex = State->CurrentHandlerPtr->Ex; State->CurrentHandlerPtr->PrevHandlerPtr->ExPending = State->CurrentHandlerPtr->ExPending; } State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; } } ExceptionHandlerInfo* CurrHandlerPtr = State->CurrentHandlerPtr; if (CurrHandlerPtr != null) { if ((uint)CurrHandlerPtr->HandlerAddress != 0x00000000u) { if ((uint)CurrHandlerPtr->FilterAddress != 0x00000000u) { //Catch handler CurrHandlerPtr->ExPending = 0; } CurrHandlerPtr->InHandler = 1; ArbitaryReturn(CurrHandlerPtr->EBP, CurrHandlerPtr->ESP, CurrHandlerPtr->HandlerAddress); } } } // If we get to here, it's an unhandled exception HaltReason = "Unhandled / improperly handled exception!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte*)0xDEADBEEF) = 0; }
public static unsafe void HandleLeave(void* continuePtr) { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = "Cannot leave on null handler! Address: 0x "; uint y = *((uint*)(BasePointer + 4)); int offset = 48; #region Address while (offset > 40) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(5); // Try to cause fault *((byte*)0xDEADBEEF) = 0; } // Leaving a critical section cleanly // We need to handle 2 cases: // Case 1 : Leaving "try" or "catch" of a try-catch // Case 2 : Leaving the "try" of a try-finally if ((uint)State->CurrentHandlerPtr->FilterAddress != 0x0u) { // Case 1 : Leaving "try" or "catch" of a try-catch if (State->CurrentHandlerPtr->Ex != null) { Testing2.GC.DecrementRefCount((Testing2.Object)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex)); State->CurrentHandlerPtr->Ex = null; } State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte*)continuePtr); } else { // Case 2 : Leaving the "try" of a try-finally State->CurrentHandlerPtr->InHandler = 1; ArbitaryReturn(State->CurrentHandlerPtr->EBP, State->CurrentHandlerPtr->ESP, State->CurrentHandlerPtr->HandlerAddress); } }
public static unsafe void HandleEndFinally() { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = "Cannot end finally on null handler!"; BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(5); // Try to cause fault *((byte*)0xDEADBEEF) = 0; } // Leaving a "finally" critical section cleanly // We need to handle 2 cases: // Case 1 : Pending exception // Case 2 : No pending exception if (State->CurrentHandlerPtr->ExPending != 0) { // Case 1 : Pending exception HandleException(); } else { // Case 2 : No pending exception State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte*)*((uint*)(BasePointer + 4))); } }
public static unsafe void HandleLeave(void *continuePtr) { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = "Cannot leave on null handler! Address: 0x "; uint y = *((uint *)(BasePointer + 4)); int offset = 48; #region Address while (offset > 40) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(5); // Try to cause fault *((byte *)0xDEADBEEF) = 0; } // Leaving a critical section cleanly // We need to handle 2 cases: // Case 1 : Leaving "try" or "catch" of a try-catch // Case 2 : Leaving the "try" of a try-finally if ((uint)State->CurrentHandlerPtr->FilterAddress != 0x0u) { // Case 1 : Leaving "try" or "catch" of a try-catch if (State->CurrentHandlerPtr->Ex != null) { Testing2.GC.DecrementRefCount((Testing2.Object)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex)); State->CurrentHandlerPtr->Ex = null; } State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte *)continuePtr); } else { // Case 2 : Leaving the "try" of a try-finally State->CurrentHandlerPtr->InHandler = 1; ArbitaryReturn(State->CurrentHandlerPtr->EBP, State->CurrentHandlerPtr->ESP, State->CurrentHandlerPtr->HandlerAddress); } }
public static void *AllocZeroed(UInt32 size, Testing2.String caller) { return(AllocZeroed(size, 1, caller)); }
public static void *NewString(int length) { if (!Enabled) { BasicConsole.SetTextColour(BasicConsole.warning_colour); BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled."); BasicConsole.DelayOutput(10); BasicConsole.SetTextColour(BasicConsole.default_colour); return(null); } //try { if (length < 0) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Error! GC can't create a new string because \"length\" is less than 0."); BasicConsole.DelayOutput(5); BasicConsole.SetTextColour(BasicConsole.default_colour); return(null); //ExceptionMethods.Throw_OverflowException(); } InsideGC = true; //Alloc space for GC header that prefixes object data //Alloc space for new string object //Alloc space for new string chars uint totalSize = ((Testing2.Type) typeof(Testing2.String)).Size; totalSize += /*char size in bytes*/ 2 * (uint)length; totalSize += (uint)sizeof(GCHeader); GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewString"); if ((UInt32)newObjPtr == 0) { InsideGC = false; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Error! GC can't create a new string because the heap returned a null pointer."); BasicConsole.DelayOutput(10); BasicConsole.SetTextColour(BasicConsole.default_colour); return(null); } NumObjs++; NumStrings++; //Initialise the GCHeader SetSignature(newObjPtr); //RefCount to 0 initially because of Testing2.String.New should be used // - In theory, New should be called, creates new string and passes it back to caller // Caller is then required to store the string in a variable resulting in inc. // ref count so ref count = 1 in only stored location. // Caller is not allowed to just "discard" (i.e. use Pop IL op or C# that generates // Pop IL op) so ref count will always at some point be incremented and later // decremented by managed code. OR the variable will stay in a static var until // the OS exits... newObjPtr->RefCount = 0; Testing2.String newStr = (Testing2.String)Utilities.ObjectUtilities.GetObject(newObjPtr + 1); newStr._Type = (Testing2.Type) typeof(Testing2.String); newStr.length = length; //Move past GCHeader byte *newObjBytePtr = (byte *)(newObjPtr + 1); InsideGC = false; return(newObjBytePtr); } //finally { //ExitCritical(); } }
public static void FillString(uint value, int offset, Testing2.String str) { int end = offset - 8; while (offset > end) { uint rem = value & 0xFu; switch (rem) { case 0: str[offset] = '0'; break; case 1: str[offset] = '1'; break; case 2: str[offset] = '2'; break; case 3: str[offset] = '3'; break; case 4: str[offset] = '4'; break; case 5: str[offset] = '5'; break; case 6: str[offset] = '6'; break; case 7: str[offset] = '7'; break; case 8: str[offset] = '8'; break; case 9: str[offset] = '9'; break; case 10: str[offset] = 'A'; break; case 11: str[offset] = 'B'; break; case 12: str[offset] = 'C'; break; case 13: str[offset] = 'D'; break; case 14: str[offset] = 'E'; break; case 15: str[offset] = 'F'; break; } value >>= 4; offset--; } }