/// <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); }
// 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); }
// 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); }
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); } }
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); } }
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); }
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); }
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); }