using System; using CPUx86 = Cosmos.IL2CPU.X86; using Indy.IL2CPU; namespace Cosmos.IL2CPU.X86.IL { [Cosmos.IL2CPU.OpCode( ILOpCode.Code.Stsfld )] public class Stsfld : ILOp { public Stsfld( Cosmos.IL2CPU.Assembler aAsmblr ) : base( aAsmblr ) { } public override void Execute( MethodInfo aMethod, ILOpCode aOpCode ) { var xType = aMethod.MethodBase.DeclaringType; var xOpCode = ( ILOpCodes.OpField )aOpCode; System.Reflection.FieldInfo xField = xOpCode.Value; int aExtraOffset = 0; bool xNeedsGC = xField.FieldType.IsClass && !xField.FieldType.IsValueType; uint xSize = SizeOfType( xField.FieldType ); if( xNeedsGC ) { aExtraOffset = 12; } new Comment( Assembler, "Type = '" + xField.FieldType.FullName + "', NeedsGC = " + xNeedsGC ); uint xOffset = 0; var xFields = xField.DeclaringType.GetFields(); foreach( System.Reflection.FieldInfo xInfo in xFields ) { if( xInfo == xField ) break; xOffset += SizeOfType( xInfo.FieldType ); } string xDataName = DataMember.GetStaticFieldName(xField); if( xNeedsGC ) { new CPUx86.Push { DestinationRef = ElementReference.New( xDataName ), DestinationIsIndirect = true }; new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName( GCImplementationRefs.DecRefCountRef ) }; } for( int i = 0; i < ( xSize / 4 ); i++ ) { new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; new CPUx86.Move { DestinationRef = ElementReference.New( xDataName, i * 4 ), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX }; } switch( xSize % 4 ) { case 1: { new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; new CPUx86.Move { DestinationRef = ElementReference.New( xDataName, ( int )( ( xSize / 4 ) * 4 ) ), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.AL }; break; } case 2: { new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; new CPUx86.Move { DestinationRef = ElementReference.New( xDataName, ( int )( ( xSize / 4 ) * 4 ) ), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.AX }; break; } case 0: { break; } default: //EmitNotImplementedException(Assembler, GetServiceProvider(), "Ldsfld: Remainder size " + (xSize % 4) + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel); throw new NotImplementedException(); //break; } Assembler.Stack.Pop(); } } // using System; // using System.Collections.Generic; // using Cosmos.IL2CPU.X86; // // // using CPUx86 = Cosmos.IL2CPU.X86; // using System.Reflection; // using Indy.IL2CPU.Compiler; // // namespace Indy.IL2CPU.IL.X86 { // [OpCode(OpCodeEnum.Stsfld)] // public class Stsfld: Op { // private string mDataName; // private Type mDataType; // private bool mNeedsGC; // private string mBaseLabel; // private string mNextLabel; // private string mCurLabel; // private uint mCurOffset; // private MethodInformation mMethodInformation; // // //public static void ScanOp(ILReader aReader, MethodInformation aMethodInfo, SortedList aMethodData) { // // FieldInfo xField = aReader.OperandValueField; // // Engine.QueueStaticField(xField); // //} // private FieldInfo mField; // public Stsfld(ILReader aReader, MethodInformation aMethodInfo) // : base(aReader, aMethodInfo) { // mField = aReader.OperandValueField; // mDataName = DataMember.GetStaticFieldName(mField); // mNeedsGC = !mField.FieldType.IsValueType; // mDataType = mField.FieldType; // mBaseLabel = GetInstructionLabel(aReader); // mMethodInformation = aMethodInfo; // mCurOffset = aReader.Position; // mCurLabel = IL.Op.GetInstructionLabel(aReader); // mNextLabel = IL.Op.GetInstructionLabel(aReader.NextPosition); // } // // public override void DoAssemble() { // var xSize = GetService().SizeOfType(mField.FieldType); // var xDecRefMethodInfo = GetService().GetMethodInfo(GCImplementationRefs.DecRefCountRef, // false); // // // if (mNeedsGC) { // new CPUx86.Push { DestinationRef = ElementReference.New(mDataName), DestinationIsIndirect = true }; // new CPUx86.Call { DestinationLabel = xDecRefMethodInfo.LabelName}; // } // for (int i = 0; i < (xSize / 4); i++) // { // new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // new CPUx86.Move { DestinationRef = ElementReference.New(mDataName, i * 4), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX }; // } // switch (xSize % 4) // { // case 1: { // new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // new CPUx86.Move { DestinationRef = ElementReference.New(mDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.AL }; // break; // } // case 2: { // new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // new CPUx86.Move { DestinationRef = ElementReference.New(mDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPUx86.Registers.AX }; // break; // } // case 0: { // break; // } // default: // EmitNotImplementedException(Assembler, GetServiceProvider(), "Ldsfld: Remainder size " + (xSize % 4) + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel); // break; // // } // Assembler.Stack.Pop(); // } // } // } }