void WriteExceptionHandlerSpecific(ExceptionHandler handler) { switch (handler.HandlerType) { case ExceptionHandlerType.Catch: WriteMetadataToken(metadata.LookupToken(handler.CatchType)); break; case ExceptionHandlerType.Filter: WriteInt32(handler.FilterStart.Offset); break; default: WriteInt32(0); break; } }
void ReadExceptionHandlerSpecific(ExceptionHandler handler) { switch (handler.HandlerType) { case ExceptionHandlerType.Catch: handler.CatchType = (TypeReference)reader.LookupToken(ReadToken()); break; case ExceptionHandlerType.Filter: handler.FilterStart = GetInstruction(ReadInt32()); break; default: Advance(4); break; } }
private static MethodBody CloneMethodBody(MethodBody body, MethodDefinition source, MethodDefinition target) { var context = target.DeclaringType.Module; var nb = new MethodBody(target) { MaxStackSize = body.MaxStackSize, InitLocals = body.InitLocals, CodeSize = body.CodeSize }; var worker = nb.GetILProcessor(); foreach (var var in body.Variables) nb.Variables.Add(new VariableDefinition( var.Name, FixTypeImport(context, source, target, var.VariableType))); foreach (var instr in body.Instructions) { var ni = new Instruction(instr.OpCode, OpCodes.Nop); switch (instr.OpCode.OperandType) { case OperandType.InlineArg: case OperandType.ShortInlineArg: if (instr.Operand == body.ThisParameter) ni.Operand = nb.ThisParameter; else { var param = body.Method.Parameters.IndexOf((ParameterDefinition)instr.Operand); ni.Operand = target.Parameters[param]; } break; case OperandType.InlineVar: case OperandType.ShortInlineVar: var var = body.Variables.IndexOf((VariableDefinition)instr.Operand); ni.Operand = nb.Variables[var]; break; case OperandType.InlineField: ni.Operand = FixFieldImport(context, source, target, (FieldReference)instr.Operand); break; case OperandType.InlineMethod: ni.Operand = FixMethodImport(context, source, target, (MethodReference)instr.Operand); break; case OperandType.InlineType: ni.Operand = FixTypeImport(context, source, target, (TypeReference)instr.Operand); break; case OperandType.InlineTok: if ((instr.Operand) is TypeReference) ni.Operand = FixTypeImport(context, source, target, (TypeReference)instr.Operand); else if ((instr.Operand) is FieldReference) ni.Operand = FixFieldImport(context, source, target, (FieldReference)instr.Operand); else if ((instr.Operand) is MethodReference) ni.Operand = FixMethodImport(context, source, target, (MethodReference)instr.Operand); break; case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: case OperandType.InlineSwitch: break; default: ni.Operand = instr.Operand; break; } worker.Append(ni); } for (var i = 0; i < body.Instructions.Count; i++) { var instr = nb.Instructions[i]; var oldi = body.Instructions[i]; switch (instr.OpCode.OperandType) { case OperandType.InlineSwitch: { var olds = (Instruction[])oldi.Operand; var targets = new Instruction[olds.Length]; for (var j = 0; j < targets.Length; j++) targets[j] = GetInstruction(body, nb, olds[j]); instr.Operand = targets; } break; case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: instr.Operand = GetInstruction(body, nb, (Instruction)oldi.Operand); break; } } foreach (var eh in body.ExceptionHandlers) { var neh = new ExceptionHandler(eh.HandlerType) { TryStart = GetInstruction(body, nb, eh.TryStart), TryEnd = GetInstruction(body, nb, eh.TryEnd), HandlerStart = GetInstruction(body, nb, eh.HandlerStart), HandlerEnd = GetInstruction(body, nb, eh.HandlerEnd) }; switch (eh.HandlerType) { case ExceptionHandlerType.Catch: neh.CatchType = FixTypeImport(context, source, target, eh.CatchType); break; case ExceptionHandlerType.Filter: neh.FilterStart = GetInstruction(body, nb, eh.FilterStart); break; } nb.ExceptionHandlers.Add(neh); } return nb; }
// inline ? void ReadExceptionHandlers(int count, Func<int> read_entry, Func<int> read_length) { for (int i = 0; i < count; i++) { var handler = new ExceptionHandler( (ExceptionHandlerType)(read_entry() & 0x7)); handler.TryStart = GetInstruction(read_entry()); handler.TryEnd = GetInstruction(handler.TryStart.Offset + read_length()); handler.HandlerStart = GetInstruction(read_entry()); handler.HandlerEnd = GetInstruction(handler.HandlerStart.Offset + read_length()); ReadExceptionHandlerSpecific(handler); this.body.ExceptionHandlers.Add(handler); } }