From d1f837f66b0b065d671ea22006ef413eb45988ca Mon Sep 17 00:00:00 2001 From: kudzu_cp <6d05c8c8ef5431987001abfdb2eadc9593ac9498> Date: Fri, 24 Jul 2009 19:50:53 +0000 Subject: [PATCH] --- .../Cosmos.IL2CPU.Profiler/ILOpProfiler.cs | 2 +- .../IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj | 1 + source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs | 62 ++----------------- .../Cosmos.IL2CPU/ILOpCodes/InlineVar.cs | 15 +++++ source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs | 31 ++++++---- source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs | 31 ++++++---- 6 files changed, 58 insertions(+), 84 deletions(-) create mode 100644 source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs diff --git a/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs b/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs index 2304dc521..087160baf 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs @@ -5,7 +5,7 @@ using System.Text; namespace Cosmos.IL2CPU.Profiler { public class ILOpProfiler : Cosmos.IL2CPU.ILOp { - protected ILOpProfiler(ILOpCode aOpCode) + public ILOpProfiler(ILOpCode aOpCode) : base(aOpCode) { } } diff --git a/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj b/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj index 487209a9f..5b555bcf6 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj +++ b/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj @@ -53,6 +53,7 @@ + diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs index ce4b8379f..fdaaf8022 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs @@ -12,15 +12,6 @@ namespace Cosmos.IL2CPU { //TODO: Change this to an abstract class and make constructor protected public class ILOpCode { - public readonly Code OpCode; - - public ILOpCode(Code aOpCode) { - OpCode = aOpCode; - } - - //TODO: Use System.Reflection.Emit.OpCodes where possible, but we still need these - //enums because they are used in attributes and other places that we need - //compile time values public enum Code : ushort { #region Values Nop = 0x0000, @@ -252,55 +243,10 @@ namespace Cosmos.IL2CPU { #endregion } - public static long? GetShortcutOperand(Code aOpCode) { - switch (aOpCode) { - case Code.Ldarg_0: - return 0; - case Code.Ldarg_1: - return 1; - case Code.Ldarg_2: - return 2; - case Code.Ldarg_3: - return 3; - case Code.Ldc_I4_0: - return 0; - case Code.Ldc_I4_1: - return 1; - case Code.Ldc_I4_2: - return 2; - case Code.Ldc_I4_3: - return 3; - case Code.Ldc_I4_4: - return 4; - case Code.Ldc_I4_5: - return 5; - case Code.Ldc_I4_6: - return 6; - case Code.Ldc_I4_7: - return 7; - case Code.Ldc_I4_8: - return 8; - case Code.Ldc_I4_M1: - return -1; - case Code.Ldloc_0: - return 0; - case Code.Ldloc_1: - return 1; - case Code.Ldloc_2: - return 2; - case Code.Ldloc_3: - return 3; - case Code.Stloc_0: - return 0; - case Code.Stloc_1: - return 1; - case Code.Stloc_2: - return 2; - case Code.Stloc_3: - return 3; - default: - return null; - } + public readonly Code OpCode; + + public ILOpCode(Code aOpCode) { + OpCode = aOpCode; } } diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs new file mode 100644 index 000000000..001d2dda6 --- /dev/null +++ b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Cosmos.IL2CPU.ILOpCodes { + public class InlineVar : ILOpCode { + public readonly UInt16 Value; + + public InlineVar(Code aOpCode, UInt16 aValue) + : base(aOpCode) { + Value = aValue; + } + } +} diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs index ba3d7b7c1..8d2039462 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs @@ -58,13 +58,11 @@ namespace Cosmos.IL2CPU { } //TODO: Need to look at OpCode operandtype and queue for these: + // probably dont need to look by op, but can do by operand instead. // Call: QueueMethod(aReader.OperandValueMethod); // Callvirt: QueueMethod(aReader.OperandValueMethod); // Newobj: QueueMethod(aReader.OperandValueMethod); - // Get arguments before Shortcut expansion. - //TODO: Are all shortcuts wo arguments? if so we can skip this step for shortcuts - ILOpCode xILOpCode = null; switch (xOpCode.OperandType) { // The operand is a 32-bit integer branch target. @@ -81,7 +79,7 @@ namespace Cosmos.IL2CPU { // The operand is a 32-bit integer. case OperandType.InlineI: - xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadInt32(xIL, xPos)); + xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadUInt32(xIL, xPos)); xPos = xPos + 4; break; @@ -122,7 +120,7 @@ namespace Cosmos.IL2CPU { break; case OperandType.InlineSwitch: { - int xCount = (int)ReadInt32(xIL, xPos); + int xCount = (int)ReadUInt32(xIL, xPos); int[] xBranchLocations = new int[xCount]; uint[] xBranchValues = new uint[xCount]; for (int i = 0; i < xCount; i++) { @@ -153,7 +151,7 @@ namespace Cosmos.IL2CPU { // 16-bit integer containing the ordinal of a local variable or an argument. case OperandType.InlineVar: - xILOpCode = new ILOpCode(xOpCodeVal); + xILOpCode = new ILOpCodes.InlineVar(xOpCodeVal, ReadUInt16(xIL, xPos)); xPos = xPos + 2; break; @@ -175,7 +173,7 @@ namespace Cosmos.IL2CPU { xPos = xPos + 4; break; - // 8-bit integer containing the ordinal of a local variable or an argumenta. + // 8-bit integer containing the ordinal of a local variable or an argument. case OperandType.ShortInlineVar: xILOpCode = new ILOpCode(xOpCodeVal); xPos = xPos + 4; @@ -186,9 +184,12 @@ namespace Cosmos.IL2CPU { } #region Expand shortcuts + // This region expands shortcut ops into full ops + // This elminates the amount of code required in the assemblers + // by allowing them to ignore the shortcuts switch (xOpCodeVal) { case ILOpCode.Code.Beq_S: - xILOpCode = new ILOpCodes.InlineNone(ILOpCode.Code.Beq); + //xILOpCode = new ILOpCodes.xxx(ILOpCode.Code.Beq, xILOpCode.value); break; case ILOpCode.Code.Bge_S: @@ -240,19 +241,19 @@ namespace Cosmos.IL2CPU { break; case ILOpCode.Code.Ldarg_0: - //return Code.Ldarg; + xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 0); break; case ILOpCode.Code.Ldarg_1: - //return Code.Ldarg; + xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 1); break; case ILOpCode.Code.Ldarg_2: - //return Code.Ldarg; + xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 2); break; case ILOpCode.Code.Ldarg_3: - //return Code.Ldarg; + xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 3); break; case ILOpCode.Code.Ldarg_S: @@ -368,10 +369,14 @@ namespace Cosmos.IL2CPU { return xResult; } - private UInt32 ReadInt32(byte[] aBytes, int aPos) { + private UInt32 ReadUInt32(byte[] aBytes, int aPos) { return (UInt32)(aBytes[aPos + 3] << 24 | aBytes[aPos + 2] << 16 | aBytes[aPos + 1] << 8 | aBytes[aPos]); } + private UInt16 ReadUInt16(byte[] aBytes, int aPos) { + return (UInt16)(aBytes[aPos + 1] << 8 | aBytes[aPos]); + } + //mOperandValueStr = mModule.ResolveString(OperandValueInt32); //public MethodBase OperandValueMethod { diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs index a551ae205..9ec887c90 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs @@ -33,22 +33,25 @@ namespace Cosmos.IL2CPU { public ILScanner(Type aAssemblerBaseOp) : this(aAssemblerBaseOp, false) { } - public ILScanner(Type aAssemblerBaseOp, bool aProfileMode) { + public ILScanner(Type aAssemblerBaseOp, bool aSingleILOp) { mReader = new ILReader(); - if (aProfileMode) { - LoadILOpsForProfiling(aAssemblerBaseOp); + if (aSingleILOp) { + LoadILOp(aAssemblerBaseOp); } else { LoadILOps(aAssemblerBaseOp); } } - protected void LoadILOpsForProfiling(Type aAssemblerBaseOp) { + protected void LoadILOp(Type aAssemblerBaseOp) { var xCtor = aAssemblerBaseOp.GetConstructors()[0]; - foreach (var xCode in Enum.GetValues(typeof(ILOpCode.Code))) { - if ((uint)xCode <= 0xFF) { - mILOpsLo[(uint)xCode] = xCtor; + // Don't change the type in the foreach to a var, its necessary as it is now + // to typecast it, so we can then recast to an int. + foreach (ILOpCode.Code xCode in Enum.GetValues(typeof(ILOpCode.Code))) { + int xCodeValue = (int)xCode; + if (xCodeValue <= 0xFF) { + mILOpsLo[xCodeValue] = xCtor; } else { - mILOpsHi[(uint)xCode & 0xFF] = xCtor; + mILOpsHi[xCodeValue & 0xFF] = xCtor; } } } @@ -101,12 +104,16 @@ namespace Cosmos.IL2CPU { foreach (var xOpCode in xOpCodes) { //InstructionCount++; ConstructorInfo xCtor; - if ((uint)xOpCode.OpCode <= 0xFF) { - xCtor = mILOpsLo[(uint)xOpCode.OpCode]; + uint xOpCodeVal = (uint)xOpCode.OpCode; + if (xOpCodeVal <= 0xFF) { + xCtor = mILOpsLo[xOpCodeVal]; } else { - xCtor = mILOpsHi[(uint)xOpCode.OpCode]; + xCtor = mILOpsHi[xOpCodeVal & 0xFF]; + } + // TODO: Remove this if when all shortcut espansions are working again + if (xCtor != null) { + var xILOp = xCtor.Invoke(new object[] { xOpCode }); } - var xILOp = xCtor.Invoke(new object[] {xOpCode}); } } }