mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +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() {
|
||||
// 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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public void Assemble(string aMethod) {
|
||||
Call(aMethod);
|
||||
if (HasResult) {
|
||||
Push(Assembler, "EAX");
|
||||
Push(Assembler, "eax");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue