Cosmos/source/Indy.IL2CPU.IL/ILReader.cs
smremde_cp 043f9f1288 Fixed IL2CODE UInt32 bug (thianks M)
Removed PCIDevice hack
2008-03-19 12:42:08 +00:00

302 lines
No EOL
8.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
namespace Indy.IL2CPU.IL {
public partial class ILReader {
private readonly MethodBody mBody;
private MemoryStream mStream;
private MethodBase mMethod;
private Module mModule;
public ILReader(MethodBase aMethod) {
mBody = aMethod.GetMethodBody();
mMethod = aMethod;
mModule = mMethod.Module;
mStream = new MemoryStream(mBody.GetILAsByteArray());
}
private OpCodeEnum mOpCode;
private byte[] mOperand;
private bool mHasOperand;
public int Position {
get;
private set;
}
public int NextPosition {
get {
return (int)mStream.Position;
}
}
public bool EndOfStream {
get {
return mStream.Position == mStream.Length;
}
}
public bool HasOperand {
get {
return mHasOperand;
}
}
public OpCodeEnum OpCode {
get {
return mOpCode;
}
}
public byte[] Operand {
get {
return mOperand;
}
}
private string mOperandValueStr;
public string OperandValueStr {
get {
if (mOperandValueStr == null) {
mOperandValueStr = mModule.ResolveString(OperandValueInt32);
}
return mOperandValueStr;
}
}
private MethodBase mOperandValueMethod;
public MethodBase OperandValueMethod {
get {
if (mOperandValueMethod == null) {
Type[] xTypeGenArgs = null;
Type[] xMethodGenArgs = null;
if (mMethod.DeclaringType.IsGenericType) {
xTypeGenArgs = mMethod.DeclaringType.GetGenericArguments();
}
if (mMethod.IsGenericMethod) {
xMethodGenArgs = mMethod.GetGenericArguments();
}
mOperandValueMethod = mModule.ResolveMethod(OperandValueInt32, xTypeGenArgs, xMethodGenArgs);
}
return mOperandValueMethod;
}
}
private uint? mOperandValueBranchPosition;
private bool mIsShortcut;
public uint OperandValueBranchPosition {
get {
if (mOperandValueBranchPosition == null) {
//sbyte xTemp = (sbyte)mOperand;
//if (xTemp == mOperand) {
// mOperandValueBranchPosition = NextPosition + xTemp;
//} else {
// if (mStream.Length < (NextPosition + mOperand + 1)) {
// mOperandValueBranchPosition = (uint)mOperand;
// } else {
// mOperandValueBranchPosition = (uint)(NextPosition + mOperand);
// }
if (!mIsShortcut) {
mOperandValueBranchPosition = (uint?)(NextPosition + OperandValueInt32);
} else {
mOperandValueBranchPosition = (uint?)(NextPosition + (sbyte)OperandValueInt32);
}
//}
}
return mOperandValueBranchPosition.Value;
}
}
private FieldInfo mOperandValueField;
public FieldInfo OperandValueField {
get {
if (mOperandValueField == null) {
Type[] xTypeGenArgs = null;
Type[] xMethodGenArgs = null;
if (mMethod.DeclaringType.IsGenericType) {
xTypeGenArgs = mMethod.DeclaringType.GetGenericArguments();
}
if (mMethod.IsGenericMethod) {
xMethodGenArgs = mMethod.GetGenericArguments();
}
mOperandValueField = mModule.ResolveField(OperandValueInt32, xTypeGenArgs, xMethodGenArgs);
}
return mOperandValueField;
}
}
private Type mOperandValueType;
public Type OperandValueType {
get {
if (mOperandValueType == null) {
Type[] xTypeGenArgs = null;
Type[] xMethodGenArgs = null;
if (mMethod.DeclaringType.IsGenericType) {
xTypeGenArgs = mMethod.DeclaringType.GetGenericArguments();
}
if (mMethod.IsGenericMethod) {
xMethodGenArgs = mMethod.GetGenericArguments();
}
mOperandValueType = mModule.ResolveType(OperandValueInt32, xTypeGenArgs, xMethodGenArgs);
}
return mOperandValueType;
}
}
public uint[] OperandValueBranchLocations {
get;
private set;
}
private int? mOperandValueInt32;
public int OperandValueInt32 {
get
{
if (!mIsShortcut)
{
if (mOperandValueInt32 == null)
{
byte[] xData = new byte[4];
Array.Copy(Operand, xData, Math.Min(4, Operand.Length));
mOperandValueInt32 = BitConverter.ToInt32(xData, 0);
}
}
else
{
sbyte xShortValue = (sbyte)Operand[0];
mOperandValueInt32 = xShortValue;
}
return mOperandValueInt32.Value;
}
}
private Single? mOperandValueSingle;
public Single OperandValueSingle {
get {
if (mOperandValueSingle == null) {
mOperandValueSingle = BitConverter.ToSingle(Operand, 0);
}
return mOperandValueSingle.Value;
}
}
private Double? mOperandValueDouble;
public Double OperandValueDouble {
get {
if (mOperandValueDouble == null) {
mOperandValueDouble = BitConverter.ToDouble(Operand, 0);
}
return mOperandValueDouble.Value;
}
}
public bool Read() {
Position = NextPosition;
int xByteValueInt = mStream.ReadByte();
OpCodeEnum xOpCode;
if (xByteValueInt == -1) {
return false;
}
byte xByteValue = (byte)xByteValueInt;
if (xByteValue == 0xFE) {
xByteValueInt = mStream.ReadByte();
if (xByteValueInt == -1) {
return false;
}
xOpCode = (OpCodeEnum)(xByteValue << 8 | xByteValueInt);
} else {
xOpCode = (OpCodeEnum)xByteValue;
}
byte xOperandSize = GetOperandSize(xOpCode);
mOperand = null;
mOperandValueStr = null;
mOperandValueMethod = null;
mOperandValueField = null;
mOperandValueSingle = null;
mOperandValueType = null;
mOperandValueInt32 = null;
mOperandValueBranchPosition = null;
OperandValueBranchLocations = null;
mOperandValueDouble = null;
mOpCode = GetNonShortcutOpCode(xOpCode);
mIsShortcut = mOpCode != xOpCode;
mHasOperand = xOperandSize > 0;
if (mHasOperand) {
mOperand = ReadOperand(xOperandSize);
mOperandValueInt32 = GetInt32FromOperandByteArray(mOperand);
} else {
if (mOpCode != xOpCode) {
long? xTempOperand = GetShortcutOperand(xOpCode);
if (xTempOperand != null) {
mHasOperand = true;
mOperand = BitConverter.GetBytes(xTempOperand.Value);
}
}
if (mOpCode == OpCodeEnum.Switch) {
int[] xBranchLocations1 = new int[ReadInt32()];
for (int i = 0; i < xBranchLocations1.Length; i++) {
xBranchLocations1[i] = ReadInt32();
}
uint[] xResult = new uint[xBranchLocations1.Length];
for (int i = 0; i < xBranchLocations1.Length; i++) {
if ((NextPosition + xBranchLocations1[i]) < 0) {
xResult[i] = (uint)xBranchLocations1[i];
} else {
xResult[i] = (uint)(NextPosition + xBranchLocations1[i]);
}
}
OperandValueBranchLocations = xResult;
}
}
return true;
}
private Int64 ReadInt64() {
long xResult = 0;
byte xOperandSize = 64;
byte[] xBytes = new byte[xOperandSize / 8];
while (xOperandSize > 0) {
int xByteValueInt = mStream.ReadByte();
if (xByteValueInt == -1) {
break;
}
xBytes[(xOperandSize / 8) - 1] = (byte)xByteValueInt;
xOperandSize -= 8;
}
for (int i = 0; i < xBytes.Length; i++) {
xResult = xResult << 8 | xBytes[i];
}
return xResult;
}
private byte[] ReadOperand(byte aOperandSize) {
byte[] xBytes = new byte[aOperandSize / 8];
int index = 0;
while (aOperandSize > 0) {
int xByteValueInt = mStream.ReadByte();
if (xByteValueInt == -1) {
break;
}
xBytes[index] = (byte)xByteValueInt;
index += 1;
aOperandSize -= 8;
}
return xBytes;
}
private static Int32 GetInt32FromOperandByteArray(byte[] aData) {
Int32 xResult = 0;
for (int i = aData.Length - 1; i >= 0; i--) {
xResult = xResult << 8 | aData[i];
}
return xResult;
}
private Int32 ReadInt32() {
return GetInt32FromOperandByteArray(ReadOperand(32));
}
}
}