/// <summary> /// See base class documentation. /// </summary> /// <param name="anILOpInfo">See base class documentation.</param> /// <param name="aScannerState">See base class documentation.</param> /// <returns>See base class documentation.</returns> /// <exception cref="System.NotSupportedException"> /// Thrown if the value to store is floating point. /// </exception> public override string Convert(ILOpInfo anILOpInfo, ILScannerState aScannerState) { StringBuilder result = new StringBuilder(); int metadataToken = Utils.ReadInt32(anILOpInfo.ValueBytes, 0); FieldInfo theField = aScannerState.CurrentILChunk.Method.Module.ResolveField(metadataToken); string fieldID = aScannerState.GetStaticFieldID(theField); int size = Utils.GetNumBytesForType(theField.FieldType); bool isFloat = Utils.IsFloat(theField.FieldType); StackItem value = aScannerState.CurrentStackFrame.Stack.Pop(); if (isFloat) { //SUPPORT - floats throw new NotSupportedException("Storing static fields of type float not supported yet!"); } if (size == 1) { result.AppendLine("pop dword eax"); result.AppendLine(string.Format("mov byte [{0}], al", fieldID)); } else if (size == 2) { result.AppendLine("pop dword eax"); result.AppendLine(string.Format("mov word [{0}], ax", fieldID)); } else if (size == 4) { result.AppendLine("pop dword eax"); result.AppendLine(string.Format("mov dword [{0}], eax", fieldID)); } else if (size == 8) { result.AppendLine("pop dword eax"); result.AppendLine(string.Format("mov byte [{0}], eax", fieldID)); result.AppendLine("pop dword eax"); result.AppendLine(string.Format("mov byte [{0}+4], eax", fieldID)); } return result.ToString().Trim(); }
/// <summary> /// See base class documentation. /// </summary> /// <param name="anILOpInfo">See base class documentation.</param> /// <param name="aScannerState">See base class documentation.</param> /// <returns>See base class documentation.</returns> /// <exception cref="System.NotSupportedException"> /// Thrown when loading a static float field. /// </exception> public override string Convert(ILOpInfo anILOpInfo, ILScannerState aScannerState) { StringBuilder result = new StringBuilder(); //Load static field //Load the metadata token used to get the field info int metadataToken = Utils.ReadInt32(anILOpInfo.ValueBytes, 0); //Get the field info for the field to load FieldInfo theField = aScannerState.CurrentILChunk.Method.Module.ResolveField(metadataToken); //Get the ID (i.e. ASM label) of the field to load string fieldID = aScannerState.GetStaticFieldID(theField); //Load the field or field address switch ((OpCodes)anILOpInfo.opCode.Value) { case OpCodes.Ldsfld: { int size = Utils.GetNumBytesForType(theField.FieldType); bool isFloat = Utils.IsFloat(theField.FieldType); if (isFloat) { //SUPPORT - floats throw new NotSupportedException("Loading static fields of type float not supported yet!"); } if(size == 1) { result.AppendLine("xor eax, eax"); result.AppendLine(string.Format("mov byte al, [{0}]", fieldID)); result.AppendLine("push dword eax"); } else if(size == 2) { result.AppendLine("xor eax, eax"); result.AppendLine(string.Format("mov word ax, [{0}]", fieldID)); result.AppendLine("push dword eax"); } else if(size == 4) { result.AppendLine(string.Format("mov dword eax, [{0}]", fieldID)); result.AppendLine("push dword eax"); } else if (size == 8) { result.AppendLine(string.Format("mov dword eax, [{0}+4]", fieldID)); result.AppendLine("push dword eax"); result.AppendLine(string.Format("mov dword eax, [{0}]", fieldID)); result.AppendLine("push dword eax"); } aScannerState.CurrentStackFrame.Stack.Push(new StackItem() { isFloat = isFloat, sizeOnStackInBytes = (size == 8 ? 8 : 4), isGCManaged = Utils.IsGCManaged(theField.FieldType) }); } break; case OpCodes.Ldsflda: //Load the address of the field i.e. address of the ASM label result.AppendLine(string.Format("push dword {0}", fieldID)); aScannerState.CurrentStackFrame.Stack.Push(new StackItem() { isFloat = false, sizeOnStackInBytes = 4, isGCManaged = false }); break; } return result.ToString().Trim(); }