static int GetDataSize(OperandType operandType) { switch (operandType) { case OperandType.InlineNone: return(0); case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineI: case OperandType.ShortInlineVar: return(1); case OperandType.InlineVar: return(2); case OperandType.InlineBrTarget: case OperandType.InlineField: case OperandType.InlineI: case OperandType.InlineMethod: case OperandType.InlineSig: case OperandType.InlineString: case OperandType.InlineSwitch: case OperandType.InlineTok: case OperandType.InlineType: case OperandType.ShortInlineR: return(4); case OperandType.InlineI8: case OperandType.InlineR: return(8); default: return(0); } }
internal IlInstruction[] ReadMethodNoLock(MethodBody methodBody, MethodBase methodBase) { _module = methodBase.Module; Type declaringType = methodBase.DeclaringType; _declaringTypeIsGeneric = declaringType.IsGenericType; _typeGenericArguments = _declaringTypeIsGeneric ? declaringType.GetGenericArguments() : null; _methodIsGeneric = methodBase.IsGenericMethod; _methodGenericArguments = _methodIsGeneric ? methodBase.GetGenericArguments() : null; List <IlInstruction> result = new List <IlInstruction>(); byte[] instructionBytes = methodBody.GetILAsByteArray(); int instructionIndex = 0; int startAddress; for (int position = 0; position < instructionBytes.Length;) { startAddress = position; ushort operationData = instructionBytes[position]; if (IsInstructionPrefix(operationData)) { operationData = (ushort)((operationData << 8) | instructionBytes[++position]); } position++; if (!_instructionLookup.TryGetValue(operationData, out ILOpCode code)) { throw new InvalidProgramException(string.Format("0x{0:X2} is not a valid op code.", operationData)); } OperandType operandType = GetOperandType(code); int dataSize = GetDataSize(operandType); byte[] data = new byte[dataSize]; Buffer.BlockCopy(instructionBytes, position, data, 0, dataSize); object objData = this.GetData(operandType, data); position += dataSize; if (operandType == OperandType.InlineSwitch) { dataSize = (int)objData; int[] labels = new int[dataSize]; for (int index = 0; index < labels.Length; index++) { labels[index] = BitConverter.ToInt32(instructionBytes, position); position += 4; } objData = labels; } result.Add(new IlInstruction(code, data, startAddress, objData, instructionIndex++)); } return(result.ToArray()); }
internal OpCode(string stringname, StackBehaviour pop, StackBehaviour push, System.Reflection.Emit.OperandType operand, System.Reflection.Emit.OpCodeType type, int size, byte s1, byte s2, System.Reflection.Emit.FlowControl ctrl, bool endsjmpblk, int stack) { this.m_stringname = stringname; this.m_pop = pop; this.m_push = push; this.m_operand = operand; this.m_type = type; this.m_size = size; this.m_s1 = s1; this.m_s2 = s2; this.m_ctrl = ctrl; this.m_endsUncondJmpBlk = endsjmpblk; this.m_stackChange = stack; }
internal OpCode(string stringname, StackBehaviour pop, StackBehaviour push, System.Reflection.Emit.OperandType operand, System.Reflection.Emit.OpCodeType type, int size, byte s1, byte s2, System.Reflection.Emit.FlowControl ctrl, bool endsjmpblk, int stack) { this.m_stringname = stringname; this.m_pop = pop; this.m_push = push; this.m_operand = operand; this.m_type = type; this.m_size = size; this.m_s1 = s1; this.m_s2 = s2; this.m_ctrl = ctrl; this.m_endsUncondJmpBlk = endsjmpblk; this.m_stackChange = stack; }
private object GetData(OperandType operandType, byte[] rawData) { object data = null; switch (operandType) { case OperandType.InlineField: if ((_declaringTypeIsGeneric) || (_methodIsGeneric)) { data = _module.ResolveField(BitConverter.ToInt32(rawData, 0), _typeGenericArguments, _methodGenericArguments); } else { data = _module.ResolveField(BitConverter.ToInt32(rawData, 0)); } break; case OperandType.InlineSwitch: data = BitConverter.ToInt32(rawData, 0); break; case OperandType.InlineBrTarget: case OperandType.InlineI: data = BitConverter.ToInt32(rawData, 0); break; case OperandType.InlineI8: data = BitConverter.ToInt64(rawData, 0); break; case OperandType.InlineMethod: if ((_declaringTypeIsGeneric) || (_methodIsGeneric)) { data = _module.ResolveMethod(BitConverter.ToInt32(rawData, 0), _typeGenericArguments, _methodGenericArguments); } else { data = _module.ResolveMethod(BitConverter.ToInt32(rawData, 0)); } break; case OperandType.InlineR: data = BitConverter.ToDouble(rawData, 0); break; case OperandType.InlineSig: data = _module.ResolveSignature(BitConverter.ToInt32(rawData, 0)); break; case OperandType.InlineString: data = _module.ResolveString(BitConverter.ToInt32(rawData, 0)); break; case OperandType.InlineTok: case OperandType.InlineType: if ((_declaringTypeIsGeneric) || (_methodIsGeneric)) { data = _module.ResolveType(BitConverter.ToInt32(rawData, 0), _typeGenericArguments, _methodGenericArguments); } else { data = _module.ResolveType(BitConverter.ToInt32(rawData, 0)); } break; case OperandType.InlineVar: data = BitConverter.ToInt16(rawData, 0); break; case OperandType.ShortInlineVar: case OperandType.ShortInlineI: case OperandType.ShortInlineBrTarget: data = rawData[0]; break; case OperandType.ShortInlineR: data = BitConverter.ToSingle(rawData, 0); break; } return(data); }