public override void VisitMethodBody(MethodBody body) { m_codeWriter.Empty(); }
public override void VisitInstructionCollection(InstructionCollection instructions) { MethodBody body = instructions.Container; long start = m_codeWriter.BaseStream.Position; ComputeMaxStack(instructions); foreach (Instruction instr in instructions) { instr.Offset = (int)(m_codeWriter.BaseStream.Position - start); if (instr.OpCode.Size == 1) { m_codeWriter.Write(instr.OpCode.Op2); } else { m_codeWriter.Write(instr.OpCode.Op1); m_codeWriter.Write(instr.OpCode.Op2); } if (instr.OpCode.OperandType != OperandType.InlineNone && instr.Operand == null) { throw new ReflectionException("OpCode {0} have null operand", instr.OpCode.Name); } switch (instr.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: Instruction [] targets = (Instruction [])instr.Operand; for (int i = 0; i < targets.Length + 1; i++) { m_codeWriter.Write((uint)0); } break; case OperandType.ShortInlineBrTarget: m_codeWriter.Write((byte)0); break; case OperandType.InlineBrTarget: m_codeWriter.Write(0); break; case OperandType.ShortInlineI: if (instr.OpCode == OpCodes.Ldc_I4_S) { m_codeWriter.Write((sbyte)instr.Operand); } else { m_codeWriter.Write((byte)instr.Operand); } break; case OperandType.ShortInlineVar: m_codeWriter.Write((byte)body.Variables.IndexOf( (VariableDefinition)instr.Operand)); break; case OperandType.ShortInlineParam: m_codeWriter.Write((byte)GetParameterIndex(body, (ParameterDefinition)instr.Operand)); break; case OperandType.InlineSig: WriteToken(GetCallSiteToken((CallSite)instr.Operand)); break; case OperandType.InlineI: m_codeWriter.Write((int)instr.Operand); break; case OperandType.InlineVar: m_codeWriter.Write((short)body.Variables.IndexOf( (VariableDefinition)instr.Operand)); break; case OperandType.InlineParam: m_codeWriter.Write((short)GetParameterIndex( body, (ParameterDefinition)instr.Operand)); break; case OperandType.InlineI8: m_codeWriter.Write((long)instr.Operand); break; case OperandType.ShortInlineR: m_codeWriter.Write((float)instr.Operand); break; case OperandType.InlineR: m_codeWriter.Write((double)instr.Operand); break; case OperandType.InlineString: WriteToken(new MetadataToken(TokenType.String, m_reflectWriter.MetadataWriter.AddUserString(instr.Operand as string))); break; case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineType: case OperandType.InlineTok: if (instr.Operand is TypeReference) { WriteToken(GetTypeToken((TypeReference)instr.Operand)); } else if (instr.Operand is GenericInstanceMethod) { WriteToken(m_reflectWriter.GetMethodSpecToken(instr.Operand as GenericInstanceMethod)); } else if (instr.Operand is MemberReference) { WriteToken(m_reflectWriter.GetMemberRefToken((MemberReference)instr.Operand)); } else if (instr.Operand is IMetadataTokenProvider) { WriteToken(((IMetadataTokenProvider)instr.Operand).MetadataToken); } else { throw new ReflectionException( string.Format("Wrong operand for {0} OpCode: {1}", instr.OpCode.OperandType, instr.Operand.GetType().FullName)); } break; } } // patch branches long pos = m_codeWriter.BaseStream.Position; foreach (Instruction instr in instructions) { switch (instr.OpCode.OperandType) { case OperandType.InlineSwitch: m_codeWriter.BaseStream.Position = instr.Offset + instr.OpCode.Size; Instruction [] targets = (Instruction [])instr.Operand; m_codeWriter.Write((uint)targets.Length); foreach (Instruction tgt in targets) { m_codeWriter.Write((tgt.Offset - (instr.Offset + instr.OpCode.Size + (4 * (targets.Length + 1))))); } break; case OperandType.ShortInlineBrTarget: m_codeWriter.BaseStream.Position = instr.Offset + instr.OpCode.Size; m_codeWriter.Write((byte)(((Instruction)instr.Operand).Offset - (instr.Offset + instr.OpCode.Size + 1))); break; case OperandType.InlineBrTarget: m_codeWriter.BaseStream.Position = instr.Offset + instr.OpCode.Size; m_codeWriter.Write(((Instruction)instr.Operand).Offset - (instr.Offset + instr.OpCode.Size + 4)); break; } } m_codeWriter.BaseStream.Position = pos; }