Beispiel #1
0
        public static void Main()
        {
            ExceptionMethods.AddExceptionHandlerInfo(null, null);

            UART.Init();
            BasicConsole.Init();
            BasicConsole.WriteLine("Kernel executing...");

            try
            {
                ManagedMain();
            }
            catch
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Startup error! " + ExceptionMethods.CurrentException.Message);
                BasicConsole.WriteLine("FlingOS forced to halt!");
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

            bool OK2 = true;

            while (OK2)
            {
                ;
            }
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        public static unsafe void AddExceptionHandlerInfo(
            void *handlerPtr,
            void *filterPtr)
        {
            if (State == null)
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! ExceptionMethods.State is null.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

            AddExceptionHandlerInfo_EntryStackState *BasePtr = (AddExceptionHandlerInfo_EntryStackState *)BasePointer;

            uint LocalsSize = (uint)BasePtr - (uint)StackPointer;

            // Create space for setting up handler info
            StackPointer -= sizeof(ExceptionHandlerInfo);

            // Setup handler info
            ExceptionHandlerInfo *ExHndlrPtr = (ExceptionHandlerInfo *)StackPointer;

            ExHndlrPtr->EBP = BasePtr->EBP;
            //                  EBP + 8 (for ret addr, ebp) + 8 (for args) - sizeof(ExceptionHandlerInfo)
            ExHndlrPtr->ESP            = (uint)BasePtr + 8 + 8 - (uint)sizeof(ExceptionHandlerInfo);
            ExHndlrPtr->FilterAddress  = (byte *)filterPtr;
            ExHndlrPtr->HandlerAddress = (byte *)handlerPtr;
            ExHndlrPtr->PrevHandlerPtr = State->CurrentHandlerPtr;
            ExHndlrPtr->InHandler      = 0;
            ExHndlrPtr->ExPending      = 0;
            ExHndlrPtr->Ex             = null;

            State->CurrentHandlerPtr = (ExceptionHandlerInfo *)((byte *)ExHndlrPtr + (LocalsSize + 12));

            StackPointer -= 8; // For duplicate (empty) args
            StackPointer -= 8; // For duplicate ebp, ret addr

            // Setup the duplicate stack data
            //  - Nothing to do for args - duplicate values don't matter
            //  - Copy over ebp and return address
            uint *DuplicateValsStackPointer = (uint *)StackPointer;

            *DuplicateValsStackPointer = BasePtr->EBP;
            *(DuplicateValsStackPointer + 1) = BasePtr->RetAddr;

            ShiftStack((byte *)ExHndlrPtr + sizeof(ExceptionHandlerInfo) - 4, LocalsSize + 12);

            // Shift stack pointer to correct position - eliminates "empty space" of duplicates
            StackPointer += 16;

            // MethodEnd will:
            //      - Add size of locals to esp
            //      - Pop EBP
            //      - Ret to ret address
            // Caller will:
            //      - Add size of args to esp
            // Which should leave the stack at the bottom of the (shifted up) ex handler info
        }
Beispiel #4
0
        public static void *NewObj(Testing2.Type theType)
        {
            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
            //{
            InsideGC = true;

            //Alloc space for GC header that prefixes object data
            //Alloc space for new object

            uint totalSize = theType.Size;

            totalSize += (uint)sizeof(GCHeader);

            GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewObject");

            if ((UInt32)newObjPtr == 0)
            {
                InsideGC = false;

                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't create a new object because the heap returned a null pointer.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

            NumObjs++;

            //Initialise the GCHeader
            SetSignature(newObjPtr);
            newObjPtr->RefCount = 1;
            //Initialise the object _Type field
            Testing2.ObjectWithType newObj = (Testing2.ObjectWithType)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
            newObj._Type = theType;

            //Move past GCHeader
            byte *newObjBytePtr = (byte *)(newObjPtr + 1);

            InsideGC = false;

            return(newObjBytePtr);
            //}
            //finally
            //{
            //}
        }
Beispiel #5
0
        public static void MemSet(byte val, byte *to, uint length)
        {
            BasicConsole.WriteLine(((Testing2.String) "Setting ") + (uint)to + " to " + val + ", size: " + length);
            //BasicConsole.DumpMemory(to, (int)length);

            uint tempLength = length;

            while (tempLength-- > 0)
            {
                *to++ = val;
            }

            //BasicConsole.DumpMemory(to - length, (int)length);
        }
Beispiel #6
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;
        }
Beispiel #7
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)));
            }
        }
Beispiel #8
0
        public static void _IncrementRefCount(byte *objPtr)
        {
            if ((uint)objPtr < (uint)sizeof(GCHeader))
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't increment ref count of an object in low memory.");
                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

            objPtr -= sizeof(GCHeader);
            GCHeader *gcHeaderPtr = (GCHeader *)objPtr;

            if (CheckSignature(gcHeaderPtr))
            {
                gcHeaderPtr->RefCount++;

                if (gcHeaderPtr->RefCount > 0)
                {
                    RemoveObjectToCleanup(gcHeaderPtr);
                }
            }
        }
Beispiel #9
0
        public static void ManagedMain()
        {
            InitialiseInterrupts();

            EnableInterrupts();
            BasicConsole.WriteLine("Interrupts enabled");

            #region Struct Tests

            //int size = sizeof(AStruct);

            //if (size != 15)
            //{
            //    UART.Write("Bad size\n");
            //}
            //else
            //{
            //    UART.Write("Good size\n");
            //}

            //AStruct Inst = new AStruct();
            //Inst.a = 1;
            //Inst.b = 2;
            //Inst.c = 4;
            //Inst.d = 8;

            //if (Inst.a != 1)
            //{
            //    UART.Write("Inst.a wrong\n");
            //}
            //else
            //{
            //    UART.Write("Inst.a right\n");
            //}
            //if (Inst.b != 2)
            //{
            //    UART.Write("Inst.b wrong\n");
            //}
            //else
            //{
            //    UART.Write("Inst.b right\n");
            //}
            //if (Inst.c != 4)
            //{
            //    UART.Write("Inst.c wrong\n");
            //}
            //else
            //{
            //    UART.Write("Inst.c right\n");
            //}
            //if (Inst.d != 8)
            //{
            //    UART.Write("Inst.d wrong\n");
            //}
            //else
            //{
            //    UART.Write("Inst.d right\n");
            //}

            //AStruct* HeapInst = (AStruct*)Heap.AllocZeroed((uint)sizeof(AStruct), "Kernel:Main");
            //if (HeapInst == null)
            //{
            //    UART.Write("HeapInst null\n");
            //}
            //else
            //{
            //    UART.Write("HeapInst not null\n");
            //}

            //HeapInst->a = 1;
            //HeapInst->b = 2;
            //HeapInst->c = 4;
            //HeapInst->d = 8;

            //if (HeapInst->a != 1)
            //{
            //    UART.Write("HeapInst->a wrong\n");
            //}
            //else
            //{
            //    UART.Write("HeapInst->a right\n");
            //}
            //if (HeapInst->b != 2)
            //{
            //    UART.Write("HeapInst->b wrong\n");
            //}
            //else
            //{
            //    UART.Write("HeapInst->b right\n");
            //}
            //if (HeapInst->c != 4)
            //{
            //    UART.Write("HeapInst->c wrong\n");
            //}
            //else
            //{
            //    UART.Write("HeapInst->c right\n");
            //}
            //if (HeapInst->d != 8)
            //{
            //    UART.Write("HeapInst->d wrong\n");
            //}
            //else
            //{
            //    UART.Write("HeapInst->d right\n");
            //}

            #endregion

            #region Array Tests Value Types

            //int[] array = new int[4];

            //int len = array.Length;

            //if (len != 4)
            //{
            //    UART.Write("Array length wrong\n");
            //}
            //else
            //{
            //    UART.Write("Array length right\n");
            //}

            //array[0] = 5;
            //array[1] = 10;
            //array[2] = 15;
            //array[3] = 20;

            //if (array[0] != 5)
            //{
            //    UART.Write("array[0] wrong\n");
            //}
            //else
            //{
            //    UART.Write("array[0] right\n");
            //}

            //if (array[1] != 10)
            //{
            //    UART.Write("array[1] wrong\n");
            //}
            //else
            //{
            //    UART.Write("array[1] right\n");
            //}

            //if (array[2] != 15)
            //{
            //    UART.Write("array[2] wrong\n");
            //}
            //else
            //{
            //    UART.Write("array[2] right\n");
            //}

            //if (array[3] != 20)
            //{
            //    UART.Write("array[3] wrong\n");
            //}
            //else
            //{
            //    UART.Write("array[3] right\n");
            //}

            #endregion

            #region Array Tests Using Structs

            //AStruct[] arr = new AStruct[3];
            //int length = arr.Length;

            //if (length != 3)
            //{
            //    UART.Write("Struct array length wrong\n");
            //}
            //else
            //{
            //    UART.Write("Struct array length right\n");
            //}

            //arr[0].a = 255;
            //arr[0].b = 32767;
            //arr[0].c = 2147483647;
            //arr[0].d = 9223372036854775807;

            //if (arr[0].a != 255)
            //{
            //    UART.Write("arr[0].a wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[0].a right\n");
            //}
            //if (arr[0].b != 32767)
            //{
            //    UART.Write("arr[0].b wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[0].b right\n");
            //}
            //if (arr[0].c != 2147483647)
            //{
            //    UART.Write("arr[0].c wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[0].c right\n");
            //}
            //if (arr[0].d != 9223372036854775807)
            //{
            //    UART.Write("arr[0].d wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[0].d right\n");
            //}

            //arr[1].a = 0;
            //arr[1].b = 1;
            //arr[1].c = 2;
            //arr[1].d = 3;

            //if (arr[1].a != 0)
            //{
            //    UART.Write("arr[1].a wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[1].a right\n");
            //}
            //if (arr[1].b != 1)
            //{
            //    UART.Write("arr[1].b wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[1].b right\n");
            //}
            //if (arr[1].c != 2)
            //{
            //    UART.Write("arr[1].c wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[1].c right\n");
            //}
            //if (arr[1].d != 3)
            //{
            //    UART.Write("arr[1].d wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[1].d right\n");
            //}

            //arr[2].a = 100;
            //arr[2].b = 3000;
            //arr[2].c = 5777;
            //arr[2].d = 99876;

            //if (arr[2].a != 100)
            //{
            //    UART.Write("arr[2].a wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[2].a right\n");
            //}
            //if (arr[2].b != 3000)
            //{
            //    UART.Write("arr[2].b wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[2].b right\n");
            //}
            //if (arr[2].c != 5777)
            //{
            //    UART.Write("arr[2].c wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[2].c right\n");
            //}
            //if (arr[2].d != 99876)
            //{
            //    UART.Write("arr[2].d wrong\n");
            //}
            //else
            //{
            //    UART.Write("arr[2].d right\n");
            //}

            #endregion

            #region String Tests

            //BasicConsole.WriteLine("Test BasicConsole write line!");

            //int testNum = 5;

            //Testing2.String ATestString = "Hello, world!";
            //BasicConsole.WriteLine(ATestString);

            //if (ATestString != "Hello, world!")
            //{
            //    BasicConsole.WriteLine("String equality does not work!");
            //}
            //else
            //{
            //    BasicConsole.WriteLine("String equality works.");
            //}

            //ATestString += " But wait! There's more...";
            //BasicConsole.WriteLine(ATestString);

            //ATestString += " We can even append numbers: " + (Testing2.String)testNum;
            //BasicConsole.WriteLine(ATestString);

            //BasicConsole.DumpMemory((byte*)Utilities.ObjectUtilities.GetHandle(ATestString) - sizeof(GCHeader), (int)(ATestString.length + Testing2.String.FieldsBytesSize + sizeof(GCHeader)));

            #endregion

            #region Objects

            //TestClass aClass = new TestClass();
            //BasicConsole.WriteLine("Object created!");
            //int fld = aClass.aField;

            //if (fld != 9)
            //{
            //    UART.Write("Class field wrong\n");
            //}
            //else
            //{
            //    UART.Write("Class field right\n");
            //}

            //int arg = 10;
            //int arg1 = aClass.aMethodInt(arg);

            //if (arg1 != 30)
            //{
            //    UART.Write("Class method int wrong\n");
            //}
            //else
            //{
            //    UART.Write("Class method int right\n");
            //}

            //aClass.aMethodVoid();
            //int arg2 = aClass.aMethodField(arg);

            //if (arg2 != 90)
            //{
            //    UART.Write("Class method field wrong\n");
            //}
            //else
            //{
            //    UART.Write("Class method field right\n");
            //}

            #endregion


            Timer.Init();

            BasicConsole.WriteLine("Okay");

            bool OK        = true;
            uint lastCount = count;
            while (OK)
            {
                if (count > lastCount)
                {
                    BasicConsole.WriteLine(count);
                    lastCount = count + 0;
                }
            }
        }
Beispiel #10
0
        public static void _DecrementRefCount(byte *objPtr)
        {
            if ((uint)objPtr < (uint)sizeof(GCHeader))
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't decrement ref count of an object in low memory.");
                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

            GCHeader *gcHeaderPtr = (GCHeader *)(objPtr - sizeof(GCHeader));

            if (CheckSignature(gcHeaderPtr))
            {
                gcHeaderPtr->RefCount--;

                //If the ref count goes below 0 then there was a circular reference somewhere.
                //  In actuality we don't care we can just only do cleanup when the ref count is
                //  exactly 0.
                if (gcHeaderPtr->RefCount == 0)
                {
#if GC_TRACE
                    BasicConsole.WriteLine("Cleaned up object.");
#endif

                    Testing2.Object obj = (Testing2.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                    if (obj is Testing2.Array)
                    {
                        //Decrement ref count of elements
                        Testing2.Array arr = (Testing2.Array)obj;
                        if (!arr.elemType.IsValueType)
                        {
                            Testing2.Object[] objArr = (Testing2.Object[])Utilities.ObjectUtilities.GetObject(objPtr);
                            for (int i = 0; i < arr.length; i++)
                            {
                                DecrementRefCount(objArr[i], true);
                            }
                        }
                    }
                    //Cleanup fields
                    FieldInfo *FieldInfoPtr = obj._Type.FieldTablePtr;
                    //Loop through all fields. The if-block at the end handles moving to parent
                    //  fields.
                    while (FieldInfoPtr != null)
                    {
                        if (FieldInfoPtr->Size > 0)
                        {
                            Testing2.Type fieldType = (Testing2.Type)Utilities.ObjectUtilities.GetObject(FieldInfoPtr->FieldType);
                            if (!fieldType.IsValueType &&
                                !fieldType.IsPointer)
                            {
                                byte *          fieldPtr    = objPtr + FieldInfoPtr->Offset;
                                Testing2.Object theFieldObj = (Testing2.Object)Utilities.ObjectUtilities.GetObject(fieldPtr);

                                DecrementRefCount(theFieldObj, true);

#if GC_TRACE
                                BasicConsole.WriteLine("Cleaned up field.");
#endif
                            }

                            FieldInfoPtr++;
                        }

                        if (FieldInfoPtr->Size == 0)
                        {
                            FieldInfoPtr = (FieldInfo *)FieldInfoPtr->FieldType;
                        }
                    }

                    AddObjectToCleanup(gcHeaderPtr, objPtr);
                }
            }
        }
Beispiel #11
0
        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();
            }
        }
Beispiel #12
0
        public static void *NewArr(int length, Testing2.Type elemType)
        {
            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)
                {
                    UART.Write("length < 0. Overflow exception.");
                    return(null);
                    //ExceptionMethods.Throw_OverflowException();
                }

                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new array object
                //Alloc space for new array elems

                uint totalSize = ((Testing2.Type) typeof(Testing2.Array)).Size;
                if (elemType.IsValueType)
                {
                    totalSize += elemType.Size * (uint)length;
                }
                else
                {
                    totalSize += elemType.StackSize * (uint)length;
                }
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewArray");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new array because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumObjs++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                newObjPtr->RefCount = 1;

                Testing2.Array newArr = (Testing2.Array)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newArr._Type    = (Testing2.Type) typeof(Testing2.Array);
                newArr.length   = length;
                newArr.elemType = elemType;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            //finally
            {
            }
        }
Beispiel #13
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);
            }
        }
Beispiel #14
0
        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);
        }