private void WriteOperandOffset(X86OffsetType type, int offset) { switch (type) { case X86OffsetType.None: break; case X86OffsetType.Short: _writer.WriteSByte((sbyte)offset); break; case X86OffsetType.Long: _writer.WriteInt32(offset); break; default: throw new NotSupportedException("Unrecognized or unsupported offset type."); } }
private void WriteOperand(CilInstruction instruction) { switch (instruction.OpCode.OperandType) { case CilOperandType.InlineNone: break; case CilOperandType.ShortInlineI: _writer.WriteSByte(OperandToSByte(instruction)); break; case CilOperandType.InlineI: _writer.WriteInt32(OperandToInt32(instruction)); break; case CilOperandType.InlineI8: _writer.WriteInt64(OperandToInt64(instruction)); break; case CilOperandType.ShortInlineR: _writer.WriteSingle(OperandToFloat32(instruction)); break; case CilOperandType.InlineR: _writer.WriteDouble(OperandToFloat64(instruction)); break; case CilOperandType.ShortInlineVar: _writer.WriteByte((byte)OperandToLocalIndex(instruction)); break; case CilOperandType.InlineVar: _writer.WriteUInt16(OperandToLocalIndex(instruction)); break; case CilOperandType.ShortInlineArgument: _writer.WriteByte((byte)OperandToArgumentIndex(instruction)); break; case CilOperandType.InlineArgument: _writer.WriteUInt16(OperandToArgumentIndex(instruction)); break; case CilOperandType.ShortInlineBrTarget: _writer.WriteSByte((sbyte)OperandToBranchDelta(instruction)); break; case CilOperandType.InlineBrTarget: _writer.WriteInt32(OperandToBranchDelta(instruction)); break; case CilOperandType.InlineSwitch: var labels = (IList <ICilLabel>)instruction.Operand; _writer.WriteInt32(labels.Count); int baseOffset = (int)_writer.Offset + labels.Count * sizeof(int); for (int i = 0; i < labels.Count; i++) { _writer.WriteInt32(labels[i].Offset - baseOffset); } break; case CilOperandType.InlineString: _writer.WriteUInt32(_operandBuilder.GetStringToken(instruction.Operand)); break; case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: _writer.WriteUInt32(_operandBuilder.GetMemberToken(instruction.Operand).ToUInt32()); break; default: throw new ArgumentOutOfRangeException(); } }
private void WriteValue(IBinaryStreamWriter writer, TypeSignature argumentType, ITypeCodedIndexProvider provider, object value) { if (argumentType.IsTypeOf("System", "Type")) { writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName((TypeSignature)value)); return; } switch (argumentType.ElementType) { case ElementType.Boolean: writer.WriteByte((byte)((bool)value ? 1 : 0)); break; case ElementType.Char: writer.WriteUInt16((char)value); break; case ElementType.I1: writer.WriteSByte((sbyte)value); break; case ElementType.U1: writer.WriteByte((byte)value); break; case ElementType.I2: writer.WriteInt16((short)value); break; case ElementType.U2: writer.WriteUInt16((ushort)value); break; case ElementType.I4: writer.WriteInt32((int)value); break; case ElementType.U4: writer.WriteUInt32((uint)value); break; case ElementType.I8: writer.WriteInt64((long)value); break; case ElementType.U8: writer.WriteUInt64((ulong)value); break; case ElementType.R4: writer.WriteSingle((float)value); break; case ElementType.R8: writer.WriteDouble((double)value); break; case ElementType.String: writer.WriteSerString(value as string); break; case ElementType.Object: var valueType = value.GetType(); var innerTypeSig = argumentType.Module.CorLibTypeFactory.FromName(valueType.Namespace, valueType.Name); TypeSignature.WriteFieldOrPropType(writer, innerTypeSig); WriteValue(writer, innerTypeSig, provider, value); break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = argumentType.Resolve(); if (enumTypeDef != null && enumTypeDef.IsEnum) { WriteValue(writer, enumTypeDef.GetEnumUnderlyingType(), provider, Value); } else { throw new NotImplementedException(); } break; default: throw new ArgumentOutOfRangeException(); } }
/// <inheritdoc /> public override void Write(MetadataBuffer buffer, IBinaryStreamWriter writer) { if (Value == null) { writer.WriteSerString(null); return; } switch (Type.GetTypeCode(Value.GetType())) { case TypeCode.Boolean: writer.WriteByte((byte)((bool)Value ? 1 : 0)); break; case TypeCode.Byte: writer.WriteByte((byte)Value); break; case TypeCode.Char: writer.WriteUInt16((char)Value); break; case TypeCode.Double: writer.WriteDouble((double)Value); break; case TypeCode.Int16: writer.WriteInt16((short)Value); break; case TypeCode.Int32: writer.WriteInt32((int)Value); break; case TypeCode.Int64: writer.WriteInt64((long)Value); break; case TypeCode.SByte: writer.WriteSByte((sbyte)Value); break; case TypeCode.Single: writer.WriteSingle((float)Value); break; case TypeCode.String: writer.WriteSerString((string)Value); break; case TypeCode.UInt16: writer.WriteUInt16((ushort)Value); break; case TypeCode.UInt32: writer.WriteUInt32((uint)Value); break; case TypeCode.UInt64: writer.WriteUInt64((ulong)Value); break; default: if (Value is TypeSignature typeSignature) { writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName(typeSignature)); } else { throw new NotSupportedException(); } break; } }
/// <summary> /// Writes the operand of the instruction to the output stream. /// </summary> /// <param name="instruction"></param> /// <exception cref="InvalidOperationException"></exception> private void WriteOperand(CilInstruction instruction) { switch (instruction.OpCode.OperandType) { case CilOperandType.InlineArgument: _writer.WriteUInt16((ushort)_builder.GetParameterIndex(instruction.Operand as ParameterSignature)); break; case CilOperandType.ShortInlineArgument: _writer.WriteByte((byte)_builder.GetParameterIndex(instruction.Operand as ParameterSignature)); break; case CilOperandType.InlineVar: _writer.WriteUInt16((ushort)_builder.GetVariableIndex(instruction.Operand as VariableSignature)); break; case CilOperandType.ShortInlineVar: _writer.WriteByte((byte)_builder.GetVariableIndex(instruction.Operand as VariableSignature)); break; case CilOperandType.ShortInlineI: _writer.WriteSByte((sbyte)instruction.Operand); break; case CilOperandType.InlineI: _writer.WriteInt32((int)instruction.Operand); break; case CilOperandType.InlineI8: _writer.WriteInt64((long)instruction.Operand); break; case CilOperandType.ShortInlineR: _writer.WriteSingle((float)instruction.Operand); break; case CilOperandType.InlineR: _writer.WriteDouble((double)instruction.Operand); break; case CilOperandType.InlineBrTarget: _writer.WriteInt32(((CilInstruction)instruction.Operand).Offset - (instruction.Offset + instruction.Size)); break; case CilOperandType.ShortInlineBrTarget: _writer.WriteSByte((sbyte)(((CilInstruction)instruction.Operand).Offset - (instruction.Offset + instruction.Size))); break; case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: var token = _builder.GetMetadataToken((IMetadataMember)instruction.Operand); if (token.Rid == 0) { throw new InvalidOperationException($"Member {instruction.Operand} has an invalid metadata token."); } _writer.WriteUInt32(token.ToUInt32()); break; case CilOperandType.InlineString: _writer.WriteUInt32(_builder.GetStringOffset((string)instruction.Operand)); break; case CilOperandType.InlineSwitch: var targets = (IList <CilInstruction>)instruction.Operand; _writer.WriteInt32(targets.Count); foreach (var target in targets) { _writer.WriteInt32(target.Offset - (instruction.Offset + instruction.Size)); } break; case CilOperandType.InlineNone: break; } }
private void WriteOperand(CilInstruction instruction) { switch (instruction.OpCode.OperandType) { case CilOperandType.InlineNone: break; case CilOperandType.ShortInlineI: _writer.WriteSByte((sbyte)instruction.Operand); break; case CilOperandType.InlineI: _writer.WriteInt32((int)instruction.Operand); break; case CilOperandType.InlineI8: _writer.WriteInt64((long)instruction.Operand); break; case CilOperandType.ShortInlineR: _writer.WriteSingle((float)instruction.Operand); break; case CilOperandType.InlineR: _writer.WriteDouble((double)instruction.Operand); break; case CilOperandType.ShortInlineVar: _writer.WriteSByte((sbyte)_operandBuilder.GetVariableIndex(instruction.Operand)); break; case CilOperandType.InlineVar: _writer.WriteUInt16((ushort)_operandBuilder.GetVariableIndex(instruction.Operand)); break; case CilOperandType.ShortInlineArgument: _writer.WriteSByte((sbyte)_operandBuilder.GetArgumentIndex(instruction.Operand)); break; case CilOperandType.InlineArgument: _writer.WriteUInt16((ushort)_operandBuilder.GetArgumentIndex(instruction.Operand)); break; case CilOperandType.ShortInlineBrTarget: sbyte shortOffset = (sbyte)(((ICilLabel)instruction.Operand).Offset - (int)(_writer.Offset + sizeof(sbyte))); _writer.WriteSByte(shortOffset); break; case CilOperandType.InlineBrTarget: int longOffset = ((ICilLabel)instruction.Operand).Offset - (int)(_writer.Offset + sizeof(int)); _writer.WriteInt32(longOffset); break; case CilOperandType.InlineSwitch: var labels = (IList <ICilLabel>)instruction.Operand; _writer.WriteInt32(labels.Count); int baseOffset = (int)_writer.Offset + labels.Count * sizeof(int); for (int i = 0; i < labels.Count; i++) { _writer.WriteInt32(labels[i].Offset - baseOffset); } break; case CilOperandType.InlineString: _writer.WriteUInt32(_operandBuilder.GetStringToken(instruction.Operand)); break; case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: _writer.WriteUInt32(_operandBuilder.GetMemberToken(instruction.Operand).ToUInt32()); break; default: throw new ArgumentOutOfRangeException(); } }