/// <summary> /// Emits the displacement operand. /// </summary> /// <param name="displacement">The displacement operand.</param> public void WriteDisplacement(Operand displacement) { byte[] disp; MemberOperand member = displacement as MemberOperand; LabelOperand label = displacement as LabelOperand; SymbolOperand symbol = displacement as SymbolOperand; if (label != null) { int pos = (int)(_codeStream.Position - _codeStreamBasePosition); disp = LittleEndianBitConverter.GetBytes((uint)_linker.Link(LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method.ToString(), pos, 0, label.Name, IntPtr.Zero)); } else if (member != null) { int pos = (int)(_codeStream.Position - _codeStreamBasePosition); disp = LittleEndianBitConverter.GetBytes((uint)_linker.Link(LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method.ToString(), pos, 0, member.Member.ToString(), member.Offset)); } else if (symbol != null) { int pos = (int)(_codeStream.Position - _codeStreamBasePosition); disp = LittleEndianBitConverter.GetBytes((uint)_linker.Link(LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method.ToString(), pos, 0, symbol.Name, IntPtr.Zero)); } else { disp = LittleEndianBitConverter.GetBytes((displacement as MemoryOperand).Offset.ToInt32()); } _codeStream.Write(disp, 0, disp.Length); }
/// <summary> /// Emits the displacement operand. /// </summary> /// <param name="displacement">The displacement operand.</param> private void EmitDisplacement(MemoryOperand displacement) { byte[] disp; MemberOperand member = displacement as MemberOperand; LabelOperand label = displacement as LabelOperand; if (null != label) { int pos = (int)(_codeStream.Position - _codeStreamBasePosition); disp = LittleEndianBitConverter.GetBytes((uint)_linker.Link(LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method, pos, 0, label.Name, IntPtr.Zero)); } else if (null != member) { int pos = (int)(_codeStream.Position - _codeStreamBasePosition); disp = LittleEndianBitConverter.GetBytes((uint)_linker.Link(LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method, pos, 0, member.Member, member.Offset)); } else { disp = LittleEndianBitConverter.GetBytes(displacement.Offset.ToInt32()); } _codeStream.Write(disp, 0, disp.Length); }
/// <summary> /// Visitation function for BinaryLogic instruction. /// </summary> /// <param name="context">The context.</param> void CIL.ICILVisitor.BinaryLogic(Context context) { if (context.Operand1.Type is ValueTypeSigType) { var type = methodCompiler.Method.Module.GetType((context.Operand1.Type as ValueTypeSigType).Token); var operand = new MemberOperand(type.Fields[0], type.Fields[0].SignatureType, new IntPtr(0)); context.SetOperand(0, operand); } if (context.Operand2.Type is ValueTypeSigType) { var type = methodCompiler.Method.Module.GetType((context.Operand2.Type as ValueTypeSigType).Token); var operand = new MemberOperand(type.Fields[0], type.Fields[0].SignatureType, new IntPtr(0)); context.SetOperand(1, operand); } switch ((context.Instruction as CIL.BaseCILInstruction).OpCode) { case CIL.OpCode.And: context.SetInstruction(IRInstruction.LogicalAnd, context.Result, context.Operand1, context.Operand2); break; case CIL.OpCode.Or: context.SetInstruction(IRInstruction.LogicalOr, context.Result, context.Operand1, context.Operand2); break; case CIL.OpCode.Xor: context.SetInstruction(IRInstruction.LogicalXor, context.Result, context.Operand1, context.Operand2); break; case CIL.OpCode.Div_un: context.SetInstruction(IRInstruction.DivU, context.Result, context.Operand1, context.Operand2); break; case CIL.OpCode.Rem_un: context.SetInstruction(IRInstruction.RemU, context.Result, context.Operand1, context.Operand2); break; default: throw new NotSupportedException(); } }
/// <summary> /// Visitation function for Ldsfld instruction. /// </summary> /// <param name="context">The context.</param> public void Ldsfld(Context context) { SigType sigType = context.RuntimeField.SignatureType; Operand source = new MemberOperand(context.RuntimeField); Operand destination = context.Result; IInstruction loadInstruction = IRInstruction.Move; if (MustSignExtendOnLoad(sigType.Type)) { loadInstruction = IRInstruction.SignExtendedMove; } else if (MustZeroExtendOnLoad(sigType.Type)) { loadInstruction = IRInstruction.ZeroExtendedMove; } context.SetInstruction(loadInstruction, destination, source); }