public IEnumerable <IInstruction> As(IType type) { EnsureType(type); var code = new AbcCode(_abc); code.As(type); 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 }