/// <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);
        }
Esempio n. 2
0
        /// <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);
        }