mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +00:00
This commit is contained in:
parent
1d2c88087a
commit
12e80eeba5
12 changed files with 68 additions and 42 deletions
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue