Example #1
0
        private static void SetupEHState(DarksVMContext ctx, object ex)
        {
            EHState ehState;

            if (ctx.EHStates.Count != 0)
            {
                ehState = ctx.EHStates[ctx.EHStates.Count - 1];
                if (ehState.CurrentFrame != null)
                {
                    if (ehState.CurrentProcess == EHState.EHProcess.Searching)
                    {
                        ctx.Registers[DarksVMConstants.REG_R1].U1 = 0;
                    }
                    else if (ehState.CurrentProcess == EHState.EHProcess.Unwinding)
                    {
                        ehState.ExceptionObj = ex;
                    }
                    return;
                }
            }
            ehState = new EHState
            {
                OldBP          = ctx.Registers[DarksVMConstants.REG_BP],
                OldSP          = ctx.Registers[DarksVMConstants.REG_SP],
                ExceptionObj   = ex,
                CurrentProcess = EHState.EHProcess.Searching,
                CurrentFrame   = null,
                HandlerFrame   = null
            };
            ctx.EHStates.Add(ehState);
        }
Example #2
0
        static void SetupEHState(VMContext ctx, object ex)
        {
            EHState ehState;

            if (ctx.EHStates.Count != 0)
            {
                ehState = ctx.EHStates[ctx.EHStates.Count - 1];
                if (ehState.CurrentFrame != null)
                {
                    if (ehState.CurrentProcess == EHState.EHProcess.Searching)
                    {
                        // Return from filter => throw exception, default to 0 by Partition III 3.34
                        ctx.Registers[Constants.REG_R1].U1 = 0;
                    }
                    else if (ehState.CurrentProcess == EHState.EHProcess.Unwinding)
                    {
                        // Return from finally => throw exception, replace current exception
                        // https://stackoverflow.com/questions/2911215/what-happens-if-a-finally-block-throws-an-exception
                        ehState.ExceptionObj = ex;
                    }
                    return;
                }
            }
            ehState = new EHState {
                OldBP          = ctx.Registers[Constants.REG_BP],
                OldSP          = ctx.Registers[Constants.REG_SP],
                ExceptionObj   = ex,
                CurrentProcess = EHState.EHProcess.Searching,
                CurrentFrame   = null,
                HandlerFrame   = null
            };
            ctx.EHStates.Add(ehState);
        }
Example #3
0
        private static void HandleEH(DarksVMContext ctx, ref ExecutionState state)
        {
            EHState ehState = ctx.EHStates[ctx.EHStates.Count - 1];

            switch (ehState.CurrentProcess)
            {
            case EHState.EHProcess.Searching:
            {
                if (ehState.CurrentFrame != null)
                {
                    // Return from filter
                    bool filterResult = ctx.Registers[DarksVMConstants.REG_R1].U1 != 0;
                    if (filterResult)
                    {
                        ehState.CurrentProcess = EHState.EHProcess.Unwinding;
                        ehState.HandlerFrame   = ehState.CurrentFrame;
                        ehState.CurrentFrame   = ctx.EHStack.Count;
                        state = ExecutionState.Next;
                        goto case EHState.EHProcess.Unwinding;
                    }
                    ehState.CurrentFrame--;
                }
                else
                {
                    ehState.CurrentFrame = ctx.EHStack.Count - 1;
                }

                Type exType = ehState.ExceptionObj.GetType();
                for (; ehState.CurrentFrame >= 0 && ehState.HandlerFrame == null; ehState.CurrentFrame--)
                {
                    EHFrame frame = ctx.EHStack[ehState.CurrentFrame.Value];
                    if (frame.EHType == DarksVMConstants.EH_FILTER)
                    {
                        // Run filter
                        uint sp = ehState.OldSP.U4;
                        ctx.Stack.SetTopPosition(++sp);
                        ctx.Stack[sp] = new DarksVMSlot {
                            O = ehState.ExceptionObj
                        };
                        ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
                        ctx.Registers[DarksVMConstants.REG_SP].U4 = sp;
                        ctx.Registers[DarksVMConstants.REG_BP]    = frame.BP;
                        ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.FilterAddr;
                        break;
                    }
                    if (frame.EHType == DarksVMConstants.EH_CATCH)
                    {
                        if (frame.CatchType.IsAssignableFrom(exType))
                        {
                            ehState.CurrentProcess = EHState.EHProcess.Unwinding;
                            ehState.HandlerFrame   = ehState.CurrentFrame;
                            ehState.CurrentFrame   = ctx.EHStack.Count;
                            goto case EHState.EHProcess.Unwinding;
                        }
                    }
                }
                if (ehState.CurrentFrame == -1 && ehState.HandlerFrame == null)
                {
                    ctx.EHStates.RemoveAt(ctx.EHStates.Count - 1);
                    state = ExecutionState.Rethrow;
                    if (ctx.EHStates.Count == 0)
                    {
                        HandleRethrow(ctx, ehState.ExceptionObj);
                    }
                }
                else
                {
                    state = ExecutionState.Next;
                }
                break;
            }

            case EHState.EHProcess.Unwinding:
            {
                ehState.CurrentFrame--;
                int i;
                for (i = ehState.CurrentFrame.Value; i > ehState.HandlerFrame.Value; i--)
                {
                    EHFrame frame = ctx.EHStack[i];
                    ctx.EHStack.RemoveAt(i);
                    if (frame.EHType == DarksVMConstants.EH_FAULT || frame.EHType == DarksVMConstants.EH_FINALLY)
                    {
                        // Run finally
                        SetupFinallyFrame(ctx, frame);
                        break;
                    }
                }
                ehState.CurrentFrame = i;

                if (ehState.CurrentFrame == ehState.HandlerFrame)
                {
                    EHFrame frame = ctx.EHStack[ehState.HandlerFrame.Value];
                    ctx.EHStack.RemoveAt(ehState.HandlerFrame.Value);
                    // Run handler
                    frame.SP.U4++;
                    ctx.Stack.SetTopPosition(frame.SP.U4);
                    ctx.Stack[frame.SP.U4] = new DarksVMSlot {
                        O = ehState.ExceptionObj
                    };

                    ctx.Registers[DarksVMConstants.REG_K1].U1 = 0;
                    ctx.Registers[DarksVMConstants.REG_SP]    = frame.SP;
                    ctx.Registers[DarksVMConstants.REG_BP]    = frame.BP;
                    ctx.Registers[DarksVMConstants.REG_IP].U8 = frame.HandlerAddr;

                    ctx.EHStates.RemoveAt(ctx.EHStates.Count - 1);
                }
                state = ExecutionState.Next;
                break;
            }

            default:
                throw new ExecutionEngineException();
            }
        }