private void ReadOperand(Instruction instruction) { switch (instruction.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int length = _il.ReadInt32(); int base_offset = _il.Position + (4 * length); int[] branches = new int[length]; for (int i = 0; i < length; i++) branches[i] = _il.ReadInt32() + base_offset; instruction.Operand = branches; break; case OperandType.ShortInlineBrTarget: instruction.Operand = (((sbyte)_il.ReadByte()) + _il.Position); break; case OperandType.InlineBrTarget: instruction.Operand = _il.ReadInt32() + _il.Position; break; case OperandType.ShortInlineI: if (instruction.OpCode == OpCodes.Ldc_I4_S) instruction.Operand = (sbyte)_il.ReadByte(); else instruction.Operand = _il.ReadByte(); break; case OperandType.InlineI: instruction.Operand = _il.ReadInt32(); break; case OperandType.ShortInlineR: instruction.Operand = _il.ReadSingle(); break; case OperandType.InlineR: instruction.Operand = _il.ReadDouble(); break; case OperandType.InlineI8: instruction.Operand = _il.ReadInt64(); break; case OperandType.InlineSig: instruction.Operand = _module.ResolveSignature(_il.ReadInt32()); break; case OperandType.InlineString: instruction.Operand = _module.ResolveString(_il.ReadInt32()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: instruction.Operand = _module.ResolveMember(_il.ReadInt32(), _typeArguments, _methodArguments); break; case OperandType.ShortInlineVar: instruction.Operand = GetVariable(instruction, _il.ReadByte()); break; case OperandType.InlineVar: instruction.Operand = GetVariable(instruction, _il.ReadInt16()); break; default: throw new NotSupportedException(); } }
private void ParseBody() { while (_il.Position < _il.Length) { var pos = _il.Position; byte op = _il.ReadByte(); var opCode = op != 0xfe ? OneByteCodes[op] : TwoByteCodes[_il.ReadByte()]; var instruction = new Instruction(pos, opCode); ReadOperand(instruction); _instructions.Add(instruction); } ResolveBranches(); }
private void ResolveBranches() { foreach (var instruction in _instructions) { switch (instruction.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: instruction.Operand = GetInstruction(_instructions, (int)instruction.Operand); break; case OperandType.InlineSwitch: var offsets = (int[])instruction.Operand; var branches = new Instruction[offsets.Length]; for (int j = 0; j < offsets.Length; j++) branches[j] = GetInstruction(_instructions, offsets[j]); instruction.Operand = branches; break; } } }
private object GetVariable(Instruction instruction, int index) { return TargetsLocalVariable(instruction.OpCode) ? (object)_locals[index] : (object)GetParameter(index); }
private void AppendLabel(StringBuilder builder, Instruction instruction) { builder.Append("IL_"); builder.Append(instruction.Offset.ToString("x4")); }