예제 #1
0
 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;
     }
 }
예제 #2
0
 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;
     }
 }
예제 #3
0
        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;
        }
예제 #4
0
        // 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);
            }
        }