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() {
// 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();

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 {
public void Assemble(string aMethod) {
Call(aMethod);
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 {
[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!");
}
}
}

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
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

View file

@ -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");
}
}
}

View file

@ -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) {

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.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) {