From dc9165e7a15b99b45d723ccba61a447f844d8253 Mon Sep 17 00:00:00 2001 From: kudzu_cp <6d05c8c8ef5431987001abfdb2eadc9593ac9498> Date: Tue, 8 Sep 2009 21:53:19 +0000 Subject: [PATCH] Fixed position labels for new assembler. --- .../IL2PCU/Cosmos.IL2CPU.X86/AssemblerNasm.cs | 16 +++++++++---- source2/IL2PCU/Cosmos.IL2CPU.X86/IL/Switch.cs | 6 +++-- .../Cosmos.IL2CPU/Assembler/Assembler.cs | 8 ++++++- source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs | 24 ++++++++++++++++++- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/source2/IL2PCU/Cosmos.IL2CPU.X86/AssemblerNasm.cs b/source2/IL2PCU/Cosmos.IL2CPU.X86/AssemblerNasm.cs index 48ec82bc5..59a7b4404 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU.X86/AssemblerNasm.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU.X86/AssemblerNasm.cs @@ -22,16 +22,24 @@ namespace Cosmos.IL2CPU.X86 { base.MethodEnd(aMethod); } + protected override void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode) { + base.BeforeOp(aMethod, aOpCode); + new Label(TmpPosLabel(aMethod, aOpCode)); + } + // These are all temp functions until we move to the new assembler. // They are used to clean up the old assembler slightly while retaining compatibiltiy for now - public static string TmpPosLabel(MethodInfo aMethod, ILOpCode aOpCode) { + public static string TmpPosLabel(MethodInfo aMethod, int xOffset) { //TODO: Change to Hex output, will be smaller and slightly faster for NASM - return "_" + aMethod.UID + "_" + aOpCode.Position + "__"; + return "POS_" + aMethod.UID + "_" + xOffset; + } + + public static string TmpPosLabel(MethodInfo aMethod, ILOpCode aOpCode) { + return TmpPosLabel(aMethod, aOpCode.Position); } public static string TmpBranchLabel(MethodInfo aMethod, ILOpCode aOpCode) { - //TODO: Change to Hex output, will be smaller and slightly faster for NASM - return "_" + aMethod.UID + "_" + ((ILOpCodes.OpBranch)aOpCode).Value + "__"; + return TmpPosLabel(aMethod, ((ILOpCodes.OpBranch)aOpCode).Value); } } diff --git a/source2/IL2PCU/Cosmos.IL2CPU.X86/IL/Switch.cs b/source2/IL2PCU/Cosmos.IL2CPU.X86/IL/Switch.cs index b34408514..039979ec5 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU.X86/IL/Switch.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU.X86/IL/Switch.cs @@ -19,8 +19,10 @@ namespace Cosmos.IL2CPU.X86.IL { new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceValue = ( uint )i }; //string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) ); - //string DestLabel = "_" + aMethod.UID + "_" + OpSw.BranchLocations[ i ] + "__"; - new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = "_" + aMethod.UID + "_" + OpSw.BranchLocations[ i ] + "__" }; + string xDestLabel = AssemblerNasm.TmpPosLabel(aMethod, OpSw.BranchLocations[i]); + new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal + , DestinationLabel = xDestLabel + }; } Assembler.Stack.Pop(); } diff --git a/source2/IL2PCU/Cosmos.IL2CPU/Assembler/Assembler.cs b/source2/IL2PCU/Cosmos.IL2CPU/Assembler/Assembler.cs index ca03fc11a..83d8a8e3b 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/Assembler/Assembler.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU/Assembler/Assembler.cs @@ -107,7 +107,9 @@ namespace Cosmos.IL2CPU { protected virtual void MethodBegin(MethodInfo aMethod) { new Comment(this, "---------------------------------------------------------"); - new Comment(this, "Begin Method: " + aMethod.MethodBase.Name); + new Comment(this, "Type: " + aMethod.MethodBase.DeclaringType.ToString()); + new Comment(this, "Name: " + aMethod.MethodBase.Name); + new Comment(this, "Plugged: " + (aMethod.PlugMethod == null ? "No" : "Yes")); } protected virtual void MethodEnd(MethodInfo aMethod) { @@ -139,6 +141,7 @@ namespace Cosmos.IL2CPU { } //mLog.Write ( "[" + xILOp.ToString() + "] \t Stack start: " + Stack.Count.ToString() ); new Comment(this, "[" + xILOp.ToString() + "]"); + BeforeOp(aMethod, xOpCode); xILOp.Execute(aMethod, xOpCode); //mLog.WriteLine( " end: " + Stack.Count.ToString() ); //mLog.Flush(); @@ -146,6 +149,9 @@ namespace Cosmos.IL2CPU { MethodEnd(aMethod); } + protected virtual void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode) { + } + /// /// allows to emit footers to the code and datamember sections /// diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs index a113df69c..c1c803928 100644 --- a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs +++ b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs @@ -50,6 +50,7 @@ namespace Cosmos.IL2CPU { public ILScanner(Assembler aAsmblr) { mAsmblr = aAsmblr; mReader = new ILReader(); + mThrowHelper = typeof(object).Assembly.GetType("System.ThrowHelper"); } public void Execute(System.Reflection.MethodInfo aStartMethod) { @@ -273,10 +274,29 @@ namespace Cosmos.IL2CPU { } // Assemble the method - mAsmblr.ProcessMethod(aMethodInfo, xOpCodes); + if (aMethodInfo.MethodBase.DeclaringType != mThrowHelper) { + mAsmblr.ProcessMethod(aMethodInfo, xOpCodes); + } } } + // System.ThrowHelper exists in MS .NET twice... + // Its an internal class that exists in both mscorlib and system assemblies. + // They are separate types though, so normally the scanner scans both and + // then we get conflicting labels. MS included it twice to make exception + // throwing code smaller. They are internal though, so we cannot + // reference them directly and only via finding them as they come along. + // We find it here, not via QueueType so we only check it here. Later + // we might have to checkin QueueType also. + // For now we accept both types, and just emit code for only one. This works + // with the current Nasm assembler as we resolve by name in the assembler. + // However with other assemblers this approach may not work. + // If AssemblerNASM adds assembly name to the label, this will allow + // both to exist as they do in BCL. + // So in the future we might be able to remove this hack, or change + // how it works. + private Type mThrowHelper; + public uint QueueMethod(MethodBase aMethodBase, bool aIsPlug) { uint xResult; @@ -346,6 +366,8 @@ namespace Cosmos.IL2CPU { QueueType(aType.BaseType); } // queue static constructor + //TODO: Should QueueMethod call QueueType with DeclaringType + // so its static constructors will get added? foreach (var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) { if (xCctor.DeclaringType == aType) { QueueMethod(xCctor, false);