diff --git a/source/Cosmos.sln.DotSettings b/source/Cosmos.sln.DotSettings
new file mode 100644
index 000000000..e892d6a1a
--- /dev/null
+++ b/source/Cosmos.sln.DotSettings
@@ -0,0 +1,6 @@
+
+ DO_NOT_SHOW
+ <Policy Inspect="True" Prefix="x" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="a" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="m" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="m" Suffix="" Style="AaBb" />
\ No newline at end of file
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/AppAssembler.cs b/source2/IL2CPU/Cosmos.IL2CPU/AppAssembler.cs
index b807010f3..8fc5078ed 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/AppAssembler.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/AppAssembler.cs
@@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Cosmos.Assembler;
using Cosmos.Assembler.x86;
+using Cosmos.Assembler.x86._486AndUp;
using Cosmos.Build.Common;
using Cosmos.Debug.Common;
using Cosmos.IL2CPU.Plugs;
@@ -66,10 +67,6 @@ namespace Cosmos.IL2CPU
new Comment("Type: " + aMethod.MethodBase.DeclaringType.ToString());
new Comment("Name: " + aMethod.MethodBase.Name);
new Comment("Plugged: " + (aMethod.PlugMethod == null ? "No" : "Yes"));
- if (aMethod.MethodBase.Name == "GetFatEntry")
- {
- Console.Write("");
- }
// for now:
var shouldIncludeArgAndLocalsComment = true;
if (shouldIncludeArgAndLocalsComment)
@@ -460,6 +457,8 @@ namespace Cosmos.IL2CPU
}
else
{
+ // now emit the actual assembler code for this method.
+
//Conditions under which we should emit an INT3 instead of a plceholder NOP:
/* - First instruction in a Method / Loop / If / Else etc.
* -- In essence, whenever there is a opening {
@@ -467,109 +466,168 @@ namespace Cosmos.IL2CPU
* -- So only insert an INT3 when we are about to insert a NOP that came from IL code
*/
+ /* We group opcodes together by logical statement. Each statement will have its logical stack cleared.
+ * Also, this lets us do optimizations later on.
+ */
bool emitINT3 = true;
- foreach (var xOpCode in aOpCodes)
+ DebugInfo.SequencePoint xPreviousSequencePoint = null;
+ var xCurrentGroup = new List();
+ foreach (var xRawOpcode in aOpCodes)
{
- ushort xOpCodeVal = (ushort)xOpCode.OpCode;
- ILOp xILOp;
- if (xOpCodeVal <= 0xFF)
+ var xSP = mSequences.FirstOrDefault(q => q.Offset == xRawOpcode.Position && q.LineStart != 0xFEEFEE);
+ var hasNewSP = false;
+ // detect if we're at a new statement.
+ if (xPreviousSequencePoint == null && xSP != null)
{
- xILOp = mILOpsLo[xOpCodeVal];
+
}
- else
+ if (xSP != null && xCurrentGroup.Count > 0)
{
- xILOp = mILOpsHi[xOpCodeVal & 0xFF];
+ EmitInstructions(aMethod, xCurrentGroup, ref emitINT3);
+ xCurrentGroup.Clear();
+ xPreviousSequencePoint = xSP;
}
- mLog.WriteLine("\t{0} {1}", Assembler.Stack.Count, xILOp.GetType().Name);
- mLog.Flush();
-
- //Only emit INT3 as per conditions above...
- bool INT3Emitted = false;
- BeforeOp(aMethod, xOpCode, emitINT3, out INT3Emitted);
- //Emit INT3 on the first non-NOP instruction immediately after a NOP
- // - This is because TracePoints for NOP are automatically ignored in code called below this
- emitINT3 = (emitINT3 && !INT3Emitted) || xILOp is Cosmos.IL2CPU.X86.IL.Nop;
-
- new Comment(xILOp.ToString());
- var xNextPosition = xOpCode.Position + 1;
- #region Exception handling support code
- ExceptionHandlingClause xCurrentHandler = null;
- var xBody = aMethod.MethodBase.GetMethodBody();
- // todo: add support for nested handlers using a stack or so..
- foreach (ExceptionHandlingClause xHandler in xBody.ExceptionHandlingClauses)
- {
- if (xHandler.TryOffset > 0)
- {
- if (xHandler.TryOffset <= xNextPosition && (xHandler.TryLength + xHandler.TryOffset) > xNextPosition)
- {
- if (xCurrentHandler == null)
- {
- xCurrentHandler = xHandler;
- continue;
- }
- else if (xHandler.TryOffset > xCurrentHandler.TryOffset && (xHandler.TryLength + xHandler.TryOffset) < (xCurrentHandler.TryLength + xCurrentHandler.TryOffset))
- {
- // only replace if the current found handler is narrower
- xCurrentHandler = xHandler;
- continue;
- }
- }
- }
- if (xHandler.HandlerOffset > 0)
- {
- if (xHandler.HandlerOffset <= xNextPosition && (xHandler.HandlerOffset + xHandler.HandlerLength) > xNextPosition)
- {
- if (xCurrentHandler == null)
- {
- xCurrentHandler = xHandler;
- continue;
- }
- else if (xHandler.HandlerOffset > xCurrentHandler.HandlerOffset && (xHandler.HandlerOffset + xHandler.HandlerLength) < (xCurrentHandler.HandlerOffset + xCurrentHandler.HandlerLength))
- {
- // only replace if the current found handler is narrower
- xCurrentHandler = xHandler;
- continue;
- }
- }
- }
- if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
- {
- if (xHandler.FilterOffset > 0)
- {
- if (xHandler.FilterOffset <= xNextPosition)
- {
- if (xCurrentHandler == null)
- {
- xCurrentHandler = xHandler;
- continue;
- }
- else if (xHandler.FilterOffset > xCurrentHandler.FilterOffset)
- {
- // only replace if the current found handler is narrower
- xCurrentHandler = xHandler;
- continue;
- }
- }
- }
- }
- }
- #endregion
- var xNeedsExceptionPush = (xCurrentHandler != null) && (((xCurrentHandler.HandlerOffset > 0 && xCurrentHandler.HandlerOffset == xOpCode.Position) || ((xCurrentHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0 && xCurrentHandler.FilterOffset > 0 && xCurrentHandler.FilterOffset == xOpCode.Position)) && (xCurrentHandler.Flags == ExceptionHandlingClauseOptions.Clause));
- if (xNeedsExceptionPush)
- {
- Push(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), true);
- Assembler.Stack.Push(4, typeof(Exception));
- }
- xILOp.DebugEnabled = DebugEnabled;
- xILOp.Execute(aMethod, xOpCode);
-
- AfterOp(aMethod, xOpCode);
- //mLog.WriteLine( " end: " + Stack.Count.ToString() );
+ xCurrentGroup.Add(xRawOpcode);
+ }
+ if (xCurrentGroup.Count > 0)
+ {
+ EmitInstructions(aMethod, xCurrentGroup, ref emitINT3);
}
}
MethodEnd(aMethod);
}
+ private void BeforeEmitInstructions(MethodInfo aMethod, List aCurrentGroup)
+ {
+ // do optimizations
+ }
+
+ private void AfterEmitInstructions(MethodInfo aMethod, List aCurrentGroup)
+ {
+ // do optimizations
+ if (Assembler.Stack.Count > 0)
+ {
+ if (mDebugStackErrors)
+ {
+ Console.WriteLine("StackCorruption in Analytical stack:");
+ Console.WriteLine("- Method: {0}", aMethod.MethodBase.GetFullName());
+ Console.WriteLine("- Last ILOpCode offset: {0}", aCurrentGroup.Last().Position.ToString("X"));
+ }
+ }
+ }
+
+ private static bool mDebugStackErrors = true;
+ private void EmitInstructions(MethodInfo aMethod, List xCurrentGroup, ref bool emitINT3)
+ {
+ new Comment(String.Format("New Group Offset {0} - Offset {1}", xCurrentGroup.First().Position.ToString("X"), xCurrentGroup.Last().Position.ToString("X")));
+ BeforeEmitInstructions(aMethod, xCurrentGroup);
+ var xFirstInstruction = true;
+ foreach (var xOpCode in xCurrentGroup)
+ {
+ ushort xOpCodeVal = (ushort) xOpCode.OpCode;
+ ILOp xILOp;
+ if (xOpCodeVal <= 0xFF)
+ {
+ xILOp = mILOpsLo[xOpCodeVal];
+ }
+ else
+ {
+ xILOp = mILOpsHi[xOpCodeVal & 0xFF];
+ }
+ mLog.WriteLine("\t{0} {1}", Assembler.Stack.Count, xILOp.GetType().Name);
+ mLog.Flush();
+
+ //Only emit INT3 as per conditions above...
+ bool INT3Emitted = false;
+ BeforeOp(aMethod, xOpCode, emitINT3, out INT3Emitted, xFirstInstruction);
+ xFirstInstruction = false;
+ //Emit INT3 on the first non-NOP instruction immediately after a NOP
+ // - This is because TracePoints for NOP are automatically ignored in code called below this
+ emitINT3 = (emitINT3 && !INT3Emitted) || xILOp is Cosmos.IL2CPU.X86.IL.Nop;
+
+ new Comment(xILOp.ToString());
+ var xNextPosition = xOpCode.Position + 1;
+
+ #region Exception handling support code
+
+ ExceptionHandlingClause xCurrentHandler = null;
+ var xBody = aMethod.MethodBase.GetMethodBody();
+ // todo: add support for nested handlers using a stack or so..
+ foreach (ExceptionHandlingClause xHandler in xBody.ExceptionHandlingClauses)
+ {
+ if (xHandler.TryOffset > 0)
+ {
+ if (xHandler.TryOffset <= xNextPosition && (xHandler.TryLength + xHandler.TryOffset) > xNextPosition)
+ {
+ if (xCurrentHandler == null)
+ {
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ else if (xHandler.TryOffset > xCurrentHandler.TryOffset && (xHandler.TryLength + xHandler.TryOffset) < (xCurrentHandler.TryLength + xCurrentHandler.TryOffset))
+ {
+ // only replace if the current found handler is narrower
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ }
+ }
+ if (xHandler.HandlerOffset > 0)
+ {
+ if (xHandler.HandlerOffset <= xNextPosition && (xHandler.HandlerOffset + xHandler.HandlerLength) > xNextPosition)
+ {
+ if (xCurrentHandler == null)
+ {
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ else if (xHandler.HandlerOffset > xCurrentHandler.HandlerOffset && (xHandler.HandlerOffset + xHandler.HandlerLength) < (xCurrentHandler.HandlerOffset + xCurrentHandler.HandlerLength))
+ {
+ // only replace if the current found handler is narrower
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ }
+ }
+ if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
+ {
+ if (xHandler.FilterOffset > 0)
+ {
+ if (xHandler.FilterOffset <= xNextPosition)
+ {
+ if (xCurrentHandler == null)
+ {
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ else if (xHandler.FilterOffset > xCurrentHandler.FilterOffset)
+ {
+ // only replace if the current found handler is narrower
+ xCurrentHandler = xHandler;
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ var xNeedsExceptionPush = (xCurrentHandler != null) && (((xCurrentHandler.HandlerOffset > 0 && xCurrentHandler.HandlerOffset == xOpCode.Position) || ((xCurrentHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0 && xCurrentHandler.FilterOffset > 0 && xCurrentHandler.FilterOffset == xOpCode.Position)) && (xCurrentHandler.Flags == ExceptionHandlingClauseOptions.Clause));
+ if (xNeedsExceptionPush)
+ {
+ Push(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), true);
+ Assembler.Stack.Push(4, typeof (Exception));
+ }
+ xILOp.DebugEnabled = DebugEnabled;
+ xILOp.Execute(aMethod, xOpCode);
+
+ AfterOp(aMethod, xOpCode);
+ //mLog.WriteLine( " end: " + Stack.Count.ToString() );
+ }
+ AfterEmitInstructions(aMethod, xCurrentGroup);
+ }
+
protected void InitILOps()
{
InitILOps(typeof(ILOp));
@@ -1177,7 +1235,7 @@ namespace Cosmos.IL2CPU
new Comment("Stack contains " + Assembler.Stack.Count + " items: (" + xContents + ")");
}
- protected void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode, bool emitInt3NotNop, out bool INT3Emitted)
+ protected void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode, bool emitInt3NotNop, out bool INT3Emitted, bool hasSourcePoint)
{
string xLabel = TmpPosLabel(aMethod, aOpCode);
Assembler.CurrentIlLabel = xLabel;
@@ -1211,7 +1269,7 @@ namespace Cosmos.IL2CPU
DebugInfo.AddSymbols(mSymbols, false);
bool INT3PlaceholderEmitted = false;
- EmitTracer(aMethod, aOpCode, aMethod.MethodBase.DeclaringType.Namespace, emitInt3NotNop, out INT3Emitted, out INT3PlaceholderEmitted);
+ EmitTracer(aMethod, aOpCode, aMethod.MethodBase.DeclaringType.Namespace, emitInt3NotNop, out INT3Emitted, out INT3PlaceholderEmitted, hasSourcePoint);
if (INT3Emitted || INT3PlaceholderEmitted)
{
@@ -1223,43 +1281,43 @@ namespace Cosmos.IL2CPU
DebugInfo.AddINT3Labels(mINT3Labels);
}
- if (DebugEnabled && StackCorruptionDetection)
- {
- // if debugstub is active, emit a stack corruption detection. at this point, the difference between EBP and ESP
- // should be equal to the local variables sizes and the IL stack.
- // if not, we should break here.
+ //if (DebugEnabled && StackCorruptionDetection)
+ //{
+ // // if debugstub is active, emit a stack corruption detection. at this point, the difference between EBP and ESP
+ // // should be equal to the local variables sizes and the IL stack.
+ // // if not, we should break here.
- // first, calculate the expected difference
- var expectedDifference = aMethod.LocalVariablesSize;
- foreach (var item in Assembler.Stack)
- {
- expectedDifference += X86.IL.Ldarg.Align(item.Size, 4);
- }
+ // // first, calculate the expected difference
+ // var expectedDifference = aMethod.LocalVariablesSize;
+ // foreach (var item in Assembler.Stack)
+ // {
+ // expectedDifference += X86.IL.Ldarg.Align(item.Size, 4);
+ // }
- // if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
- // if not, we should somehow break here.
- new Mov { DestinationReg = Registers.EAX, SourceReg = RegistersEnum.ESP };
- new Mov { DestinationReg = Registers.EBX, SourceReg = RegistersEnum.EBP };
- new Add { DestinationReg = Registers.EAX, SourceValue = expectedDifference };
- new Compare { SourceReg = RegistersEnum.EAX, DestinationReg = RegistersEnum.EBX };
- new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
- new ClrInterruptFlag();
- // don't remove the call. It seems pointless, but we need it to retrieve the EIP value
- new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
- new Assembler.Label(xLabel + ".StackCorruptionCheck_GetAddress");
- new Pop { DestinationReg = RegistersEnum.EAX };
- new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
- new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
- new Halt();
- new Assembler.Label(xLabel + ".StackCorruptionCheck_End");
+ // // if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
+ // // if not, we should somehow break here.
+ // new Mov { DestinationReg = Registers.EAX, SourceReg = RegistersEnum.ESP };
+ // new Mov { DestinationReg = Registers.EBX, SourceReg = RegistersEnum.EBP };
+ // new Add { DestinationReg = Registers.EAX, SourceValue = expectedDifference };
+ // new Compare { SourceReg = RegistersEnum.EAX, DestinationReg = RegistersEnum.EBX };
+ // new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
+ // new ClrInterruptFlag();
+ // // don't remove the call. It seems pointless, but we need it to retrieve the EIP value
+ // new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
+ // new Assembler.Label(xLabel + ".StackCorruptionCheck_GetAddress");
+ // new Pop { DestinationReg = RegistersEnum.EAX };
+ // new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
+ // new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
+ // new Halt();
+ // new Assembler.Label(xLabel + ".StackCorruptionCheck_End");
- }
+ //}
}
- protected void EmitTracer(MethodInfo aMethod, ILOpCode aOp, string aNamespace, bool emitInt3NotNop, out bool INT3Emitted, out bool INT3PlaceholderEmitted)
+ protected void EmitTracer(MethodInfo aMethod, ILOpCode aOp, string aNamespace, bool emitInt3NotNop, out bool INT3Emitted, out bool INT3PlaceholderEmitted, bool isNewSourcePoint)
{
// NOTE - These if statements can be optimized down - but clarity is
- // more important the optimizations. Furthermoer the optimazations available
+ // more important than the optimizations. Furthermore the optimizations available
// would not offer much benefit
// Determine if a new DebugStub should be emitted
@@ -1282,16 +1340,10 @@ namespace Cosmos.IL2CPU
{
// If the current position equals one of the offsets, then we have
// reached a new atomic C# statement
- var xSP = mSequences.SingleOrDefault(q => q.Offset == aOp.Position);
- if (xSP == null)
+ if (!isNewSourcePoint)
{
return;
}
- else if (xSP.LineStart == 0xFEEFEE)
- {
- // 0xFEEFEE means hiddenline -> we dont want to stop there
- return;
- }
}
// Check if the DebugStub has been disabled for this method
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/IL/Cgt.cs b/source2/IL2CPU/Cosmos.IL2CPU/IL/Cgt.cs
index 0aa923ea9..1bfc34248 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/IL/Cgt.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/IL/Cgt.cs
@@ -17,6 +17,7 @@ namespace Cosmos.IL2CPU.X86.IL
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
var xStackItem = Assembler.Stack.Pop();
+ Assembler.Stack.Pop();
if( xStackItem.Size > 8 )
{
//EmitNotImplementedException( Assembler, GetServiceProvider(), "Cgt: StackSizes>8 not supported", CurInstructionLabel, mMethodInfo, mCurrentOffset, NextInstructionLabel );
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/IL/Clt_Un.cs b/source2/IL2CPU/Cosmos.IL2CPU/IL/Clt_Un.cs
index 02db2fab6..f845687d7 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/IL/Clt_Un.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/IL/Clt_Un.cs
@@ -16,6 +16,7 @@ namespace Cosmos.IL2CPU.X86.IL
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
var xStackItem = Assembler.Stack.Pop();
+ Assembler.Stack.Pop();
if( xStackItem.Size > 8 )
{
throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Clt_Un.cs->Error: StackSizes > 8 not supported");
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/IL/Ret.cs b/source2/IL2CPU/Cosmos.IL2CPU/IL/Ret.cs
index 17e6199ca..6e577a95f 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/IL/Ret.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/IL/Ret.cs
@@ -3,18 +3,24 @@ using CPUx86 = Cosmos.Assembler.x86;
namespace Cosmos.IL2CPU.X86.IL
{
- [Cosmos.IL2CPU.OpCode(ILOpCode.Code.Ret)]
- public class Ret: ILOp
- {
- public Ret(Cosmos.Assembler.Assembler aAsmblr):base(aAsmblr)
- {
- }
+ [Cosmos.IL2CPU.OpCode(ILOpCode.Code.Ret)]
+ public class Ret : ILOp
+ {
+ public Ret(Cosmos.Assembler.Assembler aAsmblr) : base(aAsmblr)
+ {
+ }
- public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) {
- //TODO: Return
- Jump_End(aMethod);
- // Need to jump to end of method. Assembler can emit this label for now
- //new CPU.Jump { DestinationLabel = MethodFooterOp.EndOfMethodLabelNameNormal };
+ public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
+ {
+ //TODO: Return
+ Jump_End(aMethod);
+ // Need to jump to end of method. Assembler can emit this label for now
+ //new CPU.Jump { DestinationLabel = MethodFooterOp.EndOfMethodLabelNameNormal };
+ var methodInf = aMethod.MethodBase as System.Reflection.MethodInfo;
+ if (methodInf != null && methodInf.ReturnType != typeof (void))
+ {
+ Assembler.Stack.Pop();
+ }
+ }
}
- }
-}
+}
\ No newline at end of file
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/ILOpCode.cs b/source2/IL2CPU/Cosmos.IL2CPU/ILOpCode.cs
index 64e9a674e..2fee02648 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/ILOpCode.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/ILOpCode.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using SR = System.Reflection;
@@ -10,6 +11,7 @@ namespace Cosmos.IL2CPU {
// Include reference to ILOp, the scanner should do that
// Include referense to System.Reflection.Emit, this is metadata
// only needed by reader and not ILOpCode
+ //[DebuggerDisplay("IL_{Position}{:{OpCode}")]
public abstract class ILOpCode {
public enum Code : ushort {
@@ -258,5 +260,9 @@ namespace Cosmos.IL2CPU {
CurrentExceptionHandler = aCurrentExceptionHandler;
}
+ public override string ToString()
+ {
+ return String.Format("IL_{0}: {1}", Position.ToString("X4"), OpCode);
+ }
}
}
diff --git a/source2/IL2CPU/Cosmos.IL2CPU/ILScanner.cs b/source2/IL2CPU/Cosmos.IL2CPU/ILScanner.cs
index 422f5c217..bdb22cc44 100644
--- a/source2/IL2CPU/Cosmos.IL2CPU/ILScanner.cs
+++ b/source2/IL2CPU/Cosmos.IL2CPU/ILScanner.cs
@@ -16,36 +16,6 @@ namespace Cosmos.IL2CPU
{
public delegate void LogExceptionDelegate(Exception e);
- // This is necessary because HashSet and Dictionary
- // have troubles when different types of objects are stored
- // in them. I dont remember the exact problem, but something
- // with how it compares objects. ie when HashSet