public static Code EndCatch(this Code code, ISehHandlerBlock handlerBlock) { IInstruction jump; code.AddRange(code.Provider.EndCatch(handlerBlock, false, false, out jump)); return(code); }
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)); }
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))); }
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); }
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); }
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); }
public static Code EndFinally(this Code code, ISehHandlerBlock handlerBlock) { code.AddRange(code.Provider.EndFinally(handlerBlock)); return(code); }
public static Code BeginFault(this Code code, ISehHandlerBlock handlerBlock) { code.AddRange(code.Provider.BeginFault(handlerBlock)); return(code); }
public IEnumerable <IInstruction> EndFault(ISehHandlerBlock block) { return(EndFinally(block, true)); }
public IEnumerable <IInstruction> BeginFinally(ISehHandlerBlock block) { return(BeginFinally(block, false)); }
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); }
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 }
public IEnumerable <IInstruction> EndFault(ISehHandlerBlock block) { return(NopArray); }
public IEnumerable <IInstruction> BeginFinally(ISehHandlerBlock block) { return(NopArray); }
public IEnumerable <IInstruction> EndCatch(ISehHandlerBlock block, bool isLast, bool generateExit, out IInstruction jump) { jump = OpNop; return(NopArray); }
public IEnumerable <IInstruction> BeginCatch(ISehHandlerBlock handlerBlock) { return(NopArray); }