本文整理汇总了C#中Mono.Cecil.Cil.MethodBody.ComputeOffsets方法的典型用法代码示例。如果您正苦于以下问题:C# MethodBody.ComputeOffsets方法的具体用法?C# MethodBody.ComputeOffsets怎么用?C# MethodBody.ComputeOffsets使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mono.Cecil.Cil.MethodBody
的用法示例。
在下文中一共展示了MethodBody.ComputeOffsets方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: CreateDefaultCtor
/// <summary>
/// Create the Ctor
/// </summary>
private static void CreateDefaultCtor(ReachableContext reachableContext, TypeDefinition type)
{
var typeSystem = type.Module.TypeSystem;
var ctor = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, typeSystem.Void);
ctor.DeclaringType = type;
var body = new MethodBody(ctor);
body.InitLocals = true;
ctor.Body = body;
// Prepare code
var seq = new ILSequence();
seq.Emit(OpCodes.Nop);
seq.Emit(OpCodes.Ret);
// Append ret sequence
seq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add ctor
type.Methods.Add(ctor);
ctor.SetReachable(reachableContext);
}
示例2: Disassemble
public void Disassemble(MethodBody body)
{
// start writing IL code
var method = body.Method;
var codesize = body.ComputeCodeSize();
var maxstacksize = body.ComputeMaxStackSize();
body.ComputeOffsets();
_o.WriteLine("// Code size {0} (0x{0:x})", codesize);
_o.WriteLine(".maxstack {0}", maxstacksize);
if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.EntryPoint == method)
_o.WriteLine(".entrypoint");
if (method.Body.HasVariables)
{
_o.Write(".locals ");
if (body.InitLocals)
_o.Write("init ");
_o.WriteLine("(");
_o.Indent();
foreach (var v in body.Variables)
{
_o.Write("[" + v.Index + "] ");
v.VariableType.WriteTo(_o);
if (!string.IsNullOrEmpty(v.Name))
{
_o.Write(' ');
_o.Write(DisassemblerHelpers.Escape(v.Name));
}
if (v.Index + 1 < body.Variables.Count)
_o.Write(',');
_o.WriteLine();
}
_o.Unindent();
_o.WriteLine(")");
}
_o.WriteLine();
if (body.Instructions.Count > 0)
{
var inst = body.Instructions[0];
var branchTargets = GetBranchTargets(body.Instructions);
WriteStructureBody(new IlStructure(body, codesize), branchTargets, ref inst);
}
else
{
// we ignore method without instructions (but it can have exception handlers)
_o.WriteLine();
}
}
示例3: EnsureClassCtor
/// <summary>
/// Ensure there is a class ctor.
/// </summary>
private static MethodDefinition EnsureClassCtor(ReachableContext reachableContext, TypeDefinition type)
{
var ctor = type.GetClassCtor();
if (ctor != null)
return ctor; // Already exists
// Create class ctor
var typeSystem = type.Module.TypeSystem;
ctor = new MethodDefinition(".cctor", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static | MethodAttributes.SpecialName, typeSystem.Void);
ctor.DeclaringType = type;
var body = new MethodBody(ctor);
body.InitLocals = true;
ctor.Body = body;
// Prepare code
var seq = new ILSequence();
seq.Emit(OpCodes.Nop);
seq.Emit(OpCodes.Ret);
// Append ret sequence
seq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add ctor
type.Methods.Add(ctor);
ctor.SetReachable(reachableContext);
return ctor;
}
示例4: AddBridge
/// <summary>
/// Add a method that has the same signature as basemethod and calls method.
/// </summary>
private MethodDefinition AddBridge(MethodDefinition method, MethodDefinition baseMethod)
{
var bridge = new MethodDefinition(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType) { HasThis = true };
var cloner = new TypeCloner(true, method.Module.TypeSystem);
bridge.ReturnType = cloner.Get(baseMethod.ReturnType, bridge);
bridge.IsAbstract = false;
// Clone parameters
foreach (var p in baseMethod.Parameters)
{
bridge.Parameters.Add(new ParameterDefinition(p.Name, p.Attributes, cloner.Get(p.ParameterType, bridge)));
}
// Create body
var body = new MethodBody(bridge);
bridge.Body = body;
// Create code
var seq = new ILSequence();
// this
seq.Emit(OpCodes.Ldarg_0);
// parameters
for (var i = 0; i < bridge.Parameters.Count; i++)
{
var p = bridge.Parameters[i];
seq.Emit(OpCodes.Ldarg, p);
if (baseMethod.Parameters[i].ParameterType.ContainsGenericParameter)
{
seq.Emit(OpCodes.Unbox, method.Parameters[i].ParameterType);
}
}
// Call actual method
seq.Emit(OpCodes.Call, method);
// Return
seq.Emit(OpCodes.Ret);
// Add code to body
seq.AppendTo(body);
body.ComputeOffsets();
// add overrides, so that we can find the method later
bridge.Overrides.Add(baseMethod);
// Add to class
method.DeclaringType.Methods.Add(bridge);
bridge.SetReachable(reachableContext);
return bridge;
}
示例5: CreateCopyFromMethod
/// <summary>
/// Create a CopyFrom method.
/// </summary>
private static MethodDefinition CreateCopyFromMethod(ReachableContext reachableContext, TypeDefinition type)
{
var typeSystem = type.Module.TypeSystem;
var method = new MethodDefinition(NameConstants.Struct.CopyFromMethodName, MethodAttributes.Public, type);
var sourceParam = new ParameterDefinition(type);
method.Parameters.Add(sourceParam);
method.DeclaringType = type;
var body = new MethodBody(method);
body.InitLocals = true;
method.Body = body;
// Prepare code
var seq = new ILSequence();
seq.Emit(OpCodes.Nop);
// Call base CopyFrom
var baseType = (type.BaseType != null) ? type.BaseType.GetElementType().Resolve() : null;
if ((baseType != null) && baseType.IsValueType && (baseType.FullName != "System.ValueType"))
{
var baseMethod = new MethodReference(NameConstants.Struct.CopyFromMethodName, baseType, baseType) { HasThis = true };
baseMethod.Parameters.Add(new ParameterDefinition(baseType));
seq.Emit(OpCodes.Ldarg, sourceParam);
seq.Emit(OpCodes.Call, baseMethod);
}
// Copy all fields
foreach (var field in type.Fields.Where(x => !x.IsStatic))
{
TypeDefinition fieldTypeDef;
var isStructField = StructFields.IsStructField(field, out fieldTypeDef);
// Prepare for stfld
seq.Emit(OpCodes.Ldarg, body.ThisParameter);
// Load from source
seq.Emit(OpCodes.Ldarg, sourceParam);
seq.Emit(OpCodes.Ldfld, field);
// If struct, create clone
if (isStructField)
{
var cloneMethod = new MethodReference(NameConstants.Struct.CloneMethodName, fieldTypeDef, fieldTypeDef) { HasThis = true };
seq.Emit(OpCodes.Call, cloneMethod);
}
// Save in this
seq.Emit(OpCodes.Stfld, field);
}
// Return this
seq.Emit(OpCodes.Ldarg, body.ThisParameter);
seq.Emit(OpCodes.Ret);
// Append ret sequence
seq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add method
type.Methods.Add(method);
method.SetReachable(reachableContext);
return method;
}
示例6: CreateCloneMethod
/// <summary>
/// Create a Clone method.
/// </summary>
private static void CreateCloneMethod(ReachableContext reachableContext, TypeDefinition type, MethodDefinition copyFromMethod)
{
var method = new MethodDefinition(NameConstants.Struct.CloneMethodName, MethodAttributes.Public, type);
method.DeclaringType = type;
var body = new MethodBody(method);
body.InitLocals = true;
method.Body = body;
// Prepare code
var seq = new ILSequence();
seq.Emit(OpCodes.Nop);
// Create new instance
var defaultCtor = CreateDefaultCtorRef(type);
seq.Emit(OpCodes.Newobj, defaultCtor);
// Call clone.CopyFrom
seq.Emit(OpCodes.Dup);
seq.Emit(OpCodes.Ldarg, body.ThisParameter);
seq.Emit(OpCodes.Call, copyFromMethod);
// Return clone
seq.Emit(OpCodes.Ret);
// Append ret sequence
seq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add method
type.Methods.Add(method);
method.SetReachable(reachableContext);
}
示例7: InlineNewObjCall
//.........这里部分代码省略.........
}
break;
}
// Convert parameter opcodes
switch (instr.OpCode.Code)
{
case Mono.Cecil.Cil.Code.Ldarg:
{
var index = ctor.Parameters.IndexOf((ParameterDefinition) instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Ldloc;
}
break;
case Mono.Cecil.Cil.Code.Ldarga:
{
var index = ctor.Parameters.IndexOf((ParameterDefinition) instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Ldloca;
}
break;
case Mono.Cecil.Cil.Code.Starg:
{
var index = ctor.Parameters.IndexOf((ParameterDefinition) instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Stloc;
}
break;
}
}
// Update branch targets
for (var i = 0; i < seq.Length; i++)
{
var instr = seq[i];
var oldi = source.Instructions[i];
if (instr.OpCode.OperandType == OperandType.InlineSwitch)
{
var olds = (Instruction[]) oldi.Operand;
var targets = new Instruction[olds.Length];
for (int j = 0; j < targets.Length; j++)
{
targets[j] = GetClone(seq, source.Instructions, olds[j]);
}
instr.Operand = targets;
}
else if (instr.OpCode.OperandType == OperandType.ShortInlineBrTarget ||
instr.OpCode.OperandType == OperandType.InlineBrTarget)
{
instr.Operand = GetClone(seq, source.Instructions, (Instruction) oldi.Operand);
}
}
// Clone exception handlers
if (source.HasExceptionHandlers)
{
CloneInstructions(seq, source.Instructions, body.ExceptionHandlers, source.ExceptionHandlers);
}
// Find call to "this" ctor
var callToCtors = seq.Where(x => IsCallToThisCtor(x, ctor)).ToList();
if (callToCtors.Count == 0)
throw new CompilerException(string.Format("No call to another this ctor found in {0}", ctor));
if (callToCtors.Count > 1)
throw new CompilerException(string.Format("Multiple calls to another this ctor found in {0}", ctor));
var callToCtor = callToCtors[0];
// Change "ld this" to nop
var args = callToCtor.GetCallArguments(seq, true);
args[0].ChangeToNop(); // Replace ldarg.0
// Replace call to this ctor with newobj
var callSeq = new ILSequence();
callSeq.Emit(OpCodes.Newobj, (MethodReference) callToCtor.Operand);
callSeq.Emit(OpCodes.Stloc, thisVariable); // Save new object
callToCtor.ChangeToNop();
callSeq.InsertToBefore(callToCtor, seq);
// Replace ret instructions
var end = seq.Emit(OpCodes.Ldloc, thisVariable);
var retInstructions = seq.Where(x => x.OpCode.Code == Mono.Cecil.Cil.Code.Ret).ToList();
foreach (var ins in retInstructions)
{
ins.OpCode = OpCodes.Br;
ins.Operand = end;
}
// Insert cloned instructions
prefixSeq.InsertTo(0, seq);
seq.InsertToAfter(instruction, body);
// Change replaced instruction to nop
instruction.ChangeToNop();
// Update offsets
body.ComputeOffsets();
}
示例8: InlineCall
//.........这里部分代码省略.........
break;
case Code.Ldarga:
{
var index = targetMethod.Parameters.IndexOf((ParameterDefinition)instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Ldloca;
}
break;
case Code.Starg:
{
var index = targetMethod.Parameters.IndexOf((ParameterDefinition)instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Stloc;
}
break;
}
}
// Update branch targets
for (var i = 0; i < seq.Length; i++)
{
var instr = seq[i];
var oldi = source.Instructions[i];
if (instr.OpCode.OperandType == OperandType.InlineSwitch)
{
var olds = (Instruction[])oldi.Operand;
var targets = new Instruction[olds.Length];
for (int j = 0; j < targets.Length; j++)
{
targets[j] = GetClone(seq, source.Instructions, olds[j]);
}
instr.Operand = targets;
}
else if (instr.OpCode.OperandType == OperandType.ShortInlineBrTarget ||
instr.OpCode.OperandType == OperandType.InlineBrTarget)
{
instr.Operand = GetClone(seq, source.Instructions, (Instruction)oldi.Operand);
}
}
// Clone exception handlers
if (source.HasExceptionHandlers)
{
body.ComputeOffsets();
CloneInstructions(seq, source.Instructions, body.ExceptionHandlers, source.ExceptionHandlers);
}
// Replace ret instructions
var end = seq.Emit(OpCodes.Nop);
var retInstructions = seq.Where(x => x.OpCode.Code == Code.Ret).ToList();
foreach (var ins in retInstructions)
{
ins.OpCode = OpCodes.Br;
ins.Operand = end;
}
// cast return type of a generic method. TODO: better might be to
// correctly resolve calls to generic instances as well (above)
if (targetMethod.ReturnType.IsGenericParameter)
{
var methodRef = (MethodReference)instruction.Operand;
TypeReference returnType = null;
var gp = (GenericParameter)methodRef.ReturnType;
if (gp.Type == GenericParameterType.Type)
{
var gi = methodRef.DeclaringType as IGenericInstance;
if (gi != null && gi.HasGenericArguments)
returnType = gi.GenericArguments[gp.Position];
}
else if (gp.Type == GenericParameterType.Method)
{
var gi = methodRef as IGenericInstance;
if (gi != null && gi.HasGenericArguments)
returnType = gi.GenericArguments[gp.Position];
}
if (returnType != null)
{
if (!returnType.IsPrimitive)
{
seq.Emit(OpCodes.Castclass, returnType);
}
// todo: handle primitive types. unbox them? are structs correctly handled? enums?
}
}
// Insert cloned instructions
prefixSeq.InsertTo(0, seq);
seq.InsertToAfter(instruction, body);
// Change replaced instruction to nop
instruction.ChangeToNop();
// Update offsets
body.ComputeOffsets();
}
示例9: Convert
/// <summary>
/// Convert all synchronized methods.
/// </summary>
private static void Convert(MethodBody body)
{
var typeSystem = body.Method.Module.TypeSystem;
var monitorType = typeSystem.LookupType("System.Threading", "Monitor");
var enterMethod = new MethodReference("Enter", typeSystem.Void, monitorType);
enterMethod.Parameters.Add(new ParameterDefinition(typeSystem.Object));
var exitMethod = new MethodReference("Exit", typeSystem.Void, monitorType);
exitMethod.Parameters.Add(new ParameterDefinition(typeSystem.Object));
var firstInstr = body.Instructions[0];
// Expand macro's
body.SimplifyMacros();
// Prepare new return
var retSeq = new ILSequence();
retSeq.Emit(OpCodes.Nop);
retSeq.Emit(OpCodes.Ret);
// Monitor.Enter(this)
var initSeq = new ILSequence();
initSeq.Emit(OpCodes.Ldarg_0); // ld this
initSeq.Emit(OpCodes.Call, enterMethod);
initSeq.InsertTo(0, body);
// Leave sequence
var leaveSeq = new ILSequence();
leaveSeq.Emit(OpCodes.Nop);
leaveSeq.Emit(OpCodes.Leave, retSeq.First);
leaveSeq.AppendTo(body);
// Finally: Monitor.Exit(this)
var finallySeq = new ILSequence();
finallySeq.Emit(OpCodes.Ldarg_0); // ld this
finallySeq.Emit(OpCodes.Call, exitMethod);
finallySeq.Emit(OpCodes.Endfinally);
finallySeq.AppendTo(body);
// Replace Ret instructions
foreach (var instr in body.Instructions.Where(x => x.OpCode.Code == Mono.Cecil.Cil.Code.Ret))
{
if (instr.Next == leaveSeq.First)
{
instr.ChangeToNop();
}
else
{
instr.OpCode = OpCodes.Br;
instr.Operand = leaveSeq.First;
}
}
// Append ret sequence
retSeq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add try/finally block
var handler = new ExceptionHandler(ExceptionHandlerType.Finally);
handler.TryStart = firstInstr;
handler.TryEnd = finallySeq.First; // leaveSeq.Last;
handler.HandlerStart = finallySeq.First;
handler.HandlerEnd = retSeq.First; // finallySeq.Last;
body.ExceptionHandlers.Insert(0, handler);
}
示例10: InlineCall
//.........这里部分代码省略.........
}
// Now clone instructions
var seq = new ILSequence();
foreach (var instr in source.Instructions)
{
var ni = new Instruction(instr.OpCode, instr.Operand);
seq.Append(ni);
ni.Offset = instr.Offset;
// Convert variable opcodes
switch (instr.OpCode.OperandType)
{
case OperandType.InlineVar:
case OperandType.ShortInlineVar:
{
var index = source.Variables.IndexOf((VariableDefinition)instr.Operand);
ni.Operand = variables[index];
}
break;
}
// Convert parameter opcodes
switch (instr.OpCode.Code)
{
case Code.Ldarg:
{
var index = targetMethod.Parameters.IndexOf((ParameterDefinition)instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Ldloc;
}
break;
case Code.Ldarga:
{
var index = targetMethod.Parameters.IndexOf((ParameterDefinition)instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Ldloca;
}
break;
case Code.Starg:
{
var index = targetMethod.Parameters.IndexOf((ParameterDefinition)instr.Operand);
ni.Operand = (index >= 0) ? paramVariables[index] : thisVariable;
ni.OpCode = OpCodes.Stloc;
}
break;
}
}
// Update branch targets
for (var i = 0; i < seq.Length; i++)
{
var instr = seq[i];
var oldi = source.Instructions[i];
if (instr.OpCode.OperandType == OperandType.InlineSwitch)
{
var olds = (Instruction[])oldi.Operand;
var targets = new Instruction[olds.Length];
for (int j = 0; j < targets.Length; j++)
{
targets[j] = GetClone(seq, source.Instructions, olds[j]);
}
instr.Operand = targets;
}
else if (instr.OpCode.OperandType == OperandType.ShortInlineBrTarget ||
instr.OpCode.OperandType == OperandType.InlineBrTarget)
{
instr.Operand = GetClone(seq, source.Instructions, (Instruction)oldi.Operand);
}
}
// Clone exception handlers
if (source.HasExceptionHandlers)
{
body.ComputeOffsets();
CloneInstructions(seq, source.Instructions, body.ExceptionHandlers, source.ExceptionHandlers);
}
// Replace ret instructions
var end = seq.Emit(OpCodes.Nop);
var retInstructions = seq.Where(x => x.OpCode.Code == Code.Ret).ToList();
foreach (var ins in retInstructions)
{
ins.OpCode = OpCodes.Br;
ins.Operand = end;
}
// Insert cloned instructions
prefixSeq.InsertTo(0, seq);
seq.InsertToAfter(instruction, body);
// Change replaced instruction to nop
instruction.ChangeToNop();
// Update offsets
body.ComputeOffsets();
}