Beispiel #1
0
        public static Code EndCatch(this Code code, ISehHandlerBlock handlerBlock)
        {
            IInstruction jump;

            code.AddRange(code.Provider.EndCatch(handlerBlock, false, false, out jump));
            return(code);
        }
Beispiel #2
0
        void BeginCatch(ISehHandlerBlock block, AbcCode code, AbcExceptionHandler e, ref int var, bool dupException, bool catchAnyException)
        {
            var beginIndex = code.Count;

            var catchInfo = new CatchInfo
            {
                CatchAnyException = catchAnyException
            };
            bool coerceAny = catchAnyException;

            if (var < 0 || catchAnyException)
            {
                coerceAny           = true;
                var                 = SharedExceptionVar;
                catchInfo.IsTempVar = true;
            }
            catchInfo.ExceptionVar = var;
            e.LocalVariable        = var;

            var handlerInfo = block.Tag as SehHandlerInfo;

            if (handlerInfo == null)
            {
                handlerInfo = new SehHandlerInfo {
                    CatchInfo = catchInfo
                };
                block.Tag = handlerInfo;
            }
            else
            {
                handlerInfo.CatchInfo = catchInfo;
            }

            //NOTE: we store exception in temp variable to use for rethrow operation
            if (dupException && !catchAnyException)
            {
                code.Dup();
            }

            if (coerceAny)
            {
                code.CoerceAnyType();
            }

            //store exception in variable to use for rethrow operation
            code.SetLocal(var);

            _resolver.Add(code[beginIndex], new ExceptionTarget(e));
        }
Beispiel #3
0
        static bool MustCatchAnyException(ISehHandlerBlock block)
        {
            var prev = block.PrevHandler;

            if (prev != null)
            {
                var info = prev.Tag as SehHandlerInfo;
                if (info != null)
                {
                    return(info.CatchInfo.CatchAnyException);
                }
            }

            return(block.Owner.Handlers.Any(handler => IsVesException(handler.ExceptionType)));
        }
Beispiel #4
0
        public IEnumerable <IInstruction> EndCatch(ISehHandlerBlock handlerBlock, bool isLast, bool generateExit, out IInstruction jump)
        {
            var ci = handlerBlock.GetCatchInfo();

            jump = null;
            var code = new AbcCode(_abc);

            if (PopCatchScope)
            {
                code.PopScope(); //pops catch scope
            }
            //we now no need in exception variable
            KillExceptionVariable(code, ci);

            //NOTE: no need to generate exit jump for last catch block
            if (generateExit && !isLast)
            {
                jump = code.Goto();
            }

            return(code);
        }
Beispiel #5
0
        public IEnumerable <IInstruction> BeginCatch(ISehHandlerBlock handlerBlock)
        {
            var tryBlock = handlerBlock.Owner;

            var exceptionType = handlerBlock.ExceptionType;

            if (exceptionType != null)
            {
                EnsureType(exceptionType);
            }

            var seh = new AbcExceptionHandler();

            _body.Exceptions.Add(seh);
            _resolver.Add(tryBlock, new ExceptionFrom(seh), new ExceptionTo(seh));

            bool catchAnyException = MustCatchAnyException(handlerBlock);

            seh.Type = catchAnyException ? _abc.BuiltinTypes.Object : handlerBlock.ExceptionType.GetMultiname();

            int var = handlerBlock.ExceptionVariable;

            if (var >= 0)
            {
                var = GetVarIndex(var);
            }

            var code = new AbcCode(_abc);

            BeginCatch(handlerBlock, code, seh, ref var, !_popException, catchAnyException);

            if (catchAnyException)
            {
                RouteException(code, handlerBlock, var);
                _sehsToResolve.Add(tryBlock);
            }

            return(code);
        }
Beispiel #6
0
        private IEnumerable <IInstruction> EndFinally(ISehHandlerBlock block, bool fault)
        {
            var handlerInfo = block.GetHandlerInfo();
            var ci          = handlerInfo.CatchInfo;
            var fi          = handlerInfo.FinallyInfo;

            if (fi.IsFault != fault)
            {
                throw new InvalidOperationException("Finally block type mistmatch!");
            }

            var code = new AbcCode(_abc);

            if (fault)
            {
                code.GetLocal(ci.ExceptionVar);
                KillExceptionVariable(code, ci);
                code.Throw();
            }
            else
            {
                // check if we should rethrow exception
                code.GetLocal(fi.RethrowFlagVariable);
                // trying to fix IVDiffGramTest
                // KillTempVar(code, fi.RethrowFlagVariable);
                var br = code.IfFalse();

                code.GetLocal(ci.ExceptionVar);
                KillExceptionVariable(code, ci);
                var end = code.Throw();

                br.GotoNext(end);
            }

            return(code);
        }
Beispiel #7
0
 public static Code EndFinally(this Code code, ISehHandlerBlock handlerBlock)
 {
     code.AddRange(code.Provider.EndFinally(handlerBlock));
     return(code);
 }
Beispiel #8
0
 public static Code BeginFault(this Code code, ISehHandlerBlock handlerBlock)
 {
     code.AddRange(code.Provider.BeginFault(handlerBlock));
     return(code);
 }
Beispiel #9
0
 public IEnumerable <IInstruction> EndFault(ISehHandlerBlock block)
 {
     return(EndFinally(block, true));
 }
Beispiel #10
0
 public IEnumerable <IInstruction> BeginFinally(ISehHandlerBlock block)
 {
     return(BeginFinally(block, false));
 }
Beispiel #11
0
        private IEnumerable <IInstruction> BeginFinally(ISehHandlerBlock block, bool fault)
        {
            var e = new AbcExceptionHandler();

            _body.Exceptions.Add(e);
            e.To     = -1;
            e.Target = -1;

            var fi = new FinallyInfo {
                IsFault = fault
            };

            block.Tag = new SehHandlerInfo {
                FinallyInfo = fi
            };

            _resolver.Add(block.Owner, new ExceptionFrom(e), null);

            var code = new AbcCode(_abc);

            if (!fault)
            {
                //Reset rethrow flag
                fi.RethrowFlagVariable = NewTempVar(true);
                _initializableTempVars.Add(new TempVar(fi.RethrowFlagVariable, new Instruction(InstructionCode.Pushfalse)));
                code.PushNativeBool(false);
                // Trying to fix IVDiffGramTest. Coercing to any type does not help. The test failed with error:
                // The Dark Side clouds everything. Impossible to see, the future is. (c) Yoda
                // code.CoerceAnyType();
                code.SetLocal(fi.RethrowFlagVariable);
            }

            //Add goto finally body
            var gotoBody = code.Goto();

            _resolver.Add(gotoBody, new ExceptionTo(e));

            //NOTE: Insert empty handler to catch unhandled or rethrown exception
            //begin catch
            BeginCatch(block, code, e, ref fi.ExceptionVariable, false, false);

            var end = (Instruction)code[code.Count - 1];

            if (!fault)
            {
                //Set rethrow flag to true to rethrow exception
                code.PushNativeBool(true);
                // Trying to fix IVDiffGramTest. Coercing to any type does not help. The test failed with error:
                // The Dark Side clouds everything. Impossible to see, the future is. (c) Yoda
                // code.CoerceAnyType();
                end = code.SetLocal(fi.RethrowFlagVariable);
            }

            if (PopCatchScope)
            {
                end = code.PopScope(); //pops catch scope
            }
            //end of catch

            gotoBody.GotoNext(end);

            return(code);
        }
Beispiel #12
0
        void RouteException(AbcCode code, ISehHandlerBlock block, int var)
        {
            var exceptionType = block.ExceptionType;

            if (block.PrevHandler == null)
            {
                //if err is AVM error then we translate it to System.Exception.
                //code.GetLocal(var);
                //code.As(AvmTypeCode.Error);
                //code.PushNull();
                //var ifNotError = code.IfEquals();

                code.GetLocal(var);
                code.As(SystemTypes.Exception, true);
                code.PushNull();
                var ifExc = code.IfNotEquals();

                code.GetLocal(var);
                code.As(AvmTypeCode.Error);
                code.PushNull();
                var ifNotError = code.IfEquals();

                CallToException(code, var);
                code.CoerceAnyType();
                code.SetLocal(var);

                //check my exception
                var labelNotError = code.Label();
                ifExc.BranchTarget      = labelNotError;
                ifNotError.BranchTarget = labelNotError;
            }

            code.GetLocal(var);

            var handlerInfo = (SehHandlerInfo)block.Tag;

            handlerInfo.CheckExceptionLabel = code.Label();
            //NOTE: Exception on stack can be routed from previous handlers
            code.SetLocal(var);
            code.GetLocal(var);
            code.As(exceptionType, true);
            code.PushNull();
            var ifMyException = code.IfNotEquals();

            //Routing to another exception handler or rethrow
            //Instruction routing = Label();
            if (block.NextHandler == null)
            {
                code.GetLocal(var);
                code.Throw();
            }
            else
            {
                code.GetLocal(var);
                handlerInfo.JumpToNextHandler = code.Goto();
            }

            //Normal Execution: Prepare stack for handler
            var normal = code.Label();

            ifMyException.BranchTarget = normal;

            code.GetLocal(var);
            code.Coerce(exceptionType, true);

            //21 instructions for first handler
            //11 instructions for other handlers
        }
Beispiel #13
0
 public IEnumerable <IInstruction> EndFault(ISehHandlerBlock block)
 {
     return(NopArray);
 }
Beispiel #14
0
 public IEnumerable <IInstruction> BeginFinally(ISehHandlerBlock block)
 {
     return(NopArray);
 }
Beispiel #15
0
 public IEnumerable <IInstruction> EndCatch(ISehHandlerBlock block, bool isLast, bool generateExit, out IInstruction jump)
 {
     jump = OpNop;
     return(NopArray);
 }
Beispiel #16
0
 public IEnumerable <IInstruction> BeginCatch(ISehHandlerBlock handlerBlock)
 {
     return(NopArray);
 }