public void Write(WriterContext ctxt, BlobWriter writer, uint beginOffset, Func <OpCode, object, Row> findRow) { var offset = (int)(writer.Offset - beginOffset); if (offset != Offset) { throw new PEException("invalid instruction offset"); } var highByte = (ushort)OpCode >> 8; if (highByte > 0) { writer.WriteByte((byte)highByte); } writer.WriteByte((byte)OpCode); switch (OpCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: { var target = (int)Value; // NOTE: Delta is relatative to start of next instruction var delta = (int)beginOffset + target - ((int)writer.Offset + 4); writer.WriteInt32(delta); } break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: { var target = (int)Value; // NOTE: Delta is w.r.t. begining of next instruction var delta = (int)beginOffset + target - ((int)writer.Offset + 1); if (delta > 0xff) { throw new PEException("cannot use small form for this instruction"); } writer.WriteSByte((sbyte)delta); } break; case OpCode.Ldc_i4_s: writer.WriteSByte((sbyte)(int)Value); break; case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: case OpCode.Unaligned: writer.WriteByte((byte)(int)Value); break; case OpCode.Ldc_i4: writer.WriteInt32((int)Value); break; case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: writer.WriteUInt32((uint)(int)Value); break; case OpCode.Ldc_i8: writer.WriteInt64((long)Value); break; case OpCode.Ldc_r4: writer.WriteSingle((float)Value); break; case OpCode.Ldc_r8: writer.WriteDouble((double)Value); break; case OpCode.Ldstr: WriteUserString(ctxt, writer, (string)Value); break; case OpCode.Switch: { var targets = (Seq <int>)Value; writer.WriteUInt32((uint)targets.Count); // NOTE: Deltas are w.r.t. start of next instruction for (var i = 0; i < targets.Count; i++) { var delta = (int)beginOffset + targets[i] - ((int)writer.Offset + (targets.Count * 4)); writer.WriteInt32(delta); } } break; case OpCode.Calli: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: WriteToken(ctxt, writer, findRow(OpCode, Value)); break; default: throw new PEException("unrecognised opcode"); } }
public void Write(WriterContext ctxt, BlobWriter writer, uint beginOffset, Func<OpCode, object, Row> findRow) { var offset = (int)(writer.Offset - beginOffset); if (offset != Offset) throw new PEException("invalid instruction offset"); var highByte = (ushort)OpCode >> 8; if (highByte > 0) writer.WriteByte((byte)highByte); writer.WriteByte((byte)OpCode); switch (OpCode) { case OpCode.Nop: case OpCode.Break: case OpCode.Ldarg_0: case OpCode.Ldarg_1: case OpCode.Ldarg_2: case OpCode.Ldarg_3: case OpCode.Ldloc_0: case OpCode.Ldloc_1: case OpCode.Ldloc_2: case OpCode.Ldloc_3: case OpCode.Stloc_0: case OpCode.Stloc_1: case OpCode.Stloc_2: case OpCode.Stloc_3: case OpCode.Ldnull: case OpCode.Ldc_i4_m1: case OpCode.Ldc_i4_0: case OpCode.Ldc_i4_1: case OpCode.Ldc_i4_2: case OpCode.Ldc_i4_3: case OpCode.Ldc_i4_4: case OpCode.Ldc_i4_5: case OpCode.Ldc_i4_6: case OpCode.Ldc_i4_7: case OpCode.Ldc_i4_8: case OpCode.Dup: case OpCode.Pop: case OpCode.Ret: case OpCode.Ldind_i1: case OpCode.Ldind_u1: case OpCode.Ldind_i2: case OpCode.Ldind_u2: case OpCode.Ldind_i4: case OpCode.Ldind_u4: case OpCode.Ldind_i8: case OpCode.Ldind_i: case OpCode.Ldind_r4: case OpCode.Ldind_r8: case OpCode.Ldind_ref: case OpCode.Stind_ref: case OpCode.Stind_i1: case OpCode.Stind_i2: case OpCode.Stind_i4: case OpCode.Stind_i8: case OpCode.Stind_r4: case OpCode.Stind_r8: case OpCode.Add: case OpCode.Sub: case OpCode.Mul: case OpCode.Div: case OpCode.Div_un: case OpCode.Rem: case OpCode.Rem_un: case OpCode.And: case OpCode.Or: case OpCode.Xor: case OpCode.Shl: case OpCode.Shr: case OpCode.Shr_un: case OpCode.Neg: case OpCode.Not: case OpCode.Conv_i1: case OpCode.Conv_i2: case OpCode.Conv_i4: case OpCode.Conv_i8: case OpCode.Conv_r4: case OpCode.Conv_r8: case OpCode.Conv_u4: case OpCode.Conv_u8: case OpCode.Conv_r_un: case OpCode.Throw: case OpCode.Conv_ovf_i1_un: case OpCode.Conv_ovf_i2_un: case OpCode.Conv_ovf_i4_un: case OpCode.Conv_ovf_i8_un: case OpCode.Conv_ovf_u1_un: case OpCode.Conv_ovf_u2_un: case OpCode.Conv_ovf_u4_un: case OpCode.Conv_ovf_u8_un: case OpCode.Conv_ovf_i_un: case OpCode.Conv_ovf_u_un: case OpCode.Ldlen: case OpCode.Ldelem_i1: case OpCode.Ldelem_u1: case OpCode.Ldelem_i2: case OpCode.Ldelem_u2: case OpCode.Ldelem_i4: case OpCode.Ldelem_u4: case OpCode.Ldelem_i8: case OpCode.Ldelem_i: case OpCode.Ldelem_r4: case OpCode.Ldelem_r8: case OpCode.Ldelem_ref: case OpCode.Stelem_i: case OpCode.Stelem_i1: case OpCode.Stelem_i2: case OpCode.Stelem_i4: case OpCode.Stelem_i8: case OpCode.Stelem_r4: case OpCode.Stelem_r8: case OpCode.Stelem_ref: case OpCode.Conv_ovf_i1: case OpCode.Conv_ovf_u1: case OpCode.Conv_ovf_i2: case OpCode.Conv_ovf_u2: case OpCode.Conv_ovf_i4: case OpCode.Conv_ovf_u4: case OpCode.Conv_ovf_i8: case OpCode.Conv_ovf_u8: case OpCode.Ckfinite: case OpCode.Conv_u2: case OpCode.Conv_u1: case OpCode.Conv_i: case OpCode.Conv_ovf_i: case OpCode.Conv_ovf_u: case OpCode.Add_ovf: case OpCode.Add_ovf_un: case OpCode.Mul_ovf: case OpCode.Mul_ovf_un: case OpCode.Sub_ovf: case OpCode.Sub_ovf_un: case OpCode.Endfinally: case OpCode.Stind_i: case OpCode.Conv_u: case OpCode.Prefix7: case OpCode.Prefix6: case OpCode.Prefix5: case OpCode.Prefix4: case OpCode.Prefix3: case OpCode.Prefix2: case OpCode.Prefix1: case OpCode.Prefixref: case OpCode.Arglist: case OpCode.Ceq: case OpCode.Cgt: case OpCode.Cgt_un: case OpCode.Clt: case OpCode.Clt_un: case OpCode.Localloc: case OpCode.Endfilter: case OpCode.Volatile: case OpCode.Tailcall: case OpCode.Cpblk: case OpCode.Initblk: case OpCode.Rethrow: case OpCode.Refanytype: case OpCode.Readonly: break; case OpCode.Br: case OpCode.Brfalse: case OpCode.Brtrue: case OpCode.Beq: case OpCode.Bge: case OpCode.Bgt: case OpCode.Ble: case OpCode.Blt: case OpCode.Bne_un: case OpCode.Bge_un: case OpCode.Bgt_un: case OpCode.Ble_un: case OpCode.Blt_un: case OpCode.Leave: { var target = (int)Value; // NOTE: Delta is relatative to start of next instruction var delta = (int)beginOffset + target - ((int)writer.Offset + 4); writer.WriteInt32(delta); } break; case OpCode.Br_s: case OpCode.Brfalse_s: case OpCode.Brtrue_s: case OpCode.Beq_s: case OpCode.Bge_s: case OpCode.Bgt_s: case OpCode.Ble_s: case OpCode.Blt_s: case OpCode.Bne_un_s: case OpCode.Bge_un_s: case OpCode.Bgt_un_s: case OpCode.Ble_un_s: case OpCode.Blt_un_s: case OpCode.Leave_s: { var target = (int)Value; // NOTE: Delta is w.r.t. begining of next instruction var delta = (int)beginOffset + target - ((int)writer.Offset + 1); if (delta > 0xff) throw new PEException("cannot use small form for this instruction"); writer.WriteSByte((sbyte)delta); } break; case OpCode.Ldc_i4_s: writer.WriteSByte((sbyte)(int)Value); break; case OpCode.Ldarg_s: case OpCode.Ldarga_s: case OpCode.Starg_s: case OpCode.Ldloc_s: case OpCode.Ldloca_s: case OpCode.Stloc_s: case OpCode.Unaligned: writer.WriteByte((byte)(int)Value); break; case OpCode.Ldc_i4: writer.WriteInt32((int)Value); break; case OpCode.Ldarg: case OpCode.Ldarga: case OpCode.Starg: case OpCode.Ldloc: case OpCode.Ldloca: case OpCode.Stloc: writer.WriteUInt32((uint)(int)Value); break; case OpCode.Ldc_i8: writer.WriteInt64((long)Value); break; case OpCode.Ldc_r4: writer.WriteSingle((float)Value); break; case OpCode.Ldc_r8: writer.WriteDouble((double)Value); break; case OpCode.Ldstr: WriteUserString(ctxt, writer, (string)Value); break; case OpCode.Switch: { var targets = (Seq<int>)Value; writer.WriteUInt32((uint)targets.Count); // NOTE: Deltas are w.r.t. start of next instruction for (var i = 0; i < targets.Count; i++) { var delta = (int)beginOffset + targets[i] - ((int)writer.Offset + (targets.Count * 4)); writer.WriteInt32(delta); } } break; case OpCode.Calli: case OpCode.Jmp: case OpCode.Call: case OpCode.Callvirt: case OpCode.Newobj: case OpCode.Ldftn: case OpCode.Ldvirtftn: case OpCode.Ldfld: case OpCode.Ldflda: case OpCode.Stfld: case OpCode.Ldsfld: case OpCode.Ldsflda: case OpCode.Stsfld: case OpCode.Ldtoken: case OpCode.Cpobj: case OpCode.Ldobj: case OpCode.Castclass: case OpCode.Isinst: case OpCode.Unbox: case OpCode.Stobj: case OpCode.Box: case OpCode.Newarr: case OpCode.Ldelema: case OpCode.Ldelem: case OpCode.Stelem: case OpCode.Unbox_any: case OpCode.Refanyval: case OpCode.Mkrefany: case OpCode.Initobj: case OpCode.Constrained: case OpCode.Sizeof: WriteToken(ctxt, writer, findRow(OpCode, Value)); break; default: throw new PEException("unrecognised opcode"); } }
public override void WriteValue(BlobWriter writer, object value) { switch (Type) { case PrimitiveType.Boolean: { var b = (bool)value; writer.WriteByte(b ? (byte)1 : (byte)0); } break; case PrimitiveType.Char: { var c = (char)value; writer.WriteUInt16(c); } break; case PrimitiveType.Int8: { var i = (sbyte)value; writer.WriteSByte(i); } break; case PrimitiveType.Int16: { var i = (short)value; writer.WriteInt16(i); } break; case PrimitiveType.Int32: { var i = (int)value; writer.WriteInt32(i); } break; case PrimitiveType.Int64: { var i = (long)value; writer.WriteInt64(i); } break; case PrimitiveType.UInt8: { var i = (byte)value; writer.WriteByte(i); } break; case PrimitiveType.UInt16: { var i = (ushort)value; writer.WriteUInt16(i); } break; case PrimitiveType.UInt32: { var i = (uint)value; writer.WriteUInt32(i); } break; case PrimitiveType.UInt64: { var i = (ulong)value; writer.WriteUInt64(i); } break; case PrimitiveType.IntNative: case PrimitiveType.UIntNative: throw new InvalidOperationException("cannot write native integers"); case PrimitiveType.Single: { var f = (float)value; writer.WriteSingle(f); } break; case PrimitiveType.Double: { var d = (double)value; writer.WriteDouble(d); } break; case PrimitiveType.String: { var s = (string)value; writer.WriteUTF8SizedString(s); } break; case PrimitiveType.Type: { var t = (TypeCustomAttributePropertyValue)value; writer.WriteUTF8SizedString(t.Name); } break; case PrimitiveType.Object: case PrimitiveType.TypedRef: case PrimitiveType.Void: throw new PEException("invalid type tag in custom attribute"); default: throw new ArgumentOutOfRangeException(); } }