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)); }
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 }