コード例 #1
0
        /// <summary>
        /// Emits arguments to a call, and returns an array of write-backs that
        /// should happen after the call. For emitting dynamic expressions, we
        /// need to skip the first parameter of the method (the call site).
        /// </summary>
        private List <WriteBack> EmitArguments(MethodBase method, IArgumentProvider args, int skipParameters)
        {
            ParameterInfo[] pis = method.GetParametersCached();
            Debug.Assert(args.ArgumentCount + skipParameters == pis.Length);

            List <WriteBack> writeBacks = null;

            for (int i = skipParameters, n = pis.Length; i < n; i++)
            {
                ParameterInfo parameter = pis[i];
                Expression    argument  = args.GetArgument(i - skipParameters);
                Type          type      = parameter.ParameterType;

                if (type.IsByRef)
                {
                    type = type.GetElementType();

                    WriteBack wb = EmitAddressWriteBack(argument, type);
                    if (wb != null)
                    {
                        if (writeBacks == null)
                        {
                            writeBacks = new List <WriteBack>();
                        }

                        writeBacks.Add(wb);
                    }
                }
                else
                {
                    EmitExpression(argument);
                }
            }
            return(writeBacks);
        }
コード例 #2
0
        // Emits the address of the expression, returning the write back if necessary
        //
        // For properties, we want to write back into the property if it's
        // passed byref.
        private WriteBack EmitAddressWriteBack(Expression node, Type type)
        {
            CompilationFlags startEmitted = EmitExpressionStart(node);

            WriteBack result = null;

            if (TypeUtils.AreEquivalent(type, node.Type))
            {
                switch (node.NodeType)
                {
                case ExpressionType.MemberAccess:
                    result = AddressOfWriteBack((MemberExpression)node);
                    break;

                case ExpressionType.Index:
                    result = AddressOfWriteBack((IndexExpression)node);
                    break;
                }
            }
            if (result == null)
            {
                EmitAddress(node, type, CompilationFlags.EmitAsNoTail | CompilationFlags.EmitNoExpressionStart);
            }

            EmitExpressionEnd(startEmitted);

            return(result);
        }
コード例 #3
0
        // Emits the address of the expression, returning the write back if necessary
        //
        // For properties, we want to write back into the property if it's
        // passed byref.
        private WriteBack EmitAddressWriteBack(Expression node, Type type)
        {
            ExpressionStart startEmitted = EmitExpressionStart(node);

            WriteBack result = null;

            if (type == node.Type)
            {
                switch (node.NodeType)
                {
                case ExpressionType.MemberAccess:
                    result = AddressOfWriteBack((MemberExpression)node);
                    break;

                case ExpressionType.Index:
                    result = AddressOfWriteBack((IndexExpression)node);
                    break;
                }
            }
            if (result == null)
            {
                EmitAddress(node, type, false);
            }

            EmitExpressionEnd(startEmitted);

            return(result);
        }
コード例 #4
0
 internal override void Emit(ILGenerator ilg, bool preserve)
 {
     Args.Emit(ilg);
     Symbol.EmitGet(ilg);
     if (WriteBack != null)
     {
         WriteBack.Emit(ilg, false);
     }
     if (!preserve)
     {
         ilg.Emit(OpCodes.Pop);
     }
 }
コード例 #5
0
 internal override void Emit(ILGenerator ilg, bool preserve)
 {
     if (Self != null)
     {
         Self.Emit(ilg);
     }
     Args.Emit(ilg);
     Symbol.EmitGet(ilg);
     if (WriteBack != null)
     {
         WriteBack.Emit(ilg, false);
     }
     if (!preserve && Datatype.NativeType != NativeType.Void)
     {
         ilg.Emit(OpCodes.Pop);
     }
 }
コード例 #6
0
        public void EmitSingleDataTransfer(ConditionCode conditionCode, Indexing indexing, OffsetDirection offsetDirection, TransferSize transferSize, WriteBack writeBack, TransferType transferType, int firstRegister, int destinationRegister, ShiftType secondShiftType, int secondRegister)
        {
            Debug.Assert(destinationRegister <= 0xF);
            Debug.Assert(firstRegister <= 0xF);
            Debug.Assert(secondRegister <= 0xF);

            uint value = 0;

            value |= (uint)(GetConditionCode(conditionCode) << 28);
            value |= (uint)(1 << 26);
            value |= (uint)(1 << 25);
            value |= (uint)((indexing == Indexing.Post ? 0 : 1) << 24);
            value |= (uint)((transferSize == TransferSize.Word ? 0 : 1) << 23);
            value |= (uint)((offsetDirection == OffsetDirection.Down ? 0 : 1) << 22);
            value |= (uint)((writeBack == WriteBack.NoWriteBack ? 0 : 1) << 21);
            value |= (uint)((transferType == TransferType.Store ? 0 : 1) << 20);
            value |= (uint)(destinationRegister << 12);
            value |= (uint)(firstRegister << 16);
            value |= (uint)(GetShiftTypeCode(secondShiftType) << 4);
            value |= (uint)secondRegister;

            Write(value);
        }
コード例 #7
0
        public static uint EmitSingleDataTransfer(ConditionCode conditionCode, Indexing indexing, OffsetDirection offsetDirection, TransferSize transferSize, WriteBack writeBack, TransferType transferType, int firstRegister, int destinationRegister, ShiftType secondShiftType, int secondRegister)
        {
            Debug.Assert(destinationRegister <= 0xF);
            Debug.Assert(firstRegister <= 0xF);
            Debug.Assert(secondRegister <= 0xF);

            uint value = 0;

            value |= (uint)(GetConditionCode(conditionCode) << 28);
            value |= 1 << 26;
            value |= 1 << 25;
            value |= (uint)((indexing == Indexing.Post ? 0 : 1) << 24);
            value |= (uint)((transferSize == TransferSize.Word ? 0 : 1) << 23);
            value |= (uint)((offsetDirection == OffsetDirection.Down ? 0 : 1) << 22);
            value |= (uint)((writeBack == WriteBack.NoWriteBack ? 0 : 1) << 21);
            value |= (uint)((transferType == TransferType.Store ? 0 : 1) << 20);
            value |= (uint)(destinationRegister << 12);
            value |= (uint)(firstRegister << 16);
            value |= (uint)(GetShiftTypeCode(secondShiftType) << 4);
            value |= (uint)secondRegister;

            return(value);
        }
コード例 #8
0
        public void EmitSingleDataTransfer(ConditionCode conditionCode, Indexing indexing, OffsetDirection offsetDirection, TransferSize transferSize, WriteBack writeBack, TransferType transferType, int firstRegister, int destinationRegister, uint immediate)
        {
            Debug.Assert(destinationRegister <= 0xF);
            Debug.Assert(firstRegister <= 0xF);
            Debug.Assert(immediate <= 0xFFF);

            uint value = 0;

            value |= (uint)(GetConditionCode(conditionCode) << 28);
            value |= (uint)(1 << 26);
            value |= (uint)(1 << 25);
            value |= (uint)((indexing == Indexing.Post ? 0 : 1) << 24);
            value |= (uint)((transferSize == TransferSize.Word ? 0 : 1) << 23);
            value |= (uint)((offsetDirection == OffsetDirection.Down ? 0 : 1) << 22);
            value |= (uint)((writeBack == WriteBack.NoWriteBack ? 0 : 1) << 21);
            value |= (uint)((transferType == TransferType.Store ? 0 : 1) << 20);
            value |= (uint)(destinationRegister << 12);
            value |= (uint)(firstRegister << 16);
            value |= (uint)immediate;

            Write(value);
        }