This commit is contained in:
mterwoord_cp 2007-09-15 09:11:04 +00:00
parent 1d2c88087a
commit 12e80eeba5
12 changed files with 68 additions and 42 deletions

View file

@ -16,8 +16,6 @@ namespace HelloWorldMetal {
static void Main() { static void Main() {
// Local variables are ok too, since they are stack based // 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 // String literals translate to ldstr - these would automatically be pulled out
// and put in the data section. String manipuation not permitted unless the actual // and put in the data section. String manipuation not permitted unless the actual
// bytes are modified directly. // bytes are modified directly.
@ -34,16 +32,20 @@ namespace HelloWorldMetal {
// around map replacement // around map replacement
// So the current test would be - declare a P/Invoke for writing to console in Win32 // So the current test would be - declare a P/Invoke for writing to console in Win32
// then call it below with "HelloWorld" // then call it below with "HelloWorld"
bool result = MessageBeep(0xFFFFFFFF); IntPtr xHandle = GetStdHandle(-11);
uint error = GetLastError(); // uint error = GetLastError();
// IntPtr xHandle = GetStdHandle(-11); uint xCharsWritten;
// uint xCharsWritten = 0; string theMessage = "Hello, World!";
// WriteConsole(xHandle, theMessage, 13, out xCharsWritten, IntPtr.Zero); WriteConsole(xHandle, theMessage, 13, out xCharsWritten, IntPtr.Zero);
// error = GetLastError(); //error = GetLastError();
} }
[DllImport("user32.dll")] [DllImport("kernel32.dll")]
private static extern bool MessageBeep(uint aType); 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")] [DllImport("kernel32.dll")]
private static extern uint GetLastError(); private static extern uint GetLastError();

View file

@ -15,15 +15,15 @@ section '.code' code readable executable
; IL: Nop ; IL: Nop
nop nop
; IL: Ldc_I4_0 ; IL: Ldc_I4_0
pushd 0 pushd 000000000h
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax
; IL: Ldc_I4_5 ; IL: Ldc_I4_5
pushd 5 pushd 000000005h
; IL: Call System.Int32 Program::DoEcho(System.Int32) ; IL: Call System.Int32 Program::DoEcho(System.Int32)
call System_Int32___Program_DoEcho___System_Int32___ call System_Int32___Program_DoEcho___System_Int32___
push EAX push eax
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax

View file

@ -16,7 +16,7 @@ section '.code' code readable executable
nop nop
; IL: Call System.Int32 Program::TheMethod() ; IL: Call System.Int32 Program::TheMethod()
call System_Int32___Program_TheMethod____ call System_Int32___Program_TheMethod____
push EAX push eax
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax
@ -30,7 +30,7 @@ section '.code' code readable executable
; IL: Nop ; IL: Nop
nop nop
; IL: Ldc_I4_5 ; IL: Ldc_I4_5
pushd 5 pushd 000000005h
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax

View file

@ -4,7 +4,7 @@ entry ___ENTRYPOINT___
section '.data' data readable writeable 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 section '.code' code readable executable
@ -22,26 +22,27 @@ section '.code' code readable executable
; IL: Nop ; IL: Nop
nop nop
; IL: Ldc_I4_0 ; IL: Ldc_I4_0
pushd 0 pushd 000000000h
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax
; IL: Ldstr Hello, World! ; IL: Ldstr Hello, World!
pushd StringLiteral00000000 mov eax,StringLiteral00000000
pushd eax
; IL: Stloc_1 ; IL: Stloc_1
pop eax pop eax
mov [esp - 16],eax mov [esp - 16],eax
; IL: Ldc_I4_M1 ; IL: Ldc_I4_M1
pushd -1 pushd 0FFFFFFFFh
; IL: Call System.Boolean SimplePInvokeTest.Program::MessageBeep(System.UInt32) ; IL: Call System.Boolean SimplePInvokeTest.Program::MessageBeep(System.UInt32)
call System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___ call System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___
push EAX push eax
; IL: Stloc_2 ; IL: Stloc_2
pop eax pop eax
mov [esp - 20],eax mov [esp - 20],eax
; IL: Call System.UInt32 SimplePInvokeTest.Program::GetLastError() ; IL: Call System.UInt32 SimplePInvokeTest.Program::GetLastError()
call System_UInt32___SimplePInvokeTest_Program_GetLastError____ call System_UInt32___SimplePInvokeTest_Program_GetLastError____
push EAX push eax
; IL: Stloc_3 ; IL: Stloc_3
pop eax pop eax
mov [esp - 24],eax mov [esp - 24],eax
@ -59,8 +60,8 @@ section '.code' code readable executable
System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___: System_Boolean___SimplePInvokeTest_Program_MessageBeep___System_UInt32___:
mov ebp,esp mov ebp,esp
push eax
mov eax,[ebp + 4] mov eax,[ebp + 4]
push eax
call [MessageBeep] call [MessageBeep]
ret 4 ret 4

View file

@ -15,7 +15,7 @@ section '.code' code readable executable
; IL: Nop ; IL: Nop
nop nop
; IL: Ldc_I4_5 ; IL: Ldc_I4_5
pushd 5 pushd 000000005h
; IL: Stloc_0 ; IL: Stloc_0
pop eax pop eax
mov [esp - 12],eax mov [esp - 12],eax

View file

@ -14,7 +14,7 @@ section '.code' code readable executable
; IL: Nop ; IL: Nop
nop nop
; IL: Ldc_I4_2 ; IL: Ldc_I4_2
pushd 2 pushd 000000002h
; IL: Call System.Void Program::TheMethod(System.Int32) ; IL: Call System.Void Program::TheMethod(System.Int32)
call System_Void___Program_TheMethod___System_Int32___ call System_Void___Program_TheMethod___System_Int32___
; IL: Nop ; IL: Nop

View file

@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 {
public void Assemble(string aMethod) { public void Assemble(string aMethod) {
Call(aMethod); Call(aMethod);
if (HasResult) { if (HasResult) {
Push(Assembler, "EAX"); Push(Assembler, "eax");
} }
} }

View file

@ -6,12 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Callvirt, false)] [OpCode(Code.Callvirt, false)]
public class Callvirt: Op { public class Callvirt: Call {
public Callvirt(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Callvirt(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
}
} }
} }

View file

@ -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 // 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"); string xDataName = Assembler.GetIdentifier("StringLiteral");
var xDataByteArray = new StringBuilder(); 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(x.ToString());
xDataByteArray.Append(","); xDataByteArray.Append(",");
} }
xDataByteArray.Append("0,");
Assembler.DataMembers.Add(new DataMember(xDataName, "db", xDataByteArray.ToString().TrimEnd(','))); Assembler.DataMembers.Add(new DataMember(xDataName, "db", xDataByteArray.ToString().TrimEnd(',')));
Pushd(xDataName); Move(Assembler, "eax", xDataName);
Pushd("eax");
// new Newobj() { // new Newobj() {
// CtorName = (new Label(typeof(String).FullName, typeof(Char).FullName + "*")).Name, // CtorName = (new Label(typeof(String).FullName, typeof(Char).FullName + "*")).Name,
// Assembler = Assembler // Assembler = Assembler

View file

@ -7,29 +7,29 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4)] [OpCode(Code.Ldc_I4)]
public class Ldc_I4: Op { public class Ldc_I4: Op {
private string mValue; private int mValue;
protected void SetValue(int aValue) { protected void SetValue(int aValue) {
SetValue(aValue.ToString()); mValue = aValue;
} }
protected void SetValue(string aValue) { protected void SetValue(string aValue) {
mValue = aValue; SetValue(Int32.Parse(aValue));
} }
public Ldc_I4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Ldc_I4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
if(aInstruction.Operand != null) { if (aInstruction.Operand != null) {
SetValue(aInstruction.Operand.ToString()); SetValue(aInstruction.Operand.ToString());
} }
} }
public string Value { public int Value {
get { get {
return mValue; return mValue;
} }
} }
public override sealed void Assemble() { public override sealed void Assemble() {
Pushd(Value); Pushd("0" + mValue.ToString("X8") + "h");
} }
} }
} }

View file

@ -44,7 +44,7 @@ namespace Indy.IL2CPU.IL.X86 {
if (TheMethod.PInvokeInfo.IsCharSetNotSpec) { if (TheMethod.PInvokeInfo.IsCharSetNotSpec) {
foreach (ParameterDefinition xParam in TheMethod.Parameters) { foreach (ParameterDefinition xParam in TheMethod.Parameters) {
if (xParam.ParameterType.FullName.StartsWith("System.String")) { if (xParam.ParameterType.FullName.StartsWith("System.String")) {
xMethodName += "W"; xMethodName += "A";
break; break;
} }
} }
@ -53,8 +53,11 @@ namespace Indy.IL2CPU.IL.X86 {
throw new Exception("Unable to determine what dll to use!"); throw new Exception("Unable to determine what dll to use!");
} }
MakeSureMethodIsRegistered(xDllName, xDllFileName, xMethodName); MakeSureMethodIsRegistered(xDllName, xDllFileName, xMethodName);
for (int i = MethodInfo.Arguments.Length - 1; i >= 0; i--) { // for (int i = MethodInfo.Arguments.Length - 1; i >= 0; i--) {
Op.Ldarg(Assembler, MethodInfo.Arguments[i].VirtualAddress); 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 + "]")); Assembler.Add(new CPUx86.Call("[" + xMethodName + "]"));
// if (MethodInfo.HasReturnValue) { // if (MethodInfo.HasReturnValue) {

View file

@ -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.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -88,7 +91,7 @@ namespace Indy.IL2CPU {
// first instructions are for calling the entrypoint // first instructions are for calling the entrypoint
mAssembler.Add(new Assembler.X86.Call(new Label(mCrawledAssembly.EntryPoint).Name)); mAssembler.Add(new Assembler.X86.Call(new Label(mCrawledAssembly.EntryPoint).Name));
if (mCrawledAssembly.EntryPoint.ReturnType.ReturnType.FullName.StartsWith("System.Void", StringComparison.InvariantCultureIgnoreCase)) { 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]")); mAssembler.Add(new Assembler.X86.Call("[ExitProcess]"));
ImportMember xKernel32 = new ImportMember("kernel32_dll", "kernel32.dll"); ImportMember xKernel32 = new ImportMember("kernel32_dll", "kernel32.dll");
@ -134,6 +137,24 @@ namespace Indy.IL2CPU {
} }
IL.Op xOp = GetOpFromType(mMap.MethodHeaderOp, null, xMethodInfo); IL.Op xOp = GetOpFromType(mMap.MethodHeaderOp, null, xMethodInfo);
xOp.Assembler = mAssembler; 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(); xOp.Assemble();
// what to do if a method doesn't have a body? // what to do if a method doesn't have a body?
if (xCurrentMethod.HasBody) { if (xCurrentMethod.HasBody) {