mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-22 13:58:47 +00:00
non-multicast events work now.
This commit is contained in:
parent
07a5974362
commit
8f9b9bd80d
12 changed files with 202 additions and 7 deletions
|
|
@ -12,6 +12,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
private bool mHasReturn;
|
||||
private string mNormalAddress;
|
||||
private string mMethodDescription;
|
||||
private string[] mThisAddresses;
|
||||
public Callvirt(Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
int xThisOffSet = (from item in aMethodInfo.Locals
|
||||
|
|
@ -31,6 +32,11 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
Engine.QueueMethodRef(VTablesImplRefs.GetMethodAddressForTypeRef);
|
||||
MethodInformation xTheMethodInfo = Engine.GetMethodInfo(xMethodDef, xMethodDef, mMethodDescription, null);
|
||||
mHasReturn = xTheMethodInfo.ReturnSize != 0;
|
||||
Console.WriteLine("Debug: " + xTheMethodInfo.ToString());
|
||||
mThisAddresses = xTheMethodInfo.Arguments[0].VirtualAddresses;
|
||||
if (mThisAddresses.Length > 1) {
|
||||
throw new Exception("In x86, object addresses are 4 bytes. Found different size!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void DoAssemble() {
|
||||
|
|
@ -40,8 +46,18 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
if (Assembler.InMetalMode) {
|
||||
throw new Exception("Virtual methods not supported in Metal mode! (Called method = '" + mMethodDescription + "')");
|
||||
}
|
||||
Assembler.Add(new CPUx86.Pop("eax"));
|
||||
Assembler.Add(new CPUx86.Pushd("eax"));
|
||||
string[] xAddrParts = mThisAddresses[0].Split('+');
|
||||
Pushd(4, xAddrParts[0].Trim());
|
||||
Pushd(4, xAddrParts[1].Trim());
|
||||
Pushd(4, "8");
|
||||
new Sub(null, null) {
|
||||
Assembler = this.Assembler
|
||||
}.Assemble();
|
||||
new Sub(null, null) {
|
||||
Assembler = this.Assembler
|
||||
}.Assemble();
|
||||
Pop("ecx");
|
||||
Move(Assembler, "eax", "[ecx]");
|
||||
Assembler.Add(new CPUx86.Pushd("[eax]"));
|
||||
Assembler.Add(new CPUx86.Pushd("0" + mMethodIdentifier.ToString("X") + "h"));
|
||||
Call(new CPU.Label(VTablesImplRefs.GetMethodAddressForTypeRef).Name);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
|
||||
public static unsafe class EventHandlerImpl {
|
||||
public static void Ctor(uint* aThis, uint aObject, uint aMethod) {
|
||||
// move forward 8 bytes
|
||||
uint* xThis = aThis;
|
||||
aThis += 2;
|
||||
*aThis = aObject;
|
||||
aThis += 1;
|
||||
*aThis = aMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
|
||||
public static class EventHandlerImplRefs {
|
||||
public static readonly AssemblyDefinition RuntimeAssemblyDef;
|
||||
public static readonly MethodDefinition CtorRef;
|
||||
|
||||
static EventHandlerImplRefs() {
|
||||
RuntimeAssemblyDef = AssemblyFactory.GetAssembly(typeof(EventHandlerImpl).Assembly.Location);
|
||||
TypeDefinition xType = null;
|
||||
foreach (ModuleDefinition xMod in RuntimeAssemblyDef.Modules) {
|
||||
if (xMod.Types.Contains(typeof(EventHandlerImpl).FullName)) {
|
||||
xType = xMod.Types[typeof(EventHandlerImpl).FullName];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (xType == null) {
|
||||
throw new Exception("EventHandlerImpl type not found!");
|
||||
}
|
||||
foreach (FieldInfo xField in typeof(EventHandlerImplRefs).GetFields()) {
|
||||
if (xField.Name.EndsWith("Ref")) {
|
||||
MethodDefinition xTempMethod = xType.Methods.GetMethod(xField.Name.Substring(0, xField.Name.Length - "Ref".Length)).FirstOrDefault();
|
||||
if (xTempMethod == null) {
|
||||
throw new Exception("Method '" + xField.Name.Substring(0, xField.Name.Length - "Ref".Length) + "' not found on DelegateImpl!");
|
||||
}
|
||||
xField.SetValue(null, xTempMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
|
||||
public static unsafe class EventHandlerImpl {
|
||||
public static void Ctor(uint* aThis, uint aObject, uint aMethod) {
|
||||
// move forward 8 bytes
|
||||
uint* xThis = aThis;
|
||||
aThis += 2;
|
||||
*aThis = aObject;
|
||||
aThis += 1;
|
||||
*aThis = aMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
|
||||
public static class EventHandlerImplRefs {
|
||||
public static readonly AssemblyDefinition RuntimeAssemblyDef;
|
||||
public static readonly MethodDefinition CtorRef;
|
||||
|
||||
static EventHandlerImplRefs() {
|
||||
RuntimeAssemblyDef = AssemblyFactory.GetAssembly(typeof(EventHandlerImpl).Assembly.Location);
|
||||
TypeDefinition xType = null;
|
||||
foreach (ModuleDefinition xMod in RuntimeAssemblyDef.Modules) {
|
||||
if (xMod.Types.Contains(typeof(EventHandlerImpl).FullName)) {
|
||||
xType = xMod.Types[typeof(EventHandlerImpl).FullName];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (xType == null) {
|
||||
throw new Exception("EventHandlerImpl type not found!");
|
||||
}
|
||||
foreach (FieldInfo xField in typeof(EventHandlerImplRefs).GetFields()) {
|
||||
if (xField.Name.EndsWith("Ref")) {
|
||||
MethodDefinition xTempMethod = xType.Methods.GetMethod(xField.Name.Substring(0, xField.Name.Length - "Ref".Length)).FirstOrDefault();
|
||||
if (xTempMethod == null) {
|
||||
throw new Exception("Method '" + xField.Name.Substring(0, xField.Name.Length - "Ref".Length) + "' not found on DelegateImpl!");
|
||||
}
|
||||
xField.SetValue(null, xTempMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +127,10 @@
|
|||
<Compile Include="Conv_U8.cs" />
|
||||
<Compile Include="Cpblk.cs" />
|
||||
<Compile Include="Cpobj.cs" />
|
||||
<Compile Include="CustomImplementations\System\MulticastDelegateImpl.cs" />
|
||||
<Compile Include="CustomImplementations\System\MulticastDelegateImplRefs.cs" />
|
||||
<Compile Include="CustomImplementations\System\EventHandlerImpl.cs" />
|
||||
<Compile Include="CustomImplementations\System\EventHandlerImplRefs.cs" />
|
||||
<Compile Include="CustomImplementations\System\ObjectImpl.cs" />
|
||||
<Compile Include="CustomImplementations\System\ObjectImplRefs.cs" />
|
||||
<Compile Include="CustomImplementations\System\StringImplRefs.cs" />
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
goto default;
|
||||
}
|
||||
case "System_Void___System_EventHandler__ctor___System_Object__System_IntPtr___": {
|
||||
return CustomImplementations.System.EventHandlerImplRefs.CtorRef;
|
||||
}
|
||||
default:
|
||||
return base.GetCustomMethodImplementation(aOrigMethodName, aInMetalMode);
|
||||
}
|
||||
|
|
@ -61,13 +64,16 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
switch (aMethodName) {
|
||||
case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case "System_Int32___System_Threading_Interlocked_CompareExchange___System_Int32___System_Int32__System_Int32___": {
|
||||
return true;
|
||||
}
|
||||
case "System_String___System_String_FastAllocateString___System_Int32___": {
|
||||
return true;
|
||||
}
|
||||
case "System_Void___System_EventHandler_Invoke___System_Object__System_EventArgs___": {
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return base.HasCustomAssembleImplementation(aMethodName, aInMetalMode);
|
||||
}
|
||||
|
|
@ -83,6 +89,10 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo);
|
||||
break;
|
||||
}
|
||||
case "System_Void___System_EventHandler_Invoke___System_Object__System_EventArgs___": {
|
||||
Assemble_System_EventHandler_Invoke___System_Object__System_EventArgs___(aAssembler, aMethodInfo);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
base.DoCustomAssembleImplementation(aMethodName, aInMetalMode, aAssembler, aMethodInfo);
|
||||
break;
|
||||
|
|
@ -108,5 +118,26 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
aAssembler.Add(new CPUx86.Move("[eax]", "ecx"));
|
||||
aAssembler.Add(new CPUx86.Pushd("eax"));
|
||||
}
|
||||
|
||||
private static void Assemble_System_EventHandler_Invoke___System_Object__System_EventArgs___(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
|
||||
// param 0 is instance of eventhandler
|
||||
// param 1 is sender
|
||||
// param 2 is eventargs
|
||||
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size);
|
||||
Ldarg.Push(aAssembler, 4, "0x" + (ObjectImpl.FieldDataOffset + 4).ToString("X"));
|
||||
Ldarg.Add(aAssembler);
|
||||
aAssembler.Add(new CPUx86.Pop("eax"));
|
||||
aAssembler.Add(new CPUx86.Pushd("[eax]"));
|
||||
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[1].VirtualAddresses, aMethodInfo.Arguments[1].Size);
|
||||
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[2].VirtualAddresses, aMethodInfo.Arguments[2].Size);
|
||||
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size);
|
||||
Ldarg.Push(aAssembler, 4, "0x" + ObjectImpl.FieldDataOffset.ToString("X"));
|
||||
Ldarg.Add(aAssembler);
|
||||
aAssembler.Add(new CPUx86.Pop("eax"));
|
||||
aAssembler.Add(new CPUx86.Pushd("[eax]"));
|
||||
aAssembler.Add(new CPUx86.Pop("eax"));
|
||||
aAssembler.Add(new CPUx86.Call("eax"));
|
||||
aAssembler.Add(new CPUx86.Pop("eax"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ namespace Indy.IL2CPU.IL {
|
|||
public Argument(int aSize, int aOffset, KindEnum aKind) {
|
||||
Size = aSize;
|
||||
Offset = aOffset;
|
||||
VirtualAddress = "ebp + 0" + (Offset + Size + 4).ToString("X") + "h";
|
||||
VirtualAddresses = new string[Size / 4];
|
||||
for (int i = 0; i < (Size / 4); i++) {
|
||||
VirtualAddresses[i] = "ebp + 0" + (Offset + ((i + 1) * 4) + 4).ToString("X") + "h";
|
||||
|
|
@ -43,8 +42,6 @@ namespace Indy.IL2CPU.IL {
|
|||
Kind = aKind;
|
||||
}
|
||||
|
||||
[Obsolete("Start using VirtualAddresses")]
|
||||
public readonly string VirtualAddress;
|
||||
public readonly string[] VirtualAddresses;
|
||||
public readonly int Size;
|
||||
public readonly int Offset;
|
||||
|
|
@ -88,7 +85,7 @@ namespace Indy.IL2CPU.IL {
|
|||
}
|
||||
xCurIndex = 0;
|
||||
foreach (Argument xArg in Arguments) {
|
||||
xSB.AppendLine(String.Format("\t({0}) {1}\t{2}\t{3}\r\n", xCurIndex++, xArg.Offset, xArg.Size, xArg.VirtualAddress));
|
||||
xSB.AppendLine(String.Format("\t({0}) {1}\t{2}\t{3}\r\n", xCurIndex++, xArg.Offset, xArg.Size, xArg.VirtualAddresses.FirstOrDefault()));
|
||||
}
|
||||
xSB.AppendLine("\tReturnSize: " + ReturnSize);
|
||||
return xSB.ToString();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.CustomImplementation.System {
|
||||
public static unsafe class DelegateImpl {
|
||||
[MethodAlias(Name = "System.Boolean System.Delegate.InternalEqualTypes(System.Object,System.Object)")]
|
||||
public static bool InternalEqualTypes(uint* aDelegate1, uint* aDelegate2) {
|
||||
return *aDelegate1 == *aDelegate2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.CustomImplementation.System {
|
||||
public static unsafe class MulticastDelegateImpl {
|
||||
//[MethodAlias("System_IntPtr___System_Delegate_GetInvokeMethod____")]
|
||||
public static uint Test(uint* aThis) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,9 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="CustomImplementation\System\ArrayImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\ArrayImplRefs.cs" />
|
||||
<Compile Include="CustomImplementation\System\DelegateImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\EnvironmentImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\MulticastDelegateImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\RuntimeType.RuntimeTypeCache.cs" />
|
||||
<Compile Include="CustomImplementation\System\StringImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\RuntimeType.cs" />
|
||||
|
|
|
|||
|
|
@ -4,8 +4,21 @@ using Mono.Cecil;
|
|||
|
||||
namespace Indy.IL2CPU {
|
||||
public static class ObjectUtilities {
|
||||
private static bool IsDelegate(TypeDefinition aType) {
|
||||
if(aType.BaseType.FullName == "System.Delegate") {
|
||||
return true;
|
||||
}
|
||||
if (aType.BaseType.FullName == "System.Object") {
|
||||
return false;
|
||||
}
|
||||
return IsDelegate(Engine.GetDefinitionFromTypeReference(aType.BaseType));
|
||||
}
|
||||
|
||||
public static int GetObjectStorageSize(TypeDefinition aType) {
|
||||
int xResult = ObjectImpl.FieldDataOffset;
|
||||
if (IsDelegate(aType)) {
|
||||
xResult += 8;
|
||||
}
|
||||
foreach (FieldDefinition xField in aType.Fields) {
|
||||
if (xField.IsStatic) {
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Reference in a new issue