From cf7d99acb742bfb20400a974016f4a128d96a8f2 Mon Sep 17 00:00:00 2001
From: mterwoord_cp <7cd3fd84a0151ea055c2f79e4d2eef9576fe9afesxUZAwxD>
Date: Tue, 13 May 2008 14:27:29 +0000
Subject: [PATCH] Multicast delegates
---
.../Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs | 4 +-
.../System/Assemblers/Array_InternalCopy.cs | 2 +-
.../System/Assemblers/Buffer_BlockCopy.cs | 2 +-
.../Assemblers/MulticastDelegate_Invoke.cs | 93 +++++++++++++++++++
.../System/DelegateImpl.cs | 24 +++--
.../System/MulticastDelegateImpl.cs | 11 ++-
.../Indy.IL2CPU.IL.X86.csproj | 1 +
source/Indy.IL2CPU.IL.X86/Isinst.cs | 4 +-
source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs | 78 +++++++++++-----
source/Indy.IL2CPU.IL/INeedsMethodInfo.cs | 12 +++
source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj | 1 +
source/Indy.IL2CPU.IL/MethodInformation.cs | 4 +
source/Indy.IL2CPU.IL/OpCodeMap.cs | 21 ++---
source/Indy.IL2CPU/Engine.cs | 53 ++++++-----
source/MatthijsTest/Program.cs | 36 ++++---
15 files changed, 247 insertions(+), 99 deletions(-)
create mode 100644 source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs
create mode 100644 source/Indy.IL2CPU.IL/INeedsMethodInfo.cs
diff --git a/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs b/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs
index 6fae12752..a3d94fa7f 100644
--- a/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs
+++ b/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs
@@ -5,9 +5,9 @@ using System.Text;
namespace Indy.IL2CPU.Assembler.X86 {
[OpCode(0xFFFFFFFF, "rep movsb")]
- public class RepeatMovsd: Instruction {
+ public class RepeatMovsb: Instruction {
//public readonly string Destination;
- public RepeatMovsd() {
+ public RepeatMovsb() {
// Destination = aDestination;
}
//public override string ToString() {
diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs
index ab75fccb8..84871fecc 100644
--- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs
+++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs
@@ -43,7 +43,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
new CPUx86.Move("edx", "[ebp + 0xC]");
new CPUx86.Multiply("edx");
new CPUx86.Move("ecx", "eax");
- new RepeatMovsd();
+ new RepeatMovsb();
}
}
}
diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs
index 045bcf757..abfa2d01c 100644
--- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs
+++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs
@@ -29,7 +29,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
new CPUx86.Add("edi", "eax");
new CPUx86.Move("ecx", "[ebp + 8]");
- new CPUx86.RepeatMovsd();
+ new CPUx86.RepeatMovsb();
}
}
}
\ No newline at end of file
diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs
new file mode 100644
index 000000000..b2e9b2e81
--- /dev/null
+++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Indy.IL2CPU.Plugs;
+using CPUx86 = Indy.IL2CPU.Assembler.X86;
+using CPU = Indy.IL2CPU.Assembler;
+
+namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
+ public class MulticastDelegate_Invoke : AssemblerMethod, INeedsMethodInfo {
+ ///
+ /// This method implements Multicast Invoke. This means that it should call all delegates
+ /// in the current multicast delegate.
+ /// The argument size is available in the $$ArgSize$$ field. This value is already rounded to 4byte boundaries
+ ///
+ ///
+ public override void Assemble(Assembler.Assembler aAssembler) {
+ if (MethodInfo == null) {
+ throw new Exception("This AssemblerMethod needs MethodInfo!");
+ }
+ /*
+ * EAX contains the GetInvocationList() array at the index at which it was last used
+ * EDX contains the index at which the EAX is
+ * EBX contains the number of items in the array
+ * ECX contains the argument size
+ */
+ new CPU.Label("____DEBUG_FOR_MULTICAST___");
+ new CPUx86.Move("eax", "[" + MethodInfo.Arguments[0].VirtualAddresses[0] + "]");
+ var xGetInvocationListMethod = typeof(MulticastDelegate).GetMethod("GetInvocationList");
+ new CPUx86.Push("eax");
+ new CPUx86.Call(CPU.Label.GenerateLabelName(xGetInvocationListMethod));
+ new CPUx86.Pop("eax");
+ new CPUx86.Add("eax", "8");
+ new CPUx86.Move("ebx", "[eax]");
+ new CPUx86.Add("eax", "8");
+ new CPUx86.Move("edi", "0");
+ new CPUx86.Move("ecx", "[" + MethodInfo.Arguments[0].VirtualAddresses[0] + "]");
+ new CPUx86.Move("ecx", "[ecx + " + (MethodInfo.Arguments[0].TypeInfo.Fields["$$ArgSize$$"].Offset + 12) + "]");
+
+ new CPU.Label(".BEGIN_OF_LOOP");
+ new CPUx86.Compare("edx", "ebx");
+ new CPUx86.JumpIfEqual(".END_OF_INVOKE_");
+ new CPUx86.Pushad();
+ new CPUx86.Move("edi", "[eax]");
+ new CPUx86.Move("edi", "[edi + " + (MethodInfo.Arguments[0].TypeInfo.Fields["System.Object System.Delegate._target"].Offset+12) + "]");
+ new CPUx86.Compare("edi", "0");
+ new CPUx86.JumpIfZero(".NO_THIS");
+ new CPUx86.Push("edi");
+
+ new CPU.Label(".NO_THIS");
+ new CPUx86.Sub("esp", "ecx");
+ new CPUx86.Move("esi",
+ "esp");
+ new CPUx86.Compare("edi", "0");
+ new CPUx86.JumpIfZero(".NO_THIS2");
+ new CPUx86.Add("esi", "4");
+
+ new CPU.Label(".NO_THIS2");
+ new CPUx86.Move("edi", "[eax]");
+ new CPUx86.Move("edi", "[edi + " + (MethodInfo.Arguments[0].TypeInfo.Fields["System.IntPtr System.Delegate._methodPtr"].Offset + 12) + "]");
+ new CPUx86.Push("edi");
+ new CPUx86.Move("edi", "esp");
+ new CPUx86.Add("edi", "4");
+ // substract twice
+ new CPUx86.Add("esi",
+ "ecx");
+ new CPUx86.Add("esi",
+ "ecx");
+ new CPUx86.Add("esi",
+ "40"); // 32 for the Pushad, 16 for the method header
+ new CPUx86.RepeatMovsb();
+ new CPUx86.Pop("edi");
+ new CPUx86.Call("edi");
+ new CPUx86.Popad();
+ new CPUx86.Add("edx",
+ "1");
+ new CPUx86.Add("eax", "4");
+ new CPUx86.Jump(".BEGIN_OF_LOOP");
+
+ new CPU.Label(".END_OF_INVOKE_");
+ //MethodInfo.Arguments[0].
+// new CPUx86.Move("ebx", "[eax + " + (MethodInfo.Arguments[0].TypeInfo.Fields["$$ArgSize$$"].Offset + 12) + "]");
+
+ //new CPUx86.Move("eax", CPUx86.Registers.
+ }
+
+ public MethodInformation MethodInfo
+ {
+ get;
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs
index 916338f3c..48c25556d 100644
--- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs
+++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs
@@ -9,17 +9,21 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
//[PlugField(FieldId = "$$Method$$", FieldType = typeof(object))]
//[PlugField(FieldId = "$$Object$$", FieldType = typeof(object))]
public static class DelegateImpl {
- //[PlugMethod(Signature = "System_IntPtr___System_Delegate_GetInvokeMethod____")]
- //public static unsafe uint GetInvokeMethod(uint* aThis, [FieldAccess(Name = "$$Method$$")]uint aInvokeMethod) {
- // //return *(aThis + 2);
- // return aInvokeMethod;
- //}
- //public static void DoSomethingWithDelegate(Delegate aDelegate) {
- // // fake method to have the type Delegate referenced by the assembly
- // object o = aDelegate.Target;
- // object o2 = o;
+ [PlugMethod(Signature = "System_MulticastDelegate__System_Delegate_InternalAllocLike_System_Delegate_")]
+ public unsafe static uint InternalAllocLike(uint* aDelegate) {
+ uint xNeededSize = 1024; // 24 is needed fields for Multicast Delegate
+ xNeededSize += 12;
+ uint xResultAddr = GCImplementation.AllocNewObject(xNeededSize);
+ byte* xResult = (byte*)xResultAddr;
+ byte* xDelegateAsByte = (byte*)aDelegate;
+ for (int i = 0; i < 1024; i++)
+ {
+ xResult[i] = xDelegateAsByte[i];
+ }
+ return xResultAddr;
+ }
- //}
+ public static IntPtr GetInvokeMethod() { return IntPtr.Zero; }
}
}
\ No newline at end of file
diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs
index 9c2645823..2b8567e33 100644
--- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs
+++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs
@@ -2,9 +2,16 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Indy.IL2CPU.Plugs;
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
- public static unsafe class MulticastDelegateImpl {
-
+ [Plug(Target=typeof(MulticastDelegate))]
+ [PlugField(FieldType=typeof(int), FieldId="$$ArgSize$$")]
+ public class MulticastDelegateImpl {
+ [PlugMethod(MethodAssembler=typeof(Assemblers.MulticastDelegate_Invoke))]
+ public static void InvokeMulticast(MulticastDelegate aThis)
+ {
+ throw new Exception("This method should be implemented using a MethodAssembler");
+ }
}
}
diff --git a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj
index 5c3621351..7086df128 100644
--- a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj
+++ b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj
@@ -121,6 +121,7 @@
+
diff --git a/source/Indy.IL2CPU.IL.X86/Isinst.cs b/source/Indy.IL2CPU.IL.X86/Isinst.cs
index 914070b5e..64b7743e5 100644
--- a/source/Indy.IL2CPU.IL.X86/Isinst.cs
+++ b/source/Indy.IL2CPU.IL.X86/Isinst.cs
@@ -31,11 +31,11 @@ namespace Indy.IL2CPU.IL.X86 {
public override void DoAssemble() {
string mReturnNullLabel = mThisLabel + "_ReturnNull";
- new CPUx86.Move(CPUx86.Registers.EAX, CPUx86.Registers.AtESP);
+ new CPUx86.Move(CPUx86.Registers.EAX, "[esp]");
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
- new CPUx86.Pushd("0" + mTypeId );
+ new CPUx86.Pushd("0x" + mTypeId.ToString("X"));
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");
diff --git a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs
index b06ef0215..3fa75cf83 100644
--- a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs
+++ b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86;
using Indy.IL2CPU.Assembler;
+using Indy.IL2CPU.IL.X86.CustomImplementations.System;
namespace Indy.IL2CPU.IL.X86 {
public class X86OpCodeMap: OpCodeMap {
@@ -51,10 +52,11 @@ namespace Indy.IL2CPU.IL.X86 {
public override bool HasCustomAssembleImplementation(MethodInformation aMethodInfo, bool aInMetalMode) {
switch (aMethodInfo.LabelName) {
- case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": {
+ 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___": {
+ case "System_Int32__System_Threading_Interlocked_CompareExchange_System_Int32___System_Int32__System_Int32_": {
return true;
}
case "System_String___System_String_FastAllocateString___System_Int32___": {
@@ -66,9 +68,10 @@ namespace Indy.IL2CPU.IL.X86 {
case "System_IntPtr___System_Delegate_GetInvokeMethod____": {
return true;
}
- //case "System_IntPtr___System_Delegate_GetMulticastInvoke____": {
- // return true;
- // }
+ case "System_IntPtr__System_Delegate_GetMulticastInvoke__":
+ {
+ return true;
+ }
case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": {
return true;
}
@@ -87,21 +90,27 @@ namespace Indy.IL2CPU.IL.X86 {
}
}
+ private static readonly MethodBase InvokeMulticastRef = typeof(MulticastDelegateImpl).GetMethod("InvokeMulticast", BindingFlags.Public | BindingFlags.Static);
+
public override void DoCustomAssembleImplementation(bool aInMetalMode, Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
switch (aMethodInfo.LabelName) {
- case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": {
+ case "System_Object__System_Threading_Interlocked_CompareExchange_System_Object___System_Object__System_Object_":
+ {
Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo);
break;
}
- case "System_Int32___System_Threading_Interlocked_CompareExchange___System_Int32___System_Int32__System_Int32___": {
+ case "System_Int32__System_Threading_Interlocked_CompareExchange_System_Int32___System_Int32__System_Int32_": {
Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo);
break;
}
- //case "System_IntPtr___System_Delegate_GetMulticastInvoke____": {
- // Engine.QueueMethod(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef);
- // new CPUx86.Push(CPU.Label.GenerateLabelName(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef));
- // break;
- // }
+ case "System_IntPtr__System_Delegate_GetMulticastInvoke__":
+ {
+ //IL.X86.Op.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
+
+ Engine.QueueMethod(InvokeMulticastRef);
+ new CPUx86.Push(Label.GenerateLabelName(InvokeMulticastRef));
+ break;
+ }
case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": {
break;
}
@@ -118,26 +127,45 @@ namespace Indy.IL2CPU.IL.X86 {
xOp.Assembler = aAssembler;
xOp.ProxiedMethod = CustomImplementations.System.EventHandlerImplRefs.CtorRef;
xOp.Assemble();
+ Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
+ //
+ var xInvokeMethod = aMethodInfo.TypeInfo.TypeDef.GetMethod("Invoke");
+ var xDelegateMethodInfo = Engine.GetMethodInfo(xInvokeMethod, xInvokeMethod, xInvokeMethod.Name, aMethodInfo.TypeInfo, aMethodInfo.DebugMode);
+ int xArgSize = (from item in xDelegateMethodInfo.Arguments
+ select item.Size + (item.Size % 4 == 0
+ ? 0
+ : (4 - (item.Size % 4)))).Take(xDelegateMethodInfo.Arguments.Length).Sum();
+ new CPUx86.Push((xArgSize-4).ToString());
+ new CPU.Label(".SetArgSize");
+ aAssembler.StackContents.Push(new StackContent(4));
+ Stfld.Stfld(aAssembler, aMethodInfo.TypeInfo, aMethodInfo.TypeInfo.Fields["$$ArgSize$$"]);
break;
}
- if (aMethodInfo.Method.Name == "Invoke") {
+ if (aMethodInfo.Method.Name == "Invoke") {
// param 0 is instance of eventhandler
// param 1 is sender
// param 2 is eventargs
new Label(".LoadTargetObject");
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
- Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target");
- new Label(".LoadMethodParams");
- for (int i = 1; i < aMethodInfo.Arguments.Length; i++) {
- Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]);
- }
- new Label(".LoadMethodPointer");
- Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
- Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr");
- new CPUx86.Pop("eax");
- new CPUx86.Call(CPUx86.Registers.EAX);
- new CPUx86.Add("esp",
- "4");
+ //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target");
+ //new Label(".LoadMethodParams");
+ //for (int i = 1; i < aMethodInfo.Arguments.Length; i++) {
+ // Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]);
+ //}
+ //new Label(".LoadMethodPointer");
+ //Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
+ //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr");
+ //new CPUx86.Pop("eax");
+ //new CPUx86.Call(CPUx86.Registers.EAX);
+ //new CPUx86.Add("esp",
+ // "4");
+ Engine.QueueMethod(InvokeMulticastRef);
+ new CPUx86.Call(Label.GenerateLabelName(InvokeMulticastRef));
+ var xGetInvocationListMethod = typeof(MulticastDelegate).GetMethod("GetInvocationList");
+ Engine.QueueMethod(xGetInvocationListMethod);
+ xGetInvocationListMethod = typeof(Delegate).GetMethod("GetInvocationList");
+ Engine.QueueMethod(xGetInvocationListMethod);
+
// new CPUx86.Pop(CPUx86.Registers.EAX);
//new CPUx86.Move("esp", "ebp");
break;
diff --git a/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs b/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs
new file mode 100644
index 000000000..d4012fb2c
--- /dev/null
+++ b/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Indy.IL2CPU.IL {
+ public interface INeedsMethodInfo {
+ MethodInformation MethodInfo {
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj b/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj
index 0c061605e..449218bda 100644
--- a/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj
+++ b/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj
@@ -64,6 +64,7 @@
+
diff --git a/source/Indy.IL2CPU.IL/MethodInformation.cs b/source/Indy.IL2CPU.IL/MethodInformation.cs
index 068cf8fa8..6b509dfd3 100644
--- a/source/Indy.IL2CPU.IL/MethodInformation.cs
+++ b/source/Indy.IL2CPU.IL/MethodInformation.cs
@@ -44,6 +44,7 @@ namespace Indy.IL2CPU.IL {
int aOffset,
KindEnum aKind,
bool aIsReferenceType,
+ TypeInformation aTypeInfo,
Type aArgumentType) {
mSize = aSize;
mVirtualAddresses = new string[mSize / 4];
@@ -51,6 +52,7 @@ namespace Indy.IL2CPU.IL {
mArgumentType = aArgumentType;
mIsReferenceType = aIsReferenceType;
mOffset = -1;
+ TypeInfo = aTypeInfo;
Offset = aOffset;
}
@@ -124,6 +126,8 @@ namespace Indy.IL2CPU.IL {
mArgumentType = value;
}
}
+
+ public readonly TypeInformation TypeInfo;
}
public MethodInformation(string aLabelName,
diff --git a/source/Indy.IL2CPU.IL/OpCodeMap.cs b/source/Indy.IL2CPU.IL/OpCodeMap.cs
index 78034be71..cba8ac29a 100644
--- a/source/Indy.IL2CPU.IL/OpCodeMap.cs
+++ b/source/Indy.IL2CPU.IL/OpCodeMap.cs
@@ -90,27 +90,18 @@ namespace Indy.IL2CPU.IL {
}
public virtual void DoCustomAssembleImplementation(bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
- PlugMethodAttribute xAttrib = (PlugMethodAttribute)aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast().FirstOrDefault();
+ PlugMethodAttribute xAttrib = aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast().FirstOrDefault();
if (xAttrib != null) {
Type xAssemblerType = xAttrib.MethodAssembler;
if (xAssemblerType != null) {
- AssemblerMethod xAssembler = (AssemblerMethod)Activator.CreateInstance(xAssemblerType);
+ var xAssembler = (AssemblerMethod)Activator.CreateInstance(xAssemblerType);
+ var xNeedsMethodInfo = xAssembler as INeedsMethodInfo;
+ if (xNeedsMethodInfo != null) {
+ xNeedsMethodInfo.MethodInfo = aMethodInfo; }
xAssembler.Assemble(aAssembler);
}
}
- }
-
- private static Type GetType(Assembly aAssembly, string aType) {
- string xActualTypeName = aType;
- if (xActualTypeName.Contains("<") && xActualTypeName.Contains(">")) {
- xActualTypeName = xActualTypeName.Substring(0, xActualTypeName.IndexOf("<"));
- }
- Type xResult = aAssembly.GetType(aType, false);
- if (xResult != null) {
- return xResult;
- }
- throw new Exception("Type '" + aType + "' not found in assembly '" + aAssembly + "'!");
- }
+ }
public virtual void PostProcess(Assembler.Assembler aAssembler) {
}
diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs
index 995e82d49..2e2da9ede 100644
--- a/source/Indy.IL2CPU/Engine.cs
+++ b/source/Indy.IL2CPU/Engine.cs
@@ -578,8 +578,7 @@ namespace Indy.IL2CPU {
if (xTD.BaseType == null) {
continue;
}
- if (xMethod.IsVirtual && !xMethod.IsConstructor &&
- !xMethod.IsFinal) {
+ if (xMethod.IsVirtual && !xMethod.IsConstructor) {
Type xCurrentInspectedType = xTD.BaseType;
ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length];
@@ -639,8 +638,7 @@ namespace Indy.IL2CPU {
break;
}
aCurrentInspectedType = aCurrentInspectedType.BaseType;
- MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name,
- aMethodParams);
+ MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, aMethodParams, new ParameterModifier[0]);
ParameterInfo[] xParams = xFoundMethod.GetParameters();
bool xContinue = true;
for (int i = 0; i < xParams.Length; i++) {
@@ -654,7 +652,12 @@ namespace Indy.IL2CPU {
continue;
}
if (xFoundMethod != null) {
- if (xFoundMethod.IsVirtual == aMethod.IsVirtual && xFoundMethod.IsPrivate == false && xFoundMethod.IsPublic == aMethod.IsPublic && xFoundMethod.IsFamily == aMethod.IsFamily && xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly && xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly &&
+ if (xFoundMethod.IsVirtual == aMethod.IsVirtual &&
+ xFoundMethod.IsPrivate == false &&
+ xFoundMethod.IsPublic == aMethod.IsPublic &&
+ xFoundMethod.IsFamily == aMethod.IsFamily &&
+ xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly &&
+ xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly &&
xFoundMethod.IsFinal == false) {
xBaseMethod = xFoundMethod;
}
@@ -1445,6 +1448,7 @@ namespace Indy.IL2CPU {
xCurOffset,
xKind,
!xParamDef.ParameterType.IsValueType,
+ GetTypeInfo(xParamDef.ParameterType),
xParamDef.ParameterType);
xCurOffset += xArgSize;
}
@@ -1454,6 +1458,7 @@ namespace Indy.IL2CPU {
xCurOffset,
MethodInformation.Argument.KindEnum.In,
!aCurrentMethodForArguments.DeclaringType.IsValueType,
+ GetTypeInfo(aCurrentMethodForArguments.DeclaringType),
aCurrentMethodForArguments.DeclaringType);
} else {
ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters();
@@ -1477,6 +1482,7 @@ namespace Indy.IL2CPU {
xCurOffset,
xKind,
!xParamDef.ParameterType.IsValueType,
+ GetTypeInfo(xParamDef.ParameterType),
xParamDef.ParameterType);
xCurOffset += xArgSize;
}
@@ -1509,7 +1515,7 @@ namespace Indy.IL2CPU {
out aObjectStorageSize);
}
- private static void GetTypeFieldInfoImpl(Dictionary aTypeFields,
+ private static void GetTypeFieldInfoImpl(List> aTypeFields,
Type aType,
ref int aObjectStorageSize) {
Type xActualType = aType;
@@ -1522,7 +1528,8 @@ namespace Indy.IL2CPU {
item.Value);
}
}
- foreach (FieldInfo xField in aType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
+ foreach (FieldInfo xField in aType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
if (xField.IsStatic) {
continue;
}
@@ -1557,9 +1564,9 @@ namespace Indy.IL2CPU {
xFieldSize = GetFieldStorageSize(xFieldType);
}
//}
- if (aTypeFields.ContainsKey(xFieldId)) {
- continue;
- }
+ if ((from item in aTypeFields
+ where item.Key == xFieldId
+ select item).Count() > 0) { continue; }
int xOffset = aObjectStorageSize;
FieldOffsetAttribute xOffsetAttrib = xField.GetCustomAttributes(typeof(FieldOffsetAttribute),
true).FirstOrDefault() as FieldOffsetAttribute;
@@ -1569,13 +1576,13 @@ namespace Indy.IL2CPU {
aObjectStorageSize += xFieldSize;
xOffset = -1;
}
- aTypeFields.Add(xField.GetFullName(),
+ aTypeFields.Insert(0, new KeyValuePair(xField.GetFullName(),
new TypeInformation.Field(xFieldSize,
xFieldType.IsClass && !xFieldType.IsValueType,
xFieldType,
(xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue)) {
Offset = xOffset
- });
+ }));
}
while (xCurrentPlugFieldList.Count > 0) {
var xItem = xCurrentPlugFieldList.Values.First();
@@ -1594,11 +1601,11 @@ namespace Indy.IL2CPU {
}
int xOffset = aObjectStorageSize;
aObjectStorageSize += xFieldSize;
- aTypeFields.Add(xItem.FieldId,
+ aTypeFields.Insert(0, new KeyValuePair(xItem.FieldId,
new TypeInformation.Field(xFieldSize,
xFieldType.IsClass && !xFieldType.IsValueType,
xFieldType,
- xItem.IsExternalValue));
+ xItem.IsExternalValue)));
}
if (aType.FullName != "System.Object" &&
aType.BaseType != null) {
@@ -1611,7 +1618,7 @@ namespace Indy.IL2CPU {
public static Dictionary GetTypeFieldInfo(Type aType,
out int aObjectStorageSize) {
- Dictionary xTypeFields = new Dictionary();
+ var xTypeFields = new List>();
aObjectStorageSize = 0;
GetTypeFieldInfoImpl(xTypeFields,
aType,
@@ -1619,8 +1626,8 @@ namespace Indy.IL2CPU {
if (aType.IsExplicitLayout) {
var xStructLayout = aType.StructLayoutAttribute;
if (xStructLayout.Size == 0) {
- aObjectStorageSize = (from item in xTypeFields.Values
- let xSize = item.Offset + item.Size
+ aObjectStorageSize = (from item in xTypeFields
+ let xSize = item.Value.Offset + item.Value.Size
orderby xSize
select xSize).FirstOrDefault();
} else {
@@ -1629,10 +1636,9 @@ namespace Indy.IL2CPU {
}
int xOffset = 0;
Dictionary xResult = new Dictionary();
- foreach (var item in xTypeFields.Reverse()) {
+ foreach (var item in xTypeFields) {
var xItem = item.Value;
- if (item.Value.Offset ==
- -1) {
+ if (item.Value.Offset == -1) {
xItem.Offset = xOffset;
xOffset += xItem.Size;
}
@@ -1700,6 +1706,7 @@ namespace Indy.IL2CPU {
if (mCurrent == null) {
throw new Exception("ERROR: No Current Engine found!");
}
+ if (aMethod == null) { System.Diagnostics.Debugger.Break(); }
if (!aMethod.IsStatic) {
RegisterType(aMethod.DeclaringType);
}
@@ -1739,7 +1746,11 @@ namespace Indy.IL2CPU {
aType.GetArrayRank() != 1) {
throw new Exception("Multidimensional arrays are not yet supported!");
}
- aType = aType.GetElementType();
+ if (aType.IsArray) { aType = typeof(Array); }
+ else
+ {
+ aType = aType.GetElementType();
+ }
}
Type xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName));
if (xFoundItem == null) {
diff --git a/source/MatthijsTest/Program.cs b/source/MatthijsTest/Program.cs
index 5642c0be2..47b4585db 100644
--- a/source/MatthijsTest/Program.cs
+++ b/source/MatthijsTest/Program.cs
@@ -20,33 +20,29 @@ namespace MatthijsTest
#endregion
- public static void GetResumeAndResume(ref uint aSuspend)
- {
- aSuspend = 0;
- throw new NotImplementedException();
- }
- public static int GetValue() {
- return 5; }
+
public static void Init()
{
Console.Clear();
Console.WriteLine("Kernel started!");
- int xTest = 987;
- IntPtr xPtr = (IntPtr)xTest;
- xTest = (int)xPtr;
- Console.Write("Value: ");
- Console.Write(xTest.ToString());
- Console.WriteLine();
+ Console.WriteLine("Starting doing tests");
+ DoIt();
+ Console.WriteLine("Done");
}
- }
- public interface ITest {
- void DoMessage();}
+ public class TestType { public void DoIt(object sender, EventArgs e) { Console.WriteLine("Writeline from an instance method!"); } }
- public class TestImpl : ITest {
- public void DoMessage() {
- Console.WriteLine("Message from interface member");
+ public static void DoIt()
+ {
+ EventHandler xEvent = WriteMessage1;
+ var xType = new TestType();
+ xEvent += xType.DoIt;
+ xEvent += WriteMessage2;
+ xEvent(null, null);
}
+
+ public static void WriteMessage1(object sender, EventArgs e) { Console.WriteLine("Message 1"); }
+ public static void WriteMessage2(object sender, EventArgs e) { Console.WriteLine("Message 2"); }
}
-}
\ No newline at end of file
+}