本文整理汇总了C#中Drivers.Compiler.IL.ILConversionState类的典型用法代码示例。如果您正苦于以下问题:C# ILConversionState类的具体用法?C# ILConversionState怎么用?C# ILConversionState使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
ILConversionState类属于Drivers.Compiler.IL命名空间,在下文中一共展示了ILConversionState类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Convert
/// <summary>
/// See base class documentation.
/// <para>To Do's:</para>
/// <list type="bullet">
/// <item>
/// <term>To do</term>
/// <description>Implement storing of float arguments.</description>
/// </item>
/// </list>
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotImplementedException">
/// Thrown when storing a float argument is required as it currently hasn't been
/// implemented.
/// </exception>
/// <exception cref="System.ArgumentException">
/// Thrown when an invalid number of bytes is specified for the argument to store.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Get the index of the argument to load
Int16 index = 0;
switch ((OpCodes)theOp.opCode.Value)
{
case OpCodes.Starg:
index = Utilities.ReadInt16(theOp.ValueBytes, 0);
break;
case OpCodes.Starg_S:
index = (Int16)theOp.ValueBytes[0];
break;
}
Types.VariableInfo argInfo = conversionState.Input.TheMethodInfo.ArgumentInfos[index];
//Used to store the number of bytes to add to EBP to get to the arg
int BytesOffsetFromEBP = argInfo.Offset;
//Pop the argument value from the stack
int bytesForArg = argInfo.TheTypeInfo.SizeOnStackInBytes;
for (int i = 0; i < bytesForArg; i += 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "[EBP+" + (BytesOffsetFromEBP+i) + "]" });
}
//Pop the arg value from our stack
conversionState.CurrentStackFrame.Stack.Pop();
}
示例2: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);
int bytesShift = 0;
for (int i = 0; i < dwordsToRotate; i++)
{
if (i == 0)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + bytesShift.ToString() + "]", Dest = "EAX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
}
else if (i == dwordsToRotate - 1)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
}
else
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
}
bytesShift += 4;
}
rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
}
示例3: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// Thrown if divide operands are floating point numbers or if attempting to divide 64-bit numbers.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// Thrown if either operand is < 4 bytes long.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
StackItem testItem = conversionState.CurrentStackFrame.Stack.Pop();
if (testItem.isFloat)
{
//TODO - Support floats
throw new NotSupportedException("Switch for floats no supported!");
}
else if (testItem.sizeOnStackInBytes != 4)
{
//TODO - Support other sizes
throw new NotSupportedException("Switch for non-int32s not supported!");
}
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
for (int i = 0; i < theOp.ValueBytes.Length / 4; i++)
{
int branchOffset = theOp.NextOffset + Utilities.ReadInt32(theOp.ValueBytes, i * 4);
ILOp opToGoTo = conversionState.Input.At(branchOffset);
int branchPos = conversionState.PositionOf(opToGoTo);
conversionState.Append(new ASMOps.Cmp() { Arg1 = "EAX", Arg2 = i.ToString() });
conversionState.Append(new ASMOps.Jmp() { JumpType = ASMOps.JmpOp.JumpEqual, DestILPosition = branchPos });
}
}
示例4: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Push the previous method's ebp
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EBP" });
//Set ebp for this method
//See calling convention spec - this allows easy access of
//args and locals within the method without having to track
//temporary values (which would be a nightmare with the
//exception handling implementation that the kernel uses!)
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "ESP", Dest = "EBP" });
//Allocate stack space for locals
//Only bother if there are any locals
if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
{
int totalBytes = 0;
foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
{
totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
}
//We do not use "sub esp, X" (see below) because that leaves
//junk memory - we need memory to be "initialised" to 0
//so that local variables are null unless properly initialised.
//This prevents errors in the GC.
for (int i = 0; i < totalBytes / 4; i++)
{
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
}
//result.AppendLine(string.Format("sub esp, {0}", totalBytes));
}
}
示例5: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// Thrown when the metadata token is not for method metadata.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Load token i.e. typeref
//It should also support methodref and fieldrefs
int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
try
{
Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
if (theType == null)
{
throw new NullReferenceException();
}
string typeTableId = conversionState.TheILLibrary.GetTypeInfo(theType).ID;
conversionState.AddExternalLabel(typeTableId);
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = typeTableId });
conversionState.CurrentStackFrame.Stack.Push(new StackItem()
{
isFloat = false,
sizeOnStackInBytes = 4,
isGCManaged = false,
isValue = false
});
}
catch
{
throw new NotSupportedException("The metadata token specifies a fieldref or methodref which isn't supported yet!");
}
}
示例6: Convert
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Save return address
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$ra" });
//Push the previous method's fp
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$fp" });
//Set fp for this method
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$sp", Dest = "$fp", MoveType = ASMOps.Mov.MoveTypes.RegToReg });
//Allocate stack space for locals
//Only bother if there are any locals
if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
{
int totalBytes = 0;
foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
{
totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
}
//We do not use "sub esp, X" (see below) because that leaves
//junk memory - we need memory to be "initialised" to 0
//so that local variables are null unless properly initialised.
//This prevents errors in the GC.
for (int i = 0; i < totalBytes / 4; i++)
{
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
}
//result.AppendLine(string.Format("sub esp, {0}", totalBytes));
}
}
示例7: InsertPageFaultDetection
public static void InsertPageFaultDetection(ILConversionState conversionState, string reg, int offset, ILOp.OpCodes opCode)
{
if (PageFaultDetectionEnabled)
{
conversionState.Append(new ASMOps.Call() { Target = PageFaultDetectionMethod });
}
}
示例8: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// Thrown if either or both values to shift left are floating point values or
/// if the values are 8 bytes in size.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// Thrown if either or both values to multiply are not 4 or 8 bytes
/// in size or if the values are of different size.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
StackItem theItem = conversionState.CurrentStackFrame.Stack.Peek();
if (theItem.isFloat)
{
//SUPPORT - Not op for floats
throw new NotSupportedException("Not op not supported for float operands!");
}
if (theItem.sizeOnStackInBytes == 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
}
else if (theItem.sizeOnStackInBytes == 8)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EBX" });
conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
conversionState.Append(new ASMOps.Not() { Dest = "EBX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EBX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
}
else
{
throw new NotSupportedException("Not op not supported for operand size!");
}
}
示例9: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">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 void Convert(ILConversionState conversionState, ILOp theOp)
{
//Load static field
//Load the metadata token used to get the type info
int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
//Get the type info for the object to load
Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);
//Get the object size information
int size = theTypeInfo.SizeOnStackInBytes;
//Load the object onto the stack
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "ECX" });
for (int i = size - 4; i >= 0; i -= 4)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ECX+" + i.ToString() + "]", Dest = "EAX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
}
int extra = size % 4;
for (int i = extra - 1; i >= 0; i--)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "[ECX+" + i.ToString() + "]", Dest = "AL" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Byte, Src = "AL" });
}
conversionState.CurrentStackFrame.Stack.Push(new StackItem()
{
isFloat = false,
sizeOnStackInBytes = size,
isGCManaged = false
});
}
示例10: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);
int bytesShift = 0;
for (int i = 0; i < dwordsToRotate; i++)
{
if (i == 0)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = bytesShift.ToString() + "($sp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else if (i == dwordsToRotate - 1)
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = bytesShift + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else
{
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
bytesShift += 4;
}
rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
}
示例11: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// Thrown if either or both values to not are floating point values or
/// if the values are 8 bytes in size.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Pop item to negate
StackItem itemA = conversionState.CurrentStackFrame.Stack.Peek();
if (itemA.isFloat)
{
//SUPPORT - floats
throw new NotSupportedException("Negate float vals not suppported yet!");
}
if (itemA.sizeOnStackInBytes == 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
//To not, arg Xor -1
conversionState.Append(new ASMOps.Mov() { Dest = "$t4", Src = "0xFFFFFFFF", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
conversionState.Append(new ASMOps.Xor() { Dest = "$t0", Src1 = "$t0", Src2 = "$t4" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });
}
else if (itemA.sizeOnStackInBytes == 8)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t3" });
conversionState.Append(new ASMOps.Mov() { Dest = "$t4", Src = "0xFFFFFFFF", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
conversionState.Append(new ASMOps.Xor() { Dest = "$t0", Src1 = "$t0", Src2 = "$t4" });
conversionState.Append(new ASMOps.Xor() { Dest = "$t3", Src1 = "$t3", Src2 = "$t4" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t3" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });
}
else
{
throw new NotSupportedException("Stack item size not supported by neg op!");
}
}
示例12: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">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 void Convert(ILConversionState conversionState, ILOp theOp)
{
//Load the metadata token used to get the type info
int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
//Get the type info for the object to load
Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);
//Get the object size information
int size = theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes;
conversionState.CurrentStackFrame.Stack.Pop();
conversionState.CurrentStackFrame.Stack.Pop();
//Load the object onto the stack
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Dest = "ECX", Src = "[ESP+" + theTypeInfo.SizeOnStackInBytes + "]" });
if (size == 1)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX]" });
}
else if (size == 2)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX]" });
}
else if (size >= 4)
{
for (int i = 0; i < size; i += 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
switch (size - i)
{
case 1:
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX+" + i + "]" });
break;
case 2:
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX+" + i + "]" });
break;
case 3:
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX+" + i + "]" });
conversionState.Append(new ASMOps.Shr() { Src = "16", Dest = "EAX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX+" + (i + 1) + "]" });
break;
default:
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[ECX+" + i + "]" });
break;
}
}
}
else
{
throw new ArgumentOutOfRangeException("Storing object with unsupported size! Size: " + size.ToString());
}
conversionState.Append(new ASMOps.Add() { Dest = "ESP", Src = "4" });
}
示例13: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// If either value is < 4 bytes in length or
/// operands are not of the same size.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Pop item to negate
StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();
if(itemA.isFloat)
{
//SUPPORT - floats
throw new NotSupportedException("Negate float vals not suppported yet!");
}
// Two's Complement negation
// - "Not" value then add 1
if(itemA.sizeOnStackInBytes == 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Neg() { Arg = "EAX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
}
else if (itemA.sizeOnStackInBytes == 8)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EDX" });
// Not the value
conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
conversionState.Append(new ASMOps.Not() { Dest = "EDX" });
// Then add 1
conversionState.Append(new ASMOps.Mov() { Src = "1", Dest = "EBX", Size = ASMOps.OperandSize.Dword });
conversionState.Append(new ASMOps.Mov() { Src = "0", Dest = "ECX", Size = ASMOps.OperandSize.Dword });
//Add ecx:ebx to edx:eax
//Add low bits
conversionState.Append(new ASMOps.Add() { Src = "EBX", Dest = "EAX" });
//Add high bits including any carry from
//when low bits were added
conversionState.Append(new ASMOps.Add() { Src = "ECX", Dest = "EDX", WithCarry = true });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EDX" });
conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
}
else
{
throw new NotSupportedException("Stack item size not supported by neg op!");
}
conversionState.CurrentStackFrame.Stack.Push(new StackItem()
{
isFloat = itemA.isFloat,
sizeOnStackInBytes = itemA.sizeOnStackInBytes,
isGCManaged = itemA.isGCManaged,
isValue = itemA.isValue
});
}
示例14: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">See base class documentation.</param>
/// <returns>See base class documentation.</returns>
/// <exception cref="System.NotSupportedException">
/// Thrown when the return value is a float or the size on the stack
/// in bytes is not 4 or 8 bytes.
/// </exception>
public override void Convert(ILConversionState conversionState, ILOp theOp)
{
//Store the return value
//Get the return type
Type retType = (conversionState.Input.TheMethodInfo.IsConstructor ?
typeof(void) : ((MethodInfo)conversionState.Input.TheMethodInfo.UnderlyingInfo).ReturnType);
Types.TypeInfo retTypeInfo = conversionState.TheILLibrary.GetTypeInfo(retType);
//Get the size of the return type on stack
int retSize = retTypeInfo.SizeOnStackInBytes;
//If the size isn't 0 (i.e. isn't "void" which has no return value)
if (retSize != 0)
{
//Pop the return value off our stack
StackItem retItem = conversionState.CurrentStackFrame.Stack.Pop();
//If it is float, well, we don't support it yet...
if (retItem.isFloat)
{
//SUPPORT - floats
throw new NotSupportedException("Floats return type not supported yet!");
}
//Otherwise, store the return value at [ebp+8]
//[ebp+8] because that is last "argument"
// - read the calling convention spec
else
{
for(int i = 0; i < retSize; i += 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Dest = "[EBP+" + (i + 8) + "]", Src = "EAX" });
}
}
}
//Once return value is off the stack, remove the locals
//Deallocate stack space for locals
//Only bother if there are any locals
if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
{
//Get the total size of all locals
int totalBytes = 0;
foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
{
totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
}
//Move esp past the locals
conversionState.Append(new ASMOps.Add() { Src = totalBytes.ToString(), Dest = "ESP" });
}
//Restore ebp to previous method's ebp
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EBP" });
//This pop also takes last value off the stack which
//means top item is the return address
//So ret command can now be correctly executed.
}
示例15: Convert
/// <summary>
/// See base class documentation.
/// </summary>
/// <param name="theOp">See base class documentation.</param>
/// <param name="conversionState">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 void Convert(ILConversionState conversionState, ILOp theOp)
{
int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
Types.FieldInfo theFieldInfo = conversionState.GetFieldInfo(theField.DeclaringType, theField.Name);
Types.TypeInfo theFieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theFieldInfo.FieldType);
string fieldId = theFieldInfo.ID;
int size = /*theFieldTypeInfo.IsValueType ? theFieldTypeInfo.SizeOnHeapInBytes : */theFieldTypeInfo.SizeOnStackInBytes;
bool isFloat = Utilities.IsFloat(theField.FieldType);
conversionState.AddExternalLabel(fieldId);
StackItem value = conversionState.CurrentStackFrame.Stack.Pop();
if (isFloat)
{
//SUPPORT - floats
throw new NotSupportedException("Storing static fields of type float not supported yet!");
}
conversionState.Append(new ASMOps.La() { Dest = "$t4", Label = fieldId });
if (size == 1)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "$t1", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else if (size == 2)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Halfword, Src = "$t1", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else if (size == 4)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else if (size == 8)
{
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "4($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
}
else
{
throw new ArgumentOutOfRangeException("Storing static field that has stack size greater than 8 not supported!");
}
if (value.sizeOnStackInBytes - size > 0)
{
conversionState.Append(new ASMOps.Add() { Src1 = "$sp", Src2 = (value.sizeOnStackInBytes - size).ToString(), Dest = "$sp" });
}
}