mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-10 18:21:20 +00:00
Fixed stack corruption
This commit is contained in:
parent
53f365b8a9
commit
e32bca76e9
32 changed files with 223 additions and 190 deletions
|
|
@ -90,21 +90,23 @@ namespace Cosmos.Hardware {
|
|||
}
|
||||
|
||||
public static unsafe void HandleInterrupt_00(InterruptContext* aContext) {
|
||||
HandleException(aContext->EIP, "Divide by zero", "EDivideByZero");
|
||||
HandleException(aContext->EIP, "Divide by zero", "EDivideByZero", aContext->EBP);
|
||||
}
|
||||
|
||||
public static unsafe void HandleInterrupt_06(InterruptContext* aContext) {
|
||||
HandleException(aContext->EIP, "Invalid Opcode", "EInvalidOpcode");
|
||||
HandleException(aContext->EIP, "Invalid Opcode", "EInvalidOpcode", aContext->EBP);
|
||||
}
|
||||
|
||||
public static unsafe void HandleInterrupt_0D(InterruptContext* aContext) {
|
||||
HandleException(aContext->EIP, "General Protection Fault", "GPF");
|
||||
HandleException(aContext->EIP, "General Protection Fault", "GPF", aContext->EBP);
|
||||
}
|
||||
|
||||
private static void HandleException(uint aEIP, string aDescription, string aName) {
|
||||
private static void HandleException(uint aEIP, string aDescription, string aName, uint aEBP) {
|
||||
Console.Write(aDescription);
|
||||
Console.Write(" at ");
|
||||
WriteNumber(aEIP, 32);
|
||||
Console.Write(" (EBP = ");
|
||||
Console.Write(aEBP.ToString());
|
||||
DebugUtil.SendMessage("Exceptions", aName);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("--System Halted!");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace Cosmos.Hardware {
|
|||
public class PIT: Hardware {
|
||||
public const int TicksPerSecond = 1000;
|
||||
public static void SetDivisor(ushort aDivisor) {
|
||||
IOWriteByte(0x43, 0x30);
|
||||
IOWriteByte(0x43, 0x36);
|
||||
IOWriteByte(0x40, (byte)(aDivisor & 0xFF));
|
||||
IOWriteByte(0x40, (byte)(aDivisor >> 8));
|
||||
}
|
||||
|
|
@ -18,7 +18,8 @@ namespace Cosmos.Hardware {
|
|||
|
||||
public static void Initialize(EventHandler aTick) {
|
||||
mTick = aTick;
|
||||
SetInterval(1193);
|
||||
SetInterval(1);
|
||||
//SetInterval(1193);
|
||||
}
|
||||
|
||||
private static EventHandler mTick;
|
||||
|
|
|
|||
|
|
@ -37,13 +37,17 @@ namespace Cosmos.Kernel.Plugs {
|
|||
return TextScreen.CurrentChar;
|
||||
}
|
||||
|
||||
public static int get_CursorTop() {
|
||||
return TextScreen.CurrentLine;
|
||||
}
|
||||
|
||||
public static void set_CursorLeft(int x)
|
||||
{
|
||||
TextScreen.CurrentChar = x;
|
||||
}
|
||||
|
||||
public static int get_CursorTop(int y) {
|
||||
return TextScreen.CurrentLine;
|
||||
public static void set_CursorTop(int y) {
|
||||
TextScreen.CurrentLine = y;
|
||||
}
|
||||
|
||||
public static int get_WindowHeight() {
|
||||
|
|
@ -54,10 +58,6 @@ namespace Cosmos.Kernel.Plugs {
|
|||
return TextScreen.WindowWidth;
|
||||
}
|
||||
|
||||
public static void set_CursorTop(int y) {
|
||||
TextScreen.CurrentLine = y;
|
||||
}
|
||||
|
||||
//TODO: Console uses TextWriter - intercept and plug it instead
|
||||
public static void Clear() {
|
||||
TextScreen.Clear();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace Cosmos.Kernel {
|
|||
Console.WriteLine("Done");
|
||||
Console.Write("Creating IDT...");
|
||||
Kernel.Interrupts.DoTest();
|
||||
Hardware.Storage.ATA.Initialize(Sleep);
|
||||
Hardware.CPU.CreateIDT();
|
||||
Console.WriteLine("Done");
|
||||
Keyboard.Initialize();
|
||||
|
|
@ -58,11 +59,11 @@ namespace Cosmos.Kernel {
|
|||
}
|
||||
|
||||
public static void Sleep(uint aMSec) {
|
||||
uint xEnd = TickCount + aMSec;
|
||||
while (TickCount < xEnd)
|
||||
uint xStart = TickCount;
|
||||
uint xEnd = xStart + aMSec;
|
||||
while (TickCount < xEnd) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ namespace Cosmos.Kernel.FileSystem {
|
|||
}
|
||||
|
||||
private bool ReadSuperBlock() {
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
ushort* xBuffer = (ushort*)Heap.MemAlloc(mBackend.BlockSize);
|
||||
if (!mBackend.ReadBlock(2, (byte*)xBuffer)) {
|
||||
Console.WriteLine("[Ext2|SuperBlock] Error while reading SuperBlock data");
|
||||
|
|
@ -253,11 +254,7 @@ namespace Cosmos.Kernel.FileSystem {
|
|||
bool xCurrentINodeChanged = true;
|
||||
uint xInspectedINodeCount = 0;
|
||||
for (int i = 0; i < xPath.Length; i++) {
|
||||
Console.Write("ReadFile, Iteration ");
|
||||
ATAOld.WriteNumber((uint)i, 8);
|
||||
Console.WriteLine("");
|
||||
if (!xCurrentINodeChanged) {
|
||||
Console.WriteLine("Terminating for loop, CurrentINode didn't change");
|
||||
Heap.MemFree((uint)xBuffer);
|
||||
Heap.MemFree((uint)xExt2BlockBuffer);
|
||||
return null;
|
||||
|
|
@ -294,13 +291,8 @@ namespace Cosmos.Kernel.FileSystem {
|
|||
xEntryPtr = (DirectoryEntry*)xPtrAddress;
|
||||
}
|
||||
}
|
||||
if (xCurrentINodeChanged) {
|
||||
DebugUtil.SendMessage("Ext2", "ReadFile, for loop exited with an inode change");
|
||||
} else {
|
||||
DebugUtil.SendMessage("Ext2", "ReadFile, for loop exited without an inode change");
|
||||
}
|
||||
if ((xCurrentINode.Mode & INodeModeEnum.RegularFile) == 0) {
|
||||
Console.WriteLine("No file after for loop");
|
||||
// Console.WriteLine("No file after for loop");
|
||||
return null;
|
||||
}
|
||||
byte[] xResult;//= new byte[mBlockSize];
|
||||
|
|
@ -516,6 +508,7 @@ namespace Cosmos.Kernel.FileSystem {
|
|||
ushort* xBuffer = (ushort*)Heap.MemAlloc(mBackend.BlockSize);
|
||||
byte* xExt2BlockBuffer = (byte*)Heap.MemAlloc(mBlockSize);
|
||||
INode xCurrentINode;
|
||||
System.Diagnostics.Debugger.Break();
|
||||
if (!ReadINode(EXT2_ROOT_INO, out xCurrentINode)) {
|
||||
Heap.MemFree((uint)xBuffer);
|
||||
Heap.MemFree((uint)xExt2BlockBuffer);
|
||||
|
|
|
|||
|
|
@ -181,8 +181,6 @@ namespace Cosmos.Kernel {
|
|||
char xResult = '\0';
|
||||
while (mBuffer.Count == 0 || !GetCharValue(mBuffer.Dequeue(), out xResult))
|
||||
;
|
||||
//DebugUtil.SendNumber("Keyboard", "ReadChar", xResult, 32);
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
return xResult;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ namespace Cosmos.Shell.Console.Commands
|
|||
Cosmos.Kernel.FileSystem.Ext2 xExt2 = new Cosmos.Kernel.FileSystem.Ext2 (xDrive);
|
||||
xExt2.Initialize();
|
||||
|
||||
|
||||
string[] files = xExt2.GetDirectoryEntries(new string[0]);
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
System.Console.WriteLine(files[i]);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Cosmos.Shell.Console.Commands
|
|||
|
||||
public override void Execute(string param)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
//throw new NotSupportedException();
|
||||
//_exit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ namespace Cosmos.Shell.Console.Commands {
|
|||
} catch (ArgumentException AE) {
|
||||
System.Console.WriteLine("Argument Exception Occurred:");
|
||||
System.Console.Write(" Param Name: ");
|
||||
System.Diagnostics.Debugger.Break();
|
||||
System.Console.WriteLine(AE.ParamName);
|
||||
} catch (Exception E) {
|
||||
System.Console.WriteLine("Error Occurred while executing Command!");
|
||||
|
|
|
|||
|
|
@ -12,24 +12,20 @@ namespace Cosmos.Shell.Console.Commands {
|
|||
}
|
||||
|
||||
public override void Execute(string param) {
|
||||
System.Console.Write("Emitting contents of ");
|
||||
System.Console.Write("Contents of ");
|
||||
System.Console.Write(param);
|
||||
System.Console.WriteLine(":");
|
||||
|
||||
Hardware.Storage.ATA xDrive = new Cosmos.Hardware.Storage.ATA(0, 0);
|
||||
Cosmos.Kernel.FileSystem.Ext2 xExt2 = new Cosmos.Kernel.FileSystem.Ext2(xDrive);
|
||||
if (xExt2.Initialize())
|
||||
{
|
||||
System.Console.WriteLine("Ext2 Initialized");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Console.WriteLine("Ext2 Initialization failed!");
|
||||
if (!xExt2.Initialize()){
|
||||
System.Console.WriteLine("Error: Ext2 Initialization failed!");
|
||||
return;
|
||||
}
|
||||
byte[] xItem = xExt2.ReadFile(new string[] { param });
|
||||
if (xItem == null)
|
||||
{
|
||||
System.Console.WriteLine("Couldn't read file!");
|
||||
System.Console.WriteLine("Error: Couldn't read file!");
|
||||
return;
|
||||
}
|
||||
char[] xChars = new char[xItem.Length - 1];
|
||||
|
|
|
|||
|
|
@ -27,15 +27,13 @@ namespace Cosmos.Shell.Console {
|
|||
_commands.Add(new Commands.ClsCommand());
|
||||
_commands.Add(new Commands.DirCommand());
|
||||
_commands.Add(new Commands.EchoCommand());
|
||||
_commands.Add(new Commands.ExitCommand(Stop)); // TODO: Fix this.
|
||||
_commands.Add(new Commands.GuessCommand());
|
||||
//_commands.Add(new Commands.ExitCommand(Stop)); // TODO: Fix this.
|
||||
_commands.Add(new Commands.GuessCommand());
|
||||
_commands.Add(new Commands.HelpCommand(_commands));
|
||||
_commands.Add(new Commands.TestsCommand());
|
||||
_commands.Add(new Commands.TestsCommand());
|
||||
_commands.Add(new Commands.TypeCommand());
|
||||
_commands.Add(new Commands.VersionCommand());
|
||||
_commands.Add(new Commands.MatthijsCommand());
|
||||
|
||||
|
||||
_commands.Add(new Commands.VersionCommand());
|
||||
//_commands.Add(new Commands.MatthijsCommand());
|
||||
|
||||
while (running) {
|
||||
System.Console.Write("/> ");
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@ namespace IL2CPU {
|
|||
}
|
||||
|
||||
public static int Main(string[] args) {
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
try {
|
||||
if (ParseArguments(args)) {
|
||||
Engine e = new Engine();
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ namespace Indy.IL2CPU.Assembler.X86.Native {
|
|||
|
||||
protected override void EmitImportMembers(string aGroup, StreamWriter aOutputWriter) {
|
||||
if (ImportMembers.Count > 0) {
|
||||
throw new Exception("You can't use external libraries in OS kernels");
|
||||
throw new Exception("You can't use P/Invoke in OS kernels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace Indy.IL2CPU.Assembler {
|
|||
Console.WriteLine("BSOD's Rule!");
|
||||
Console.WriteLine("");
|
||||
Console.Write("Unhandled error occurred: ");
|
||||
System.Diagnostics.Debugger.Break();
|
||||
Console.WriteLine(CurrentException.ToString());
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
|
|
@ -42,6 +43,7 @@ namespace Indy.IL2CPU.Assembler {
|
|||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
}
|
||||
|
||||
private static FieldDefinition mCurrentExceptionRef;
|
||||
public static FieldDefinition CurrentExceptionRef {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
|
||||
public static void EmitExceptionLogic(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aNextLabel, bool aDoTest) {
|
||||
//if (!aAssembler.InMetalMode) {
|
||||
if (aMethodInfo != null && aMethodInfo.LabelName == "System_Void___Cosmos_Shell_Console_Commands_MatthijsCommand_Execute___System_String___") {
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
string xJumpTo = MethodFooterOp.EndOfMethodLabelNameException;
|
||||
if (aMethodInfo != null && aMethodInfo.CurrentHandler != null) {
|
||||
switch (aMethodInfo.CurrentHandler.Type) {
|
||||
|
|
@ -47,6 +43,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
}
|
||||
if (!aDoTest) {
|
||||
new CPUx86.Call("_CODE_REQUESTED_BREAK_");
|
||||
new CPUx86.JumpAlways(xJumpTo);
|
||||
} else {
|
||||
new CPUx86.Test("ecx", "2");
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
new CPUx86.Test("ecx", "2");
|
||||
new CPUx86.JumpIfNotEquals(MethodFooterOp.EndOfMethodLabelNameException);
|
||||
}
|
||||
new CPU.Comment("Argument Count = " + mArgumentCount.ToString());
|
||||
for (int i = 0; i < mArgumentCount; i++) {
|
||||
Assembler.StackSizes.Pop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Linq;
|
||||
using Indy.IL2CPU.Assembler;
|
||||
using Indy.IL2CPU.Assembler.X86;
|
||||
using CPU = Indy.IL2CPU.Assembler;
|
||||
using CPUx86 = Indy.IL2CPU.Assembler.X86;
|
||||
using Instruction = Mono.Cecil.Cil.Instruction;
|
||||
using Mono.Cecil.Cil;
|
||||
|
|
@ -25,6 +26,9 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
new CPUx86.JumpIfNotEquals(aNextLabel);
|
||||
TypeDefinition xNullRefExcType = Engine.GetTypeDefinitionFromReflectionType(typeof(NullReferenceException));
|
||||
Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.Constructors.GetConstructor(false, new Type[0]), Engine.RegisterType(xNullRefExcType));
|
||||
aAssembler.StackSizes.Pop();
|
||||
new CPUx86.Move("[" + DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
|
||||
new CPUx86.Move("ecx", "3");
|
||||
aEmitCleanupMethod();
|
||||
Call.EmitExceptionLogic(aAssembler, aMethodInfo, aNextLabel, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
|
||||
public override void Enter(string aName) {
|
||||
X86MethodHeaderOp.AssembleHeader(Assembler, aName, new int[0], new MethodInformation.Argument[0]);
|
||||
X86MethodHeaderOp.AssembleHeader(Assembler, aName, new MethodInformation.Variable[0], new MethodInformation.Argument[0]);
|
||||
mMethodName = aName;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,27 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public static void AssembleFooter(int aReturnSize, Assembler.Assembler aAssembler, MethodInformation.Variable[] aLocals, MethodInformation.Argument[] aArgs, int aTotalArgsSize) {
|
||||
new Label(EndOfMethodLabelNameNormal);
|
||||
new CPUx86.Move("ecx", "0");
|
||||
//new CPUx86.JumpAlways("._GENERIC_Footer");
|
||||
if (aReturnSize > 0) {
|
||||
if (aReturnSize > 8) {
|
||||
throw new Exception("ReturnValue sizes larger than 8 not supported yet");
|
||||
} else {
|
||||
if (aReturnSize <= 4) {
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EAX);
|
||||
} else {
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EAX);
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EBX);
|
||||
}
|
||||
}
|
||||
}
|
||||
new CPUx86.JumpAlways(EndOfMethodLabelNameException);
|
||||
new Label(EndOfMethodLabelNameException);
|
||||
if (!aAssembler.InMetalMode) {
|
||||
if (aReturnSize > 0) {
|
||||
new CPUx86.Push("eax");
|
||||
if (aReturnSize > 4) {
|
||||
new CPUx86.Push("ebx");
|
||||
}
|
||||
}
|
||||
new CPUx86.Push("ecx");
|
||||
Engine.QueueMethodRef(GCImplementationRefs.DecRefCountRef);
|
||||
foreach (MethodInformation.Variable xLocal in aLocals) {
|
||||
|
|
@ -50,17 +68,11 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
}
|
||||
new CPUx86.Pop("ecx");
|
||||
}
|
||||
if (aReturnSize > 0) {
|
||||
if (aReturnSize > 8) {
|
||||
throw new Exception("ReturnValue sizes larger than 8 not supported yet");
|
||||
} else {
|
||||
if (aReturnSize <= 4) {
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EAX);
|
||||
} else {
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EAX);
|
||||
new Assembler.X86.Pop(CPUx86.Registers.EBX);
|
||||
if (aReturnSize > 0) {
|
||||
if (aReturnSize > 4) {
|
||||
new CPUx86.Pop("ebx");
|
||||
}
|
||||
new CPUx86.Pop("eax");
|
||||
}
|
||||
}
|
||||
for (int j = aLocals.Length - 1; j >= 0; j--) {
|
||||
|
|
|
|||
|
|
@ -9,15 +9,14 @@ using Instruction = Mono.Cecil.Cil.Instruction;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
public class X86MethodHeaderOp: MethodHeaderOp {
|
||||
public readonly int[] Locals;
|
||||
public readonly MethodInformation.Variable[] Locals;
|
||||
public readonly string LabelName = "";
|
||||
public readonly MethodInformation.Argument[] Args;
|
||||
public X86MethodHeaderOp(Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
LabelName = aMethodInfo.LabelName;
|
||||
Args = aMethodInfo.Arguments.ToArray();
|
||||
Locals = (from local in aMethodInfo.Locals
|
||||
select local.Size).ToArray();
|
||||
Locals = aMethodInfo.Locals.ToArray();
|
||||
}
|
||||
|
||||
public override void DoAssemble() {
|
||||
|
|
@ -25,7 +24,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
AssembleHeader(Assembler, LabelName, Locals, Args);
|
||||
}
|
||||
|
||||
public static void AssembleHeader(Assembler.Assembler aAssembler, string aLabelName, int[] aLocals, MethodInformation.Argument[] aArguments) {
|
||||
public static void AssembleHeader(Assembler.Assembler aAssembler, string aLabelName, MethodInformation.Variable[] aLocals, MethodInformation.Argument[] aArguments) {
|
||||
new CPU.Label(aLabelName);
|
||||
new CPUx86.Pushd(CPUx86.Registers.EBP);
|
||||
#if EXT_DEBUG
|
||||
|
|
@ -40,9 +39,9 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
// new CPUx86.Call(Label.GenerateLabelName(xTempMethod));
|
||||
// Engine.QueueMethod(xTempMethod);
|
||||
//}
|
||||
foreach (int xLocalSize in aLocals) {
|
||||
aAssembler.StackSizes.Push(xLocalSize);
|
||||
for (int i = 0; i < (xLocalSize / 4); i++) {
|
||||
foreach (var xLocal in aLocals) {
|
||||
aAssembler.StackSizes.Push(xLocal.Size);
|
||||
for (int i = 0; i < (xLocal.Size / 4); i++) {
|
||||
new CPUx86.Pushd("0");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ using Indy.IL2CPU.Plugs;
|
|||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target = typeof(byte))]
|
||||
public static class ByteImpl {
|
||||
public static string ToString(byte aThis) {
|
||||
[PlugMethod(Signature = "System_String___System_Byte_ToString____")]
|
||||
public static string ToString(ref byte aThis) {
|
||||
char[] xResult = new char[4];
|
||||
string xDigits = "0123456789ABCDEF";
|
||||
xResult[0] = '0';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ using Indy.IL2CPU.Plugs;
|
|||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target = typeof(char))]
|
||||
public static class CharImpl {
|
||||
public static string ToString(char aThis) {
|
||||
[PlugMethod(Signature = "System_String___System_Char_ToString____")]
|
||||
public static string ToString(ref char aThis) {
|
||||
char[] xResult = new char[1];
|
||||
xResult[0] = aThis;
|
||||
return new String(xResult);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
|||
[Plug(Target = typeof(Enum))]
|
||||
public static class EnumImpl {
|
||||
[PlugMethod(Signature = "System_String___System_Enum_ToString____")]
|
||||
public static string ToString(uint aThis) {
|
||||
return UInt32Impl.ToString(aThis);
|
||||
public static string ToString(ref uint aThis) {
|
||||
return UInt32Impl.ToString(ref aThis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,8 @@ using Indy.IL2CPU.Plugs;
|
|||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target=typeof(short))]
|
||||
public static class Int16Impl {
|
||||
public static string ToString(short aThis) {
|
||||
[PlugMethod(Signature = "System_String___System_Int16_ToString____")]
|
||||
public static string ToString(ref short aThis) {
|
||||
string xDigits = "0123456789ABCDEF";
|
||||
char[] xResult = new char[6];
|
||||
xResult[0] = '0';
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ using System.Text;
|
|||
using Indy.IL2CPU.Plugs;
|
||||
|
||||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target=typeof(Int32))]
|
||||
[Plug(Target = typeof(Int32))]
|
||||
public static class Int32Impl {
|
||||
public static string ToString(int aThis) {
|
||||
return UInt32Impl.ToString((uint)aThis);
|
||||
[PlugMethod(Signature = "System_String___System_Int32_ToString____")]
|
||||
public static string ToString(ref int aThis) {
|
||||
uint xValue = (uint)aThis;
|
||||
return UInt32Impl.ToString(ref xValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
|||
[Plug(Target=typeof(IntPtr))]
|
||||
public static class IntPtrImpl {
|
||||
[PlugMethod(Signature="System_String___System_IntPtr_ToString____")]
|
||||
public static string ToString(uint aThis) {
|
||||
return UInt32Impl.ToString(aThis);
|
||||
public static string ToString(ref uint aThis) {
|
||||
return UInt32Impl.ToString(ref aThis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,8 @@ using Indy.IL2CPU.Plugs;
|
|||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target=typeof(ushort))]
|
||||
public static class UInt16Impl {
|
||||
public static string ToString(ushort aThis) {
|
||||
[PlugMethod(Signature = "System_String___System_UInt16_ToString____")]
|
||||
public static string ToString(ref ushort aThis) {
|
||||
string xDigits = "0123456789ABCDEF";
|
||||
char[] xResult = new char[6];
|
||||
xResult[0] = '0';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ using Indy.IL2CPU.Plugs;
|
|||
namespace Indy.IL2CPU.IL.CustomImplementations.System {
|
||||
[Plug(Target=typeof(UInt32))]
|
||||
public static class UInt32Impl {
|
||||
public static string ToString(uint aThis) {
|
||||
[PlugMethod(Signature = "System_String___System_UInt32_ToString____")]
|
||||
public static string ToString(ref uint aThis) {
|
||||
string xDigits = "0123456789ABCDEF";
|
||||
char[] xResult = new char[10];
|
||||
xResult[0] = '0';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using Indy.IL2CPU.Assembler;
|
||||
using Mono.Cecil;
|
||||
using Instruction = Mono.Cecil.Cil.Instruction;
|
||||
using System.Xml;
|
||||
|
||||
namespace Indy.IL2CPU.IL {
|
||||
public abstract class InitVmtImplementationOp: Op {
|
||||
|
|
@ -48,109 +49,123 @@ namespace Indy.IL2CPU.IL {
|
|||
protected abstract void Call(MethodDefinition aMethod);
|
||||
|
||||
public override void DoAssemble() {
|
||||
string xTheName = DataMember.GetStaticFieldName(TypesFieldRef);
|
||||
DataMember xDataMember = (from item in Assembler.DataMembers
|
||||
where item.Value.Name == xTheName
|
||||
select item.Value).FirstOrDefault();
|
||||
if (xDataMember != null) {
|
||||
Assembler.DataMembers.Remove((from item in Assembler.DataMembers
|
||||
where item.Value == xDataMember
|
||||
select item).First());
|
||||
}
|
||||
StringBuilder xDataByteArray = new StringBuilder();
|
||||
xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes((uint)0x80000002).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(mTypes.Count).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(VTableEntrySize).Aggregate("", (r, b) => r + b + ","));
|
||||
for (uint i = 0; i < mTypes.Count; i++) {
|
||||
for (int j = 0; j < VTableEntrySize; j++) {
|
||||
xDataByteArray.Append("0,");
|
||||
using (XmlWriter xDebug = XmlWriter.Create(@"d:\vtables.xml")) {
|
||||
xDebug.WriteStartDocument();
|
||||
xDebug.WriteStartElement("VTables");
|
||||
xDebug.WriteStartElement("AllMethods");
|
||||
foreach (MethodDefinition xTheMethod in Methods) {
|
||||
xDebug.WriteStartElement("Method");
|
||||
xDebug.WriteAttributeString("Id", GetMethodIdentifier(xTheMethod).ToString("X"));
|
||||
xDebug.WriteAttributeString("Name", xTheMethod.ToString());
|
||||
xDebug.WriteEndElement();
|
||||
}
|
||||
}
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xTheName + "__Contents", "db", xDataByteArray.ToString().TrimEnd(','))));
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xTheName, "dd", xTheName + "__Contents")));
|
||||
Pushd("0" + mTypes.Count.ToString("X") + "h");
|
||||
Call(LoadTypeTableRef);
|
||||
for (int i = 0; i < mTypes.Count; i++) {
|
||||
TypeDefinition xType = mTypes[i];
|
||||
List<MethodDefinition> xEmittedMethods = new List<MethodDefinition>();
|
||||
foreach (MethodDefinition xMethod in xType.Methods) {
|
||||
if (Methods.Contains(xMethod) && !xMethod.IsAbstract) {
|
||||
xEmittedMethods.Add(xMethod);
|
||||
}
|
||||
xDebug.WriteEndElement();
|
||||
string xTheName = DataMember.GetStaticFieldName(TypesFieldRef);
|
||||
DataMember xDataMember = (from item in Assembler.DataMembers
|
||||
where item.Value.Name == xTheName
|
||||
select item.Value).FirstOrDefault();
|
||||
if (xDataMember != null) {
|
||||
Assembler.DataMembers.Remove((from item in Assembler.DataMembers
|
||||
where item.Value == xDataMember
|
||||
select item).First());
|
||||
}
|
||||
foreach (MethodDefinition xCtor in xType.Constructors) {
|
||||
if (Methods.Contains(xCtor) && !xCtor.IsAbstract) {
|
||||
xEmittedMethods.Add(xCtor);
|
||||
}
|
||||
}
|
||||
Pushd("0" + i.ToString("X") + "h");
|
||||
int? xBaseIndex = null;
|
||||
if (xType.BaseType == null) {
|
||||
for (int t = 0; t < mTypes.Count; t++) {
|
||||
if (mTypes[t].BaseType == null && mTypes[t].FullName == xType.FullName) {
|
||||
xBaseIndex = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int t = 0; t < mTypes.Count; t++) {
|
||||
if (mTypes[t].BaseType == null) {
|
||||
continue;
|
||||
}
|
||||
if (mTypes[t].BaseType.FullName == xType.BaseType.FullName && mTypes[t].FullName == xType.FullName) {
|
||||
xBaseIndex = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xBaseIndex == null) {
|
||||
throw new Exception("Base type not found!");
|
||||
}
|
||||
Pushd("0" + xBaseIndex.Value.ToString("X") + "h");
|
||||
//Pushd("0" + xEmittedMethods.Count.ToString("X") + "h");
|
||||
xDataByteArray.Remove(0, xDataByteArray.Length);
|
||||
StringBuilder xDataByteArray = new StringBuilder();
|
||||
xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(0x80000002 /* EmbeddedArray */).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(xEmittedMethods.Count).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append("0,0,0,0,");
|
||||
for (uint j = 0; j < xEmittedMethods.Count; j++) {
|
||||
xDataByteArray.Append("0,0,0,0,");
|
||||
xDataByteArray.Append(BitConverter.GetBytes((uint)0x80000002).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(mTypes.Count).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(VTableEntrySize).Aggregate("", (r, b) => r + b + ","));
|
||||
for (uint i = 0; i < mTypes.Count; i++) {
|
||||
for (int j = 0; j < VTableEntrySize; j++) {
|
||||
xDataByteArray.Append("0,");
|
||||
}
|
||||
}
|
||||
string xDataValue = xDataByteArray.ToString();
|
||||
string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodIndexesArray";
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(','))));
|
||||
Pushd(xDataName);
|
||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodAddressesArray";
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(','))));
|
||||
Pushd(xDataName);
|
||||
xDataByteArray.Remove(0, xDataByteArray.Length);
|
||||
xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(0x80000002 /* EmbeddedArray */).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes((mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Length).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes((uint)2).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(Encoding.Unicode.GetBytes(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Aggregate("", (b, x) => b + x + ",") + "0");
|
||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName);
|
||||
mAssembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataByteArray.ToString())));
|
||||
Pushd(xDataName);
|
||||
//Pushd("0");
|
||||
Call(SetTypeInfoRef);
|
||||
for (int j = 0; j < xEmittedMethods.Count; j++) {
|
||||
MethodDefinition xMethod = xEmittedMethods[j];
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xTheName + "__Contents", "db", xDataByteArray.ToString().TrimEnd(','))));
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xTheName, "dd", xTheName + "__Contents")));
|
||||
Pushd("0" + mTypes.Count.ToString("X") + "h");
|
||||
Call(LoadTypeTableRef);
|
||||
for (int i = 0; i < mTypes.Count; i++) {
|
||||
xDebug.WriteStartElement("Type");
|
||||
xDebug.WriteAttributeString("Id", i.ToString("X"));
|
||||
TypeDefinition xType = mTypes[i];
|
||||
List<MethodDefinition> xEmittedMethods = new List<MethodDefinition>();
|
||||
foreach (MethodDefinition xMethod in xType.Methods) {
|
||||
if (Methods.Contains(xMethod) && !xMethod.IsAbstract) {
|
||||
xEmittedMethods.Add(xMethod);
|
||||
}
|
||||
}
|
||||
foreach (MethodDefinition xCtor in xType.Constructors) {
|
||||
if (Methods.Contains(xCtor) && !xCtor.IsAbstract) {
|
||||
xEmittedMethods.Add(xCtor);
|
||||
}
|
||||
}
|
||||
Pushd("0" + i.ToString("X") + "h");
|
||||
Pushd("0" + j.ToString("X") + "h");
|
||||
TypeReference[] xMethodParams = new TypeReference[xMethod.Parameters.Count];
|
||||
for (int k = 0; k < xMethod.Parameters.Count; k++) {
|
||||
xMethodParams[k] = xMethod.Parameters[k].ParameterType;
|
||||
int? xBaseIndex = null;
|
||||
if (xType.BaseType == null) {
|
||||
xBaseIndex = i;
|
||||
} else {
|
||||
for (int t = 0; t < mTypes.Count; t++) {
|
||||
if (mTypes[t].ToString() == xType.BaseType.ToString()) {
|
||||
xBaseIndex = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Pushd("0" + GetMethodIdentifier(xMethod).ToString("X") + "h");
|
||||
Pushd(Label.GenerateLabelName(xMethod));
|
||||
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
|
||||
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));
|
||||
//mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue));
|
||||
//Pushd(xDataName);
|
||||
Pushd("0");
|
||||
Call(SetMethodInfoRef);
|
||||
if (xBaseIndex == null) {
|
||||
throw new Exception("Base type not found!");
|
||||
}
|
||||
xDebug.WriteAttributeString("BaseId", xBaseIndex.Value.ToString("X"));
|
||||
xDebug.WriteAttributeString("Name", mTypes[i].FullName);
|
||||
|
||||
Pushd("0" + xBaseIndex.Value.ToString("X") + "h");
|
||||
//Pushd("0" + xEmittedMethods.Count.ToString("X") + "h");
|
||||
xDataByteArray.Remove(0, xDataByteArray.Length);
|
||||
xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(0x80000002 /* EmbeddedArray */).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(xEmittedMethods.Count).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append("0,0,0,0,");
|
||||
for (uint j = 0; j < xEmittedMethods.Count; j++) {
|
||||
xDataByteArray.Append("0,0,0,0,");
|
||||
}
|
||||
string xDataValue = xDataByteArray.ToString();
|
||||
string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodIndexesArray";
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(','))));
|
||||
Pushd(xDataName);
|
||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodAddressesArray";
|
||||
Assembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(','))));
|
||||
Pushd(xDataName);
|
||||
xDataByteArray.Remove(0, xDataByteArray.Length);
|
||||
xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes(0x80000002 /* EmbeddedArray */).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes((mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Length).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(BitConverter.GetBytes((uint)2).Aggregate("", (r, b) => r + b + ","));
|
||||
xDataByteArray.Append(Encoding.Unicode.GetBytes(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Aggregate("", (b, x) => b + x + ",") + "0");
|
||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName);
|
||||
mAssembler.DataMembers.Add(new KeyValuePair<string, DataMember>(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataByteArray.ToString())));
|
||||
Pushd(xDataName);
|
||||
//Pushd("0");
|
||||
Call(SetTypeInfoRef);
|
||||
for (int j = 0; j < xEmittedMethods.Count; j++) {
|
||||
MethodDefinition xMethod = xEmittedMethods[j];
|
||||
xDebug.WriteStartElement("Method");
|
||||
xDebug.WriteAttributeString("Id", GetMethodIdentifier(xMethod).ToString("X"));
|
||||
xDebug.WriteAttributeString("Name", xMethod.ToString());
|
||||
xDebug.WriteEndElement();
|
||||
Pushd("0" + i.ToString("X") + "h");
|
||||
Pushd("0" + j.ToString("X") + "h");
|
||||
TypeReference[] xMethodParams = new TypeReference[xMethod.Parameters.Count];
|
||||
for (int k = 0; k < xMethod.Parameters.Count; k++) {
|
||||
xMethodParams[k] = xMethod.Parameters[k].ParameterType;
|
||||
}
|
||||
Pushd("0" + GetMethodIdentifier(xMethod).ToString("X") + "h");
|
||||
Pushd(Label.GenerateLabelName(xMethod));
|
||||
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
|
||||
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));
|
||||
//mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue));
|
||||
//Pushd(xDataName);
|
||||
Pushd("0");
|
||||
Call(SetMethodInfoRef);
|
||||
}
|
||||
xDebug.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ namespace Indy.IL2CPU.IL {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
if (aAssembler.InMetalMode) {
|
||||
if (xPlugMethodAttrib.Fields[PlugMethodAttribute.InMetalModePropertyName] != null && !((bool)xPlugMethodAttrib.Fields[PlugMethodAttribute.InMetalModePropertyName])) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,6 @@ namespace Indy.IL2CPU {
|
|||
if (!aInMetalMode) {
|
||||
xEntryPointOp.Call("____INIT__VMT____");
|
||||
}
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
foreach (TypeDefinition xType in mTypes) {
|
||||
foreach (MethodDefinition xMethod in xType.Constructors) {
|
||||
if (xMethod.IsStatic) {
|
||||
|
|
@ -963,9 +962,6 @@ namespace Indy.IL2CPU {
|
|||
if (xField.HasConstant) {
|
||||
Console.WriteLine("Field is constant: " + xField.GetFullName());
|
||||
}
|
||||
if (xField.DeclaringType.FullName.StartsWith("System.Collections.Generic") && aGCObjects) {
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
if (xField.FieldType.IsValueType && aGCObjects) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1041,7 +1037,6 @@ namespace Indy.IL2CPU {
|
|||
aFieldName = DataMember.GetStaticFieldName(xFieldDef);
|
||||
return;
|
||||
}
|
||||
System.Diagnostics.Debugger.Break();
|
||||
throw new Exception("Field not found!(" + String.Format("{0}/{1}/{2}", aAssembly, aType, aField));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,11 +46,25 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
|
||||
public static int GetMethodAddressForType(int aType, int aMethodIndex) {
|
||||
VTable xTable = mTypes[aType];
|
||||
for (int i = 0; i < xTable.MethodIndexes.Length; i++) {
|
||||
if (xTable.MethodIndexes[i] == aMethodIndex) {
|
||||
return xTable.MethodAddresses[i];
|
||||
VTable xTable;
|
||||
if (aType == 0) {
|
||||
xTable = mTypes[0];
|
||||
for (int i = 0; i < xTable.MethodIndexes.Length; i++) {
|
||||
if (xTable.MethodIndexes[i] == aMethodIndex) {
|
||||
return xTable.MethodAddresses[i];
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
do {
|
||||
xTable = mTypes[aType];
|
||||
for (int i = 0; i < xTable.MethodIndexes.Length; i++) {
|
||||
if (xTable.MethodIndexes[i] == aMethodIndex) {
|
||||
return xTable.MethodAddresses[i];
|
||||
}
|
||||
}
|
||||
aType = xTable.BaseTypeIdentifier;
|
||||
} while (aType != 0);
|
||||
}
|
||||
throw new Exception("Cannot find virtual method!");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue