private object GetVariable(Instruction instruction, int index) { if (TargetsLocalVariable(instruction.OpCode)) { return this.GetLocalVariable(index); } return this.GetParameter(index); }
private void ReadOperand(Instruction instruction) { switch (instruction.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int length = this.il.ReadInt32(); int base_offset = this.il.position + (4*length); int[] branches = new int[length]; for (int i = 0; i < length; i++) { branches[i] = this.il.ReadInt32() + base_offset; } instruction.Operand = branches; break; case OperandType.ShortInlineBrTarget: instruction.Operand = (((sbyte) this.il.ReadByte()) + this.il.position); break; case OperandType.InlineBrTarget: instruction.Operand = this.il.ReadInt32() + this.il.position; break; case OperandType.ShortInlineI: if (instruction.OpCode == OpCodes.Ldc_I4_S) { instruction.Operand = (sbyte) this.il.ReadByte(); } else { instruction.Operand = this.il.ReadByte(); } break; case OperandType.InlineI: instruction.Operand = this.il.ReadInt32(); break; case OperandType.ShortInlineR: instruction.Operand = this.il.ReadSingle(); break; case OperandType.InlineR: instruction.Operand = this.il.ReadDouble(); break; case OperandType.InlineI8: instruction.Operand = this.il.ReadInt64(); break; case OperandType.InlineSig: instruction.Operand = this.module.ResolveSignature(this.il.ReadInt32()); break; case OperandType.InlineString: instruction.Operand = this.module.ResolveString(this.il.ReadInt32()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: this.il.ReadInt32(); //instruction.Operand = module.ResolveMember (il.ReadInt32 (), type_arguments, method_arguments); break; case OperandType.ShortInlineVar: instruction.Operand = this.GetVariable(instruction, this.il.ReadByte()); break; case OperandType.InlineVar: instruction.Operand = this.GetVariable(instruction, this.il.ReadInt16()); break; default: throw new NotSupportedException(); } }
private void ResolveBranches() { foreach (Instruction instruction in this.instructions) { switch (instruction.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: instruction.Operand = GetInstruction(this.instructions, (int) instruction.Operand); break; case OperandType.InlineSwitch: int[] offsets = (int[]) instruction.Operand; Instruction[] branches = new Instruction[offsets.Length]; for (int j = 0; j < offsets.Length; j++) { branches[j] = GetInstruction(this.instructions, offsets[j]); } instruction.Operand = branches; break; } } }
private void ReadInstructions() { Instruction previous = null; while (this.il.position < this.il.buffer.Length) { Instruction instruction = new Instruction(this.il.position, this.ReadOpCode()); this.ReadOperand(instruction); if (previous != null) { instruction.Previous = previous; previous.Next = instruction; } this.instructions.Add(instruction); previous = instruction; } this.ResolveBranches(); }