mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 05:18:38 +00:00
This commit is contained in:
parent
491be780f8
commit
71ecc7cdf5
25 changed files with 85 additions and 69 deletions
|
|
@ -19,7 +19,15 @@ namespace HelloWorld {
|
|||
object x = "Hello, World!";
|
||||
}
|
||||
|
||||
public static void EmptyMethod() {
|
||||
}
|
||||
|
||||
public static void CallEmptyMethod() {
|
||||
EmptyMethod();
|
||||
}
|
||||
|
||||
public static void Main() {
|
||||
CallEmptyMethod();
|
||||
CallInteger();
|
||||
Integer();
|
||||
StringViaCtor();
|
||||
|
|
|
|||
|
|
@ -8,13 +8,17 @@ namespace IL2CPU {
|
|||
public class Program {
|
||||
public static void Main(string[] args) {
|
||||
try {
|
||||
string exeName = "HelloWorldMetal.exe";
|
||||
if(args.Length ==1 ) {
|
||||
exeName = args[0];
|
||||
}
|
||||
Engine e = new Engine();
|
||||
e.DebugLog += delegate(string aMessage) {
|
||||
Console.WriteLine(aMessage);
|
||||
};
|
||||
using (FileStream fs = new FileStream(@"output.asm", FileMode.Create)) {
|
||||
using (StreamWriter br = new StreamWriter(fs)) {
|
||||
e.Execute("HelloWorldMetal.exe", TargetPlatformEnum.x86, br);
|
||||
e.Execute(exeName, TargetPlatformEnum.x86, br);
|
||||
}
|
||||
}
|
||||
} catch (Exception E) {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,16 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Br_S)]
|
||||
public class Br_S: Op {
|
||||
private bool mIsFake;
|
||||
public Br_S(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
// next physical opcode is +2, because the opcode is singlebyte, and has a byte as param
|
||||
mIsFake = aInstruction.Next.Offset == (aInstruction.Offset + 2);
|
||||
}
|
||||
public override void Assemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
if (!mIsFake) {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public void Assemble(string aMethod) {
|
||||
Call(aMethod);
|
||||
if(HasResult) {
|
||||
Push("EAX");
|
||||
// Push("EAX");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,26 +7,29 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4)]
|
||||
public class Ldc_I4: Op {
|
||||
private int mOffset;
|
||||
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
|
||||
private string mValue;
|
||||
protected void SetValue(int aValue) {
|
||||
SetValue(aValue.ToString());
|
||||
}
|
||||
|
||||
protected void SetValue(string aValue) {
|
||||
mValue = aValue;
|
||||
}
|
||||
|
||||
public Ldc_I4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
int xLocalIndex;
|
||||
if(Int32.TryParse((aInstruction.Operand ?? "").ToString(), out xLocalIndex)) {
|
||||
SetLocalIndex(xLocalIndex, aMethodInfo);
|
||||
if(aInstruction.Operand != null) {
|
||||
SetValue(aInstruction.Operand.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
public string Value {
|
||||
get {
|
||||
return mOffset;
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
public override sealed void Assemble() {
|
||||
Pushd("[esp + " + mOffset + "]");
|
||||
Pushd(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public class Ldc_I4_0: Ldc_I4 {
|
||||
public Ldc_I4_0(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
SetLocalIndex(0, aMethodInfo);
|
||||
SetValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public class Ldc_I4_1: Ldc_I4 {
|
||||
public Ldc_I4_1(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
SetLocalIndex(1, aMethodInfo);
|
||||
SetValue(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_2)]
|
||||
public class Ldc_I4_2: Op {
|
||||
public class Ldc_I4_2: Ldc_I4 {
|
||||
public Ldc_I4_2(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!");
|
||||
SetValue(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_3)]
|
||||
public class Ldc_I4_3: Op {
|
||||
public class Ldc_I4_3: Ldc_I4 {
|
||||
public Ldc_I4_3(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!");
|
||||
SetValue(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_4)]
|
||||
public class Ldc_I4_4: Op {
|
||||
public class Ldc_I4_4: Ldc_I4 {
|
||||
public Ldc_I4_4(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!");
|
||||
SetValue(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_5)]
|
||||
public class Ldc_I4_5: Op {
|
||||
public class Ldc_I4_5: Ldc_I4 {
|
||||
public Ldc_I4_5(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!");
|
||||
SetValue(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_6)]
|
||||
public class Ldc_I4_6: Op {
|
||||
public class Ldc_I4_6: Ldc_I4 {
|
||||
public Ldc_I4_6(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!");
|
||||
SetValue(6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_7)]
|
||||
public class Ldc_I4_7: Op {
|
||||
public class Ldc_I4_7: Ldc_I4 {
|
||||
public Ldc_I4_7(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!");
|
||||
SetValue(7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_8)]
|
||||
public class Ldc_I4_8: Op {
|
||||
public class Ldc_I4_8: Ldc_I4 {
|
||||
public Ldc_I4_8(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!");
|
||||
SetValue(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_M1)]
|
||||
public class Ldc_I4_M1: Op {
|
||||
public class Ldc_I4_M1: Ldc_I4 {
|
||||
public Ldc_I4_M1(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!");
|
||||
SetValue(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,15 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ldc_I4_S)]
|
||||
public class Ldc_I4_S: Op {
|
||||
public readonly string Value;
|
||||
public class Ldc_I4_S: Ldc_I4 {
|
||||
public Ldc_I4_S(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
Value = (aInstruction.Operand ?? "").ToString();
|
||||
}
|
||||
|
||||
public override void Assemble() {
|
||||
Pushd(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public class Ldloc: Op {
|
||||
private int mOffset;
|
||||
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 8;
|
||||
}
|
||||
public Ldloc(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
|
|
@ -27,7 +27,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
|
||||
public sealed override void Assemble() {
|
||||
Push("eax");
|
||||
Move("eax", "[esp+" + mOffset + "]");
|
||||
Move("eax", "[ebp+" + mOffset + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public class Ldloca: Op {
|
||||
private int mOffset;
|
||||
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 84;
|
||||
}
|
||||
public Ldloca(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
|
|
@ -27,7 +27,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
|
||||
public sealed override void Assemble() {
|
||||
Push("eax");
|
||||
Move("eax", "[esp+" + mOffset + "]");
|
||||
Move("eax", "[ebp+" + mOffset + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
|
||||
public Newobj(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
CtorName = new Asm.Label(((MethodReference)aInstruction.Operand).Name).Name;
|
||||
CtorName = new Asm.Label((MethodReference)aInstruction.Operand).Name;
|
||||
}
|
||||
|
||||
public override void Assemble() {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,15 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Ret)]
|
||||
public class Ret: Op {
|
||||
private bool mHasReturn;
|
||||
public Ret(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
mHasReturn = aMethodInfo.HasReturnValue;
|
||||
}
|
||||
public override void Assemble() {
|
||||
//Ret();
|
||||
if (mHasReturn) {
|
||||
//Push("eax");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Stloc)]
|
||||
public class Stloc: Op {
|
||||
private int mOffset;
|
||||
private string mAddress;
|
||||
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
|
||||
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
|
||||
mAddress = aMethodInfo.Locals[aIndex].VirtualAddress;
|
||||
}
|
||||
public Stloc(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
|
|
@ -19,15 +19,15 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
public string Address {
|
||||
get {
|
||||
return mOffset;
|
||||
return mAddress;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void Assemble() {
|
||||
Pop("eax");
|
||||
Move("[esp+" + mOffset + "]", "eax");
|
||||
Move("[" + mAddress + "]", "eax");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public class X86MethodFooterOp: MethodFooterOp {
|
||||
public readonly int TotalLocalsSize = 0;
|
||||
public readonly int TotalArgsSize = 0;
|
||||
public readonly int LocalsCount = 0;
|
||||
public X86MethodFooterOp(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
if (aMethodInfo.Arguments.Length > 0) {
|
||||
|
|
@ -17,10 +18,18 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
if (aMethodInfo.Locals.Length > 0) {
|
||||
TotalLocalsSize += aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Offset + aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Size;
|
||||
}
|
||||
LocalsCount = aMethodInfo.Locals.Length;
|
||||
if(aMethodInfo.HasReturnValue) {
|
||||
TotalLocalsSize += 4;
|
||||
LocalsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Assemble() {
|
||||
Assembler.Add(new CPU.Add("esp", TotalLocalsSize.ToString()));
|
||||
for (int i = 0; i < LocalsCount; i++) {
|
||||
Assembler.Add(new CPU.Pop("ebp"));
|
||||
}
|
||||
Assembler.Add(new CPU.Ret(TotalArgsSize.ToString()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public override void Assemble() {
|
||||
// TODO: add support for variables with a diff datasize, other than 32bit
|
||||
Assembler.Add(new CPU.Label(LabelName));
|
||||
Assembler.Add(new CPUx86.Move("ebp", "esp"));
|
||||
for (int i = 0; i < LocalsCount; i++) {
|
||||
Assembler.Add(new CPUx86.Pushd(" 0"));
|
||||
Assembler.Add(new CPUx86.Pushd("ebp"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ namespace Indy.IL2CPU.IL {
|
|||
public Variable(int aOffset, int aSize) {
|
||||
Offset = aOffset;
|
||||
Size = aSize;
|
||||
VirtualAddress = "ebp + " + (Offset + Size + 8);
|
||||
}
|
||||
public readonly int Offset;
|
||||
public readonly int Size;
|
||||
public readonly string VirtualAddress;
|
||||
}
|
||||
|
||||
public struct Argument {
|
||||
|
|
@ -24,14 +26,16 @@ namespace Indy.IL2CPU.IL {
|
|||
public readonly int Offset;
|
||||
}
|
||||
|
||||
public MethodInformation(string aLabelName, Variable[] aLocals, Argument[] aArguments) {
|
||||
public MethodInformation(string aLabelName, Variable[] aLocals, Argument[] aArguments, bool aHasReturnValue) {
|
||||
Locals = aLocals;
|
||||
LabelName = aLabelName;
|
||||
Arguments = aArguments;
|
||||
HasReturnValue = aHasReturnValue;
|
||||
}
|
||||
|
||||
public readonly string LabelName;
|
||||
public readonly Variable[] Locals;
|
||||
public readonly Argument[] Arguments;
|
||||
public readonly bool HasReturnValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,9 +11,9 @@ using Mono.Cecil;
|
|||
using Mono.Cecil.Cil;
|
||||
using Instruction = Mono.Cecil.Cil.Instruction;
|
||||
|
||||
ERROR
|
||||
//ERROR
|
||||
|
||||
We need a special local vars register in the assembly
|
||||
//We need a special local vars register in the assembly
|
||||
|
||||
namespace Indy.IL2CPU {
|
||||
public class MethodDefinitionComparer: IComparer<MethodDefinition> {
|
||||
|
|
@ -122,7 +122,7 @@ namespace Indy.IL2CPU {
|
|||
xArgs[i] = new MethodInformation.Argument(xArgSize, xCurOffset);
|
||||
xCurOffset += xArgSize;
|
||||
}
|
||||
xMethodInfo = new MethodInformation(new Label(xCurrentMethod).Name, xVars, xArgs);
|
||||
xMethodInfo = new MethodInformation(new Label(xCurrentMethod).Name, xVars, xArgs, !xCurrentMethod.ReturnType.ReturnType.FullName.Contains("System.Void"));
|
||||
}
|
||||
IL.Op xOp = GetOpFromType(mMap.MethodHeaderOp, null, xMethodInfo);
|
||||
xOp.Assembler = mAssembler;
|
||||
|
|
|
|||
Loading…
Reference in a new issue