From 12e80eeba56306e90cfeebd9aa2372b80ace8fa6 Mon Sep 17 00:00:00 2001 From: mterwoord_cp <7cd3fd84a0151ea055c2f79e4d2eef9576fe9afesxUZAwxD> Date: Sat, 15 Sep 2007 09:11:04 +0000 Subject: [PATCH] --- source/HelloWorldMetal/Program.cs | 22 ++++++++-------- .../SimpleEchoFunction.expected.asm | 6 ++--- .../SimpleFunctionCall.expected.asm | 4 +-- .../SimplePInvokeTest.expected.asm | 15 +++++------ .../Tests/SimpleVar/SimpleVar.expected.asm | 2 +- .../SingleMethodWithParam.expected.asm | 2 +- source/Indy.IL2CPU.IL.X86/Call.cs | 2 +- source/Indy.IL2CPU.IL.X86/Callvirt.cs | 5 +--- source/Indy.IL2CPU.IL.X86/LdStr.cs | 6 +++-- source/Indy.IL2CPU.IL.X86/Ldc_I4.cs | 12 ++++----- .../X86PInvokeMethodBodyOp.cs | 9 ++++--- source/Indy.IL2CPU/Engine.cs | 25 +++++++++++++++++-- 12 files changed, 68 insertions(+), 42 deletions(-) diff --git a/source/HelloWorldMetal/Program.cs b/source/HelloWorldMetal/Program.cs index 1be8eda80..005b953b8 100644 --- a/source/HelloWorldMetal/Program.cs +++ b/source/HelloWorldMetal/Program.cs @@ -16,8 +16,6 @@ namespace HelloWorldMetal { static void Main() { // Local variables are ok too, since they are stack based - int i = 0; - string theMessage = "Hello, World!"; // String literals translate to ldstr - these would automatically be pulled out // and put in the data section. String manipuation not permitted unless the actual // bytes are modified directly. @@ -34,16 +32,20 @@ namespace HelloWorldMetal { // around map replacement // So the current test would be - declare a P/Invoke for writing to console in Win32 // then call it below with "HelloWorld" - bool result = MessageBeep(0xFFFFFFFF); - uint error = GetLastError(); -// IntPtr xHandle = GetStdHandle(-11); -// uint xCharsWritten = 0; -// WriteConsole(xHandle, theMessage, 13, out xCharsWritten, IntPtr.Zero); -// error = GetLastError(); + IntPtr xHandle = GetStdHandle(-11); +// uint error = GetLastError(); + uint xCharsWritten; + string theMessage = "Hello, World!"; + WriteConsole(xHandle, theMessage, 13, out xCharsWritten, IntPtr.Zero); + //error = GetLastError(); } - [DllImport("user32.dll")] - private static extern bool MessageBeep(uint aType); + [DllImport("kernel32.dll")] + static extern IntPtr GetStdHandle(int nStdHandle); + [DllImport("kernel32.dll")] + static extern bool WriteConsole(IntPtr hConsoleOutput, string lpBuffer, + uint nNumberOfCharsToWrite, out uint lpNumberOfCharsWritten, + IntPtr lpReserved); [DllImport("kernel32.dll")] private static extern uint GetLastError(); diff --git a/source/IL2CPU.Tests/Tests/SimpleEchoFunction/SimpleEchoFunction.expected.asm b/source/IL2CPU.Tests/Tests/SimpleEchoFunction/SimpleEchoFunction.expected.asm index 33ec8dcfb..5950deba2 100644 --- a/source/IL2CPU.Tests/Tests/SimpleEchoFunction/SimpleEchoFunction.expected.asm +++ b/source/IL2CPU.Tests/Tests/SimpleEchoFunction/SimpleEchoFunction.expected.asm @@ -15,15 +15,15 @@ section '.code' code readable executable ; IL: Nop nop ; IL: Ldc_I4_0 - pushd 0 + pushd 000000000h ; IL: Stloc_0 pop eax mov [esp - 12],eax ; IL: Ldc_I4_5 - pushd 5 + pushd 000000005h ; IL: Call System.Int32 Program::DoEcho(System.Int32) call System_Int32___Program_DoEcho___System_Int32___ - push EAX + push eax ; IL: Stloc_0 pop eax mov [esp - 12],eax diff --git a/source/IL2CPU.Tests/Tests/SimpleFunctionCall/SimpleFunctionCall.expected.asm b/source/IL2CPU.Tests/Tests/SimpleFunctionCall/SimpleFunctionCall.expected.asm index 7604e7139..b2eeb8e41 100644 --- a/source/IL2CPU.Tests/Tests/SimpleFunctionCall/SimpleFunctionCall.expected.asm +++ b/source/IL2CPU.Tests/Tests/SimpleFunctionCall/SimpleFunctionCall.expected.asm @@ -16,7 +16,7 @@ section '.code' code readable executable nop ; IL: Call System.Int32 Program::TheMethod() call System_Int32___Program_TheMethod____ - push EAX + push eax ; IL: Stloc_0 pop eax mov [esp - 12],eax @@ -30,7 +30,7 @@ section '.code' code readable executable ; IL: Nop nop ; IL: Ldc_I4_5 - pushd 5 + pushd 000000005h ; IL: Stloc_0 pop eax mov [esp - 12],eax diff --git a/source/IL2CPU.Tests/Tests/SimplePInvoke/SimplePInvokeTest.expected.asm b/source/IL2CPU.Tests/Tests/SimplePInvoke/SimplePInvokeTest.expected.asm index 02a4218d8..e19ead72f 100644 --- a/source/IL2CPU.Tests/Tests/SimplePInvoke/SimplePInvokeTest.expected.asm +++ b/source/IL2CPU.Tests/Tests/SimplePInvoke/SimplePInvokeTest.expected.asm @@ -4,7 +4,7 @@ entry ___ENTRYPOINT___ section '.data' data readable writeable - StringLiteral00000000 db 72,0,101,0,108,0,108,0,111,0,44,0,32,0,87,0,111,0,114,0,108,0,100,0,33,0 + StringLiteral00000000 db 72,101,108,108,111,44,32,87,111,114,108,100,33,0 section '.code' code readable executable @@ -22,26 +22,27 @@ section '.code' code readable executable ; IL: Nop nop ; IL: Ldc_I4_0 - pushd 0 + pushd 000000000h ; IL: Stloc_0 pop eax mov [esp - 12],eax ; IL: Ldstr Hello, World! - pushd StringLiteral00000000 + mov eax,StringLiteral00000000 + pushd eax ; IL: Stloc_1 pop eax mov [esp - 16],eax ; IL: Ldc_I4_M1 - pushd -1 + pushd 0FFFFFFFFh ; IL: Call System.Boolean SimplePInvokeTest.Program::MessageBeep(System.UInt32) call System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___ - push EAX + push eax ; IL: Stloc_2 pop eax mov [esp - 20],eax ; IL: Call System.UInt32 SimplePInvokeTest.Program::GetLastError() call System_UInt32___SimplePInvokeTest_Program_GetLastError____ - push EAX + push eax ; IL: Stloc_3 pop eax mov [esp - 24],eax @@ -59,8 +60,8 @@ section '.code' code readable executable System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___: mov ebp,esp - push eax mov eax,[ebp + 4] + push eax call [MessageBeep] ret 4 diff --git a/source/IL2CPU.Tests/Tests/SimpleVar/SimpleVar.expected.asm b/source/IL2CPU.Tests/Tests/SimpleVar/SimpleVar.expected.asm index a43b5471f..15b091b05 100644 --- a/source/IL2CPU.Tests/Tests/SimpleVar/SimpleVar.expected.asm +++ b/source/IL2CPU.Tests/Tests/SimpleVar/SimpleVar.expected.asm @@ -15,7 +15,7 @@ section '.code' code readable executable ; IL: Nop nop ; IL: Ldc_I4_5 - pushd 5 + pushd 000000005h ; IL: Stloc_0 pop eax mov [esp - 12],eax diff --git a/source/IL2CPU.Tests/Tests/SingleMethodWithParam/SingleMethodWithParam.expected.asm b/source/IL2CPU.Tests/Tests/SingleMethodWithParam/SingleMethodWithParam.expected.asm index 5663ba482..bd921b7b2 100644 --- a/source/IL2CPU.Tests/Tests/SingleMethodWithParam/SingleMethodWithParam.expected.asm +++ b/source/IL2CPU.Tests/Tests/SingleMethodWithParam/SingleMethodWithParam.expected.asm @@ -14,7 +14,7 @@ section '.code' code readable executable ; IL: Nop nop ; IL: Ldc_I4_2 - pushd 2 + pushd 000000002h ; IL: Call System.Void Program::TheMethod(System.Int32) call System_Void___Program_TheMethod___System_Int32___ ; IL: Nop diff --git a/source/Indy.IL2CPU.IL.X86/Call.cs b/source/Indy.IL2CPU.IL.X86/Call.cs index 3ec963afb..fef82dde2 100644 --- a/source/Indy.IL2CPU.IL.X86/Call.cs +++ b/source/Indy.IL2CPU.IL.X86/Call.cs @@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 { public void Assemble(string aMethod) { Call(aMethod); if (HasResult) { - Push(Assembler, "EAX"); + Push(Assembler, "eax"); } } diff --git a/source/Indy.IL2CPU.IL.X86/Callvirt.cs b/source/Indy.IL2CPU.IL.X86/Callvirt.cs index fc1d2e9ec..b7bc6dcd8 100644 --- a/source/Indy.IL2CPU.IL.X86/Callvirt.cs +++ b/source/Indy.IL2CPU.IL.X86/Callvirt.cs @@ -6,12 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Callvirt, false)] - public class Callvirt: Op { + public class Callvirt: Call { public Callvirt(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { } - public override void Assemble() { - throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); - } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/LdStr.cs b/source/Indy.IL2CPU.IL.X86/LdStr.cs index a84761f0c..65571761b 100644 --- a/source/Indy.IL2CPU.IL.X86/LdStr.cs +++ b/source/Indy.IL2CPU.IL.X86/LdStr.cs @@ -22,12 +22,14 @@ namespace Indy.IL2CPU.IL.X86 { // todo: see if we need to output trailing bytes 00 00 or 00 01 depending on whether there are bytes >7F string xDataName = Assembler.GetIdentifier("StringLiteral"); var xDataByteArray = new StringBuilder(); - foreach (byte x in Encoding.Unicode.GetBytes(LiteralStr)) { + foreach (byte x in Encoding.ASCII.GetBytes(LiteralStr)) { xDataByteArray.Append(x.ToString()); xDataByteArray.Append(","); } + xDataByteArray.Append("0,"); Assembler.DataMembers.Add(new DataMember(xDataName, "db", xDataByteArray.ToString().TrimEnd(','))); - Pushd(xDataName); + Move(Assembler, "eax", xDataName); + Pushd("eax"); // new Newobj() { // CtorName = (new Label(typeof(String).FullName, typeof(Char).FullName + "*")).Name, // Assembler = Assembler diff --git a/source/Indy.IL2CPU.IL.X86/Ldc_I4.cs b/source/Indy.IL2CPU.IL.X86/Ldc_I4.cs index 95a33a6cd..2e9e8cf41 100644 --- a/source/Indy.IL2CPU.IL.X86/Ldc_I4.cs +++ b/source/Indy.IL2CPU.IL.X86/Ldc_I4.cs @@ -7,29 +7,29 @@ using CPU = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Ldc_I4)] public class Ldc_I4: Op { - private string mValue; + private int mValue; protected void SetValue(int aValue) { - SetValue(aValue.ToString()); + mValue = aValue; } protected void SetValue(string aValue) { - mValue = aValue; + SetValue(Int32.Parse(aValue)); } public Ldc_I4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { - if(aInstruction.Operand != null) { + if (aInstruction.Operand != null) { SetValue(aInstruction.Operand.ToString()); } } - public string Value { + public int Value { get { return mValue; } } public override sealed void Assemble() { - Pushd(Value); + Pushd("0" + mValue.ToString("X8") + "h"); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs b/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs index fbc6bde5a..79cce8148 100644 --- a/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs @@ -44,7 +44,7 @@ namespace Indy.IL2CPU.IL.X86 { if (TheMethod.PInvokeInfo.IsCharSetNotSpec) { foreach (ParameterDefinition xParam in TheMethod.Parameters) { if (xParam.ParameterType.FullName.StartsWith("System.String")) { - xMethodName += "W"; + xMethodName += "A"; break; } } @@ -53,8 +53,11 @@ namespace Indy.IL2CPU.IL.X86 { throw new Exception("Unable to determine what dll to use!"); } MakeSureMethodIsRegistered(xDllName, xDllFileName, xMethodName); - for (int i = MethodInfo.Arguments.Length - 1; i >= 0; i--) { - Op.Ldarg(Assembler, MethodInfo.Arguments[i].VirtualAddress); +// for (int i = MethodInfo.Arguments.Length - 1; i >= 0; i--) { + for(int i =0;i< MethodInfo.Arguments.Length;i++){ + Op.Move(Assembler, "eax", "[" + MethodInfo.Arguments[i].VirtualAddress + "]"); + Op.Push(Assembler, "eax"); + //Op.Ldarg(Assembler, MethodInfo.Arguments[i].VirtualAddress); } Assembler.Add(new CPUx86.Call("[" + xMethodName + "]")); // if (MethodInfo.HasReturnValue) { diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs index e95989f3d..2e68a7b8b 100644 --- a/source/Indy.IL2CPU/Engine.cs +++ b/source/Indy.IL2CPU/Engine.cs @@ -1,4 +1,7 @@ -using System; +// this file supports the VERBOSE_DEBUG define. this makes it emit a bunch of comments in the assembler output. +// note that the tests are supposed to NOT include these comments +// #define VERBOSE_DEBUG +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -88,7 +91,7 @@ namespace Indy.IL2CPU { // first instructions are for calling the entrypoint mAssembler.Add(new Assembler.X86.Call(new Label(mCrawledAssembly.EntryPoint).Name)); if (mCrawledAssembly.EntryPoint.ReturnType.ReturnType.FullName.StartsWith("System.Void", StringComparison.InvariantCultureIgnoreCase)) { - mAssembler.Add(new Assembler.X86.Pushd("0")); + mAssembler.Add(new Pushd("0")); } mAssembler.Add(new Assembler.X86.Call("[ExitProcess]")); ImportMember xKernel32 = new ImportMember("kernel32_dll", "kernel32.dll"); @@ -134,6 +137,24 @@ namespace Indy.IL2CPU { } IL.Op xOp = GetOpFromType(mMap.MethodHeaderOp, null, xMethodInfo); xOp.Assembler = mAssembler; +#if VERBOSE_DEBUG + string comment = "Method: " + xCurrentMethod + "\r\n"; + if (xCurrentMethod.Body == null) { + comment += " (No locals)\r\n"; + } else { + comment += " Locals:\r\n"; + foreach (VariableDefinition xVarDef in xCurrentMethod.Body.Variables) { + comment += String.Format(" [{0}] {1}\r\n", xVarDef.Index, xVarDef.Name); + } + } + comment += " Args:\r\n"; + foreach (ParameterDefinition xParamDef in xCurrentMethod.Parameters) { + comment += String.Format(" [{0}] {1}\r\n", xParamDef.Sequence, xParamDef.Name); + } + foreach (string s in comment.Trim().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) { + mAssembler.Add(new Literal(";" + s)); + } +#endif xOp.Assemble(); // what to do if a method doesn't have a body? if (xCurrentMethod.HasBody) {