Multicast delegates

This commit is contained in:
mterwoord_cp 2008-05-13 14:27:29 +00:00
parent 2b2ca11fd4
commit cf7d99acb7
15 changed files with 247 additions and 99 deletions

View file

@ -5,9 +5,9 @@ using System.Text;
namespace Indy.IL2CPU.Assembler.X86 { namespace Indy.IL2CPU.Assembler.X86 {
[OpCode(0xFFFFFFFF, "rep movsb")] [OpCode(0xFFFFFFFF, "rep movsb")]
public class RepeatMovsd: Instruction { public class RepeatMovsb: Instruction {
//public readonly string Destination; //public readonly string Destination;
public RepeatMovsd() { public RepeatMovsb() {
// Destination = aDestination; // Destination = aDestination;
} }
//public override string ToString() { //public override string ToString() {

View file

@ -43,7 +43,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
new CPUx86.Move("edx", "[ebp + 0xC]"); new CPUx86.Move("edx", "[ebp + 0xC]");
new CPUx86.Multiply("edx"); new CPUx86.Multiply("edx");
new CPUx86.Move("ecx", "eax"); new CPUx86.Move("ecx", "eax");
new RepeatMovsd(); new RepeatMovsb();
} }
} }
} }

View file

@ -29,7 +29,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
new CPUx86.Add("edi", "eax"); new CPUx86.Add("edi", "eax");
new CPUx86.Move("ecx", "[ebp + 8]"); new CPUx86.Move("ecx", "[ebp + 8]");
new CPUx86.RepeatMovsd(); new CPUx86.RepeatMovsb();
} }
} }
} }

View file

@ -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 {
/// <summary>
/// <para>This method implements Multicast Invoke. This means that it should call all delegates
/// in the current multicast delegate. </para>
/// <para>The argument size is available in the <code>$$ArgSize$$</code> field. This value is already rounded to 4byte boundaries</para>
/// </summary>
/// <param name="aAssembler"></param>
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;
}
}
}

View file

@ -9,17 +9,21 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
//[PlugField(FieldId = "$$Method$$", FieldType = typeof(object))] //[PlugField(FieldId = "$$Method$$", FieldType = typeof(object))]
//[PlugField(FieldId = "$$Object$$", FieldType = typeof(object))] //[PlugField(FieldId = "$$Object$$", FieldType = typeof(object))]
public static class DelegateImpl { 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) { [PlugMethod(Signature = "System_MulticastDelegate__System_Delegate_InternalAllocLike_System_Delegate_")]
// // fake method to have the type Delegate referenced by the assembly public unsafe static uint InternalAllocLike(uint* aDelegate) {
// object o = aDelegate.Target; uint xNeededSize = 1024; // 24 is needed fields for Multicast Delegate
// object o2 = o; 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; }
} }
} }

View file

@ -2,9 +2,16 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Indy.IL2CPU.Plugs;
namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { 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");
}
} }
} }

View file

@ -121,6 +121,7 @@
<Compile Include="CustomImplementations\System\ArrayImpl.cs" /> <Compile Include="CustomImplementations\System\ArrayImpl.cs" />
<Compile Include="CustomImplementations\System\Assemblers\Array_InternalCopy.cs" /> <Compile Include="CustomImplementations\System\Assemblers\Array_InternalCopy.cs" />
<Compile Include="CustomImplementations\System\Assemblers\Buffer_BlockCopy.cs" /> <Compile Include="CustomImplementations\System\Assemblers\Buffer_BlockCopy.cs" />
<Compile Include="CustomImplementations\System\Assemblers\MulticastDelegate_Invoke.cs" />
<Compile Include="CustomImplementations\System\Buffer.cs" /> <Compile Include="CustomImplementations\System\Buffer.cs" />
<Compile Include="CustomImplementations\System\DelegateImpl.cs" /> <Compile Include="CustomImplementations\System\DelegateImpl.cs" />
<Compile Include="CustomImplementations\System\EnumImpl.cs" /> <Compile Include="CustomImplementations\System\EnumImpl.cs" />

View file

@ -31,11 +31,11 @@ namespace Indy.IL2CPU.IL.X86 {
public override void DoAssemble() { public override void DoAssemble() {
string mReturnNullLabel = mThisLabel + "_ReturnNull"; 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.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel); new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtEAX); 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)));
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"); MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");

View file

@ -6,6 +6,7 @@ using System.Reflection;
using CPU = Indy.IL2CPU.Assembler; using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86; using CPUx86 = Indy.IL2CPU.Assembler.X86;
using Indy.IL2CPU.Assembler; using Indy.IL2CPU.Assembler;
using Indy.IL2CPU.IL.X86.CustomImplementations.System;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
public class X86OpCodeMap: OpCodeMap { public class X86OpCodeMap: OpCodeMap {
@ -51,10 +52,11 @@ namespace Indy.IL2CPU.IL.X86 {
public override bool HasCustomAssembleImplementation(MethodInformation aMethodInfo, bool aInMetalMode) { public override bool HasCustomAssembleImplementation(MethodInformation aMethodInfo, bool aInMetalMode) {
switch (aMethodInfo.LabelName) { 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; 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; return true;
} }
case "System_String___System_String_FastAllocateString___System_Int32___": { case "System_String___System_String_FastAllocateString___System_Int32___": {
@ -66,9 +68,10 @@ namespace Indy.IL2CPU.IL.X86 {
case "System_IntPtr___System_Delegate_GetInvokeMethod____": { case "System_IntPtr___System_Delegate_GetInvokeMethod____": {
return true; return true;
} }
//case "System_IntPtr___System_Delegate_GetMulticastInvoke____": { case "System_IntPtr__System_Delegate_GetMulticastInvoke__":
// return true; {
// } return true;
}
case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": { case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": {
return true; 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) { public override void DoCustomAssembleImplementation(bool aInMetalMode, Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
switch (aMethodInfo.LabelName) { 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); Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo);
break; 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); Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo);
break; break;
} }
//case "System_IntPtr___System_Delegate_GetMulticastInvoke____": { case "System_IntPtr__System_Delegate_GetMulticastInvoke__":
// Engine.QueueMethod(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef); {
// new CPUx86.Push(CPU.Label.GenerateLabelName(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef)); //IL.X86.Op.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
// break;
// } Engine.QueueMethod(InvokeMulticastRef);
new CPUx86.Push(Label.GenerateLabelName(InvokeMulticastRef));
break;
}
case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": { case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": {
break; break;
} }
@ -118,6 +127,18 @@ namespace Indy.IL2CPU.IL.X86 {
xOp.Assembler = aAssembler; xOp.Assembler = aAssembler;
xOp.ProxiedMethod = CustomImplementations.System.EventHandlerImplRefs.CtorRef; xOp.ProxiedMethod = CustomImplementations.System.EventHandlerImplRefs.CtorRef;
xOp.Assemble(); 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; break;
} }
if (aMethodInfo.Method.Name == "Invoke") { if (aMethodInfo.Method.Name == "Invoke") {
@ -126,18 +147,25 @@ namespace Indy.IL2CPU.IL.X86 {
// param 2 is eventargs // param 2 is eventargs
new Label(".LoadTargetObject"); new Label(".LoadTargetObject");
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target"); //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target");
new Label(".LoadMethodParams"); //new Label(".LoadMethodParams");
for (int i = 1; i < aMethodInfo.Arguments.Length; i++) { //for (int i = 1; i < aMethodInfo.Arguments.Length; i++) {
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]); // Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]);
} //}
new Label(".LoadMethodPointer"); //new Label(".LoadMethodPointer");
Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); //Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]);
Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr"); //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr");
new CPUx86.Pop("eax"); //new CPUx86.Pop("eax");
new CPUx86.Call(CPUx86.Registers.EAX); //new CPUx86.Call(CPUx86.Registers.EAX);
new CPUx86.Add("esp", //new CPUx86.Add("esp",
"4"); // "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.Pop(CPUx86.Registers.EAX);
//new CPUx86.Move("esp", "ebp"); //new CPUx86.Move("esp", "ebp");
break; break;

View file

@ -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;
}
}
}

View file

@ -64,6 +64,7 @@
<Compile Include="Extensions.cs" /> <Compile Include="Extensions.cs" />
<Compile Include="ILReader.cs" /> <Compile Include="ILReader.cs" />
<Compile Include="ILReader.Utilities.cs" /> <Compile Include="ILReader.Utilities.cs" />
<Compile Include="INeedsMethodInfo.cs" />
<Compile Include="InitVmtImplementationOp.cs" /> <Compile Include="InitVmtImplementationOp.cs" />
<Compile Include="MainEntryPointOp.cs" /> <Compile Include="MainEntryPointOp.cs" />
<Compile Include="MethodFooterOp.cs" /> <Compile Include="MethodFooterOp.cs" />

View file

@ -44,6 +44,7 @@ namespace Indy.IL2CPU.IL {
int aOffset, int aOffset,
KindEnum aKind, KindEnum aKind,
bool aIsReferenceType, bool aIsReferenceType,
TypeInformation aTypeInfo,
Type aArgumentType) { Type aArgumentType) {
mSize = aSize; mSize = aSize;
mVirtualAddresses = new string[mSize / 4]; mVirtualAddresses = new string[mSize / 4];
@ -51,6 +52,7 @@ namespace Indy.IL2CPU.IL {
mArgumentType = aArgumentType; mArgumentType = aArgumentType;
mIsReferenceType = aIsReferenceType; mIsReferenceType = aIsReferenceType;
mOffset = -1; mOffset = -1;
TypeInfo = aTypeInfo;
Offset = aOffset; Offset = aOffset;
} }
@ -124,6 +126,8 @@ namespace Indy.IL2CPU.IL {
mArgumentType = value; mArgumentType = value;
} }
} }
public readonly TypeInformation TypeInfo;
} }
public MethodInformation(string aLabelName, public MethodInformation(string aLabelName,

View file

@ -90,28 +90,19 @@ namespace Indy.IL2CPU.IL {
} }
public virtual void DoCustomAssembleImplementation(bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { public virtual void DoCustomAssembleImplementation(bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
PlugMethodAttribute xAttrib = (PlugMethodAttribute)aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast<PlugMethodAttribute>().FirstOrDefault(); PlugMethodAttribute xAttrib = aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast<PlugMethodAttribute>().FirstOrDefault();
if (xAttrib != null) { if (xAttrib != null) {
Type xAssemblerType = xAttrib.MethodAssembler; Type xAssemblerType = xAttrib.MethodAssembler;
if (xAssemblerType != null) { 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); 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) { public virtual void PostProcess(Assembler.Assembler aAssembler) {
} }

View file

@ -578,8 +578,7 @@ namespace Indy.IL2CPU {
if (xTD.BaseType == null) { if (xTD.BaseType == null) {
continue; continue;
} }
if (xMethod.IsVirtual && !xMethod.IsConstructor && if (xMethod.IsVirtual && !xMethod.IsConstructor) {
!xMethod.IsFinal) {
Type xCurrentInspectedType = xTD.BaseType; Type xCurrentInspectedType = xTD.BaseType;
ParameterInfo[] xParams = xMethod.GetParameters(); ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length]; Type[] xMethodParams = new Type[xParams.Length];
@ -639,8 +638,7 @@ namespace Indy.IL2CPU {
break; break;
} }
aCurrentInspectedType = aCurrentInspectedType.BaseType; aCurrentInspectedType = aCurrentInspectedType.BaseType;
MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, aMethodParams, new ParameterModifier[0]);
aMethodParams);
ParameterInfo[] xParams = xFoundMethod.GetParameters(); ParameterInfo[] xParams = xFoundMethod.GetParameters();
bool xContinue = true; bool xContinue = true;
for (int i = 0; i < xParams.Length; i++) { for (int i = 0; i < xParams.Length; i++) {
@ -654,7 +652,12 @@ namespace Indy.IL2CPU {
continue; continue;
} }
if (xFoundMethod != null) { 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) { xFoundMethod.IsFinal == false) {
xBaseMethod = xFoundMethod; xBaseMethod = xFoundMethod;
} }
@ -1445,6 +1448,7 @@ namespace Indy.IL2CPU {
xCurOffset, xCurOffset,
xKind, xKind,
!xParamDef.ParameterType.IsValueType, !xParamDef.ParameterType.IsValueType,
GetTypeInfo(xParamDef.ParameterType),
xParamDef.ParameterType); xParamDef.ParameterType);
xCurOffset += xArgSize; xCurOffset += xArgSize;
} }
@ -1454,6 +1458,7 @@ namespace Indy.IL2CPU {
xCurOffset, xCurOffset,
MethodInformation.Argument.KindEnum.In, MethodInformation.Argument.KindEnum.In,
!aCurrentMethodForArguments.DeclaringType.IsValueType, !aCurrentMethodForArguments.DeclaringType.IsValueType,
GetTypeInfo(aCurrentMethodForArguments.DeclaringType),
aCurrentMethodForArguments.DeclaringType); aCurrentMethodForArguments.DeclaringType);
} else { } else {
ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters(); ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters();
@ -1477,6 +1482,7 @@ namespace Indy.IL2CPU {
xCurOffset, xCurOffset,
xKind, xKind,
!xParamDef.ParameterType.IsValueType, !xParamDef.ParameterType.IsValueType,
GetTypeInfo(xParamDef.ParameterType),
xParamDef.ParameterType); xParamDef.ParameterType);
xCurOffset += xArgSize; xCurOffset += xArgSize;
} }
@ -1509,7 +1515,7 @@ namespace Indy.IL2CPU {
out aObjectStorageSize); out aObjectStorageSize);
} }
private static void GetTypeFieldInfoImpl(Dictionary<string, TypeInformation.Field> aTypeFields, private static void GetTypeFieldInfoImpl(List<KeyValuePair<string, TypeInformation.Field>> aTypeFields,
Type aType, Type aType,
ref int aObjectStorageSize) { ref int aObjectStorageSize) {
Type xActualType = aType; Type xActualType = aType;
@ -1522,7 +1528,8 @@ namespace Indy.IL2CPU {
item.Value); 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) { if (xField.IsStatic) {
continue; continue;
} }
@ -1557,9 +1564,9 @@ namespace Indy.IL2CPU {
xFieldSize = GetFieldStorageSize(xFieldType); xFieldSize = GetFieldStorageSize(xFieldType);
} }
//} //}
if (aTypeFields.ContainsKey(xFieldId)) { if ((from item in aTypeFields
continue; where item.Key == xFieldId
} select item).Count() > 0) { continue; }
int xOffset = aObjectStorageSize; int xOffset = aObjectStorageSize;
FieldOffsetAttribute xOffsetAttrib = xField.GetCustomAttributes(typeof(FieldOffsetAttribute), FieldOffsetAttribute xOffsetAttrib = xField.GetCustomAttributes(typeof(FieldOffsetAttribute),
true).FirstOrDefault() as FieldOffsetAttribute; true).FirstOrDefault() as FieldOffsetAttribute;
@ -1569,13 +1576,13 @@ namespace Indy.IL2CPU {
aObjectStorageSize += xFieldSize; aObjectStorageSize += xFieldSize;
xOffset = -1; xOffset = -1;
} }
aTypeFields.Add(xField.GetFullName(), aTypeFields.Insert(0, new KeyValuePair<string,TypeInformation.Field>(xField.GetFullName(),
new TypeInformation.Field(xFieldSize, new TypeInformation.Field(xFieldSize,
xFieldType.IsClass && !xFieldType.IsValueType, xFieldType.IsClass && !xFieldType.IsValueType,
xFieldType, xFieldType,
(xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue)) { (xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue)) {
Offset = xOffset Offset = xOffset
}); }));
} }
while (xCurrentPlugFieldList.Count > 0) { while (xCurrentPlugFieldList.Count > 0) {
var xItem = xCurrentPlugFieldList.Values.First(); var xItem = xCurrentPlugFieldList.Values.First();
@ -1594,11 +1601,11 @@ namespace Indy.IL2CPU {
} }
int xOffset = aObjectStorageSize; int xOffset = aObjectStorageSize;
aObjectStorageSize += xFieldSize; aObjectStorageSize += xFieldSize;
aTypeFields.Add(xItem.FieldId, aTypeFields.Insert(0, new KeyValuePair<string,TypeInformation.Field>(xItem.FieldId,
new TypeInformation.Field(xFieldSize, new TypeInformation.Field(xFieldSize,
xFieldType.IsClass && !xFieldType.IsValueType, xFieldType.IsClass && !xFieldType.IsValueType,
xFieldType, xFieldType,
xItem.IsExternalValue)); xItem.IsExternalValue)));
} }
if (aType.FullName != "System.Object" && if (aType.FullName != "System.Object" &&
aType.BaseType != null) { aType.BaseType != null) {
@ -1611,7 +1618,7 @@ namespace Indy.IL2CPU {
public static Dictionary<string, TypeInformation.Field> GetTypeFieldInfo(Type aType, public static Dictionary<string, TypeInformation.Field> GetTypeFieldInfo(Type aType,
out int aObjectStorageSize) { out int aObjectStorageSize) {
Dictionary<string, TypeInformation.Field> xTypeFields = new Dictionary<string, TypeInformation.Field>(); var xTypeFields = new List<KeyValuePair<string, TypeInformation.Field>>();
aObjectStorageSize = 0; aObjectStorageSize = 0;
GetTypeFieldInfoImpl(xTypeFields, GetTypeFieldInfoImpl(xTypeFields,
aType, aType,
@ -1619,8 +1626,8 @@ namespace Indy.IL2CPU {
if (aType.IsExplicitLayout) { if (aType.IsExplicitLayout) {
var xStructLayout = aType.StructLayoutAttribute; var xStructLayout = aType.StructLayoutAttribute;
if (xStructLayout.Size == 0) { if (xStructLayout.Size == 0) {
aObjectStorageSize = (from item in xTypeFields.Values aObjectStorageSize = (from item in xTypeFields
let xSize = item.Offset + item.Size let xSize = item.Value.Offset + item.Value.Size
orderby xSize orderby xSize
select xSize).FirstOrDefault(); select xSize).FirstOrDefault();
} else { } else {
@ -1629,10 +1636,9 @@ namespace Indy.IL2CPU {
} }
int xOffset = 0; int xOffset = 0;
Dictionary<string, TypeInformation.Field> xResult = new Dictionary<string, TypeInformation.Field>(); Dictionary<string, TypeInformation.Field> xResult = new Dictionary<string, TypeInformation.Field>();
foreach (var item in xTypeFields.Reverse()) { foreach (var item in xTypeFields) {
var xItem = item.Value; var xItem = item.Value;
if (item.Value.Offset == if (item.Value.Offset == -1) {
-1) {
xItem.Offset = xOffset; xItem.Offset = xOffset;
xOffset += xItem.Size; xOffset += xItem.Size;
} }
@ -1700,6 +1706,7 @@ namespace Indy.IL2CPU {
if (mCurrent == null) { if (mCurrent == null) {
throw new Exception("ERROR: No Current Engine found!"); throw new Exception("ERROR: No Current Engine found!");
} }
if (aMethod == null) { System.Diagnostics.Debugger.Break(); }
if (!aMethod.IsStatic) { if (!aMethod.IsStatic) {
RegisterType(aMethod.DeclaringType); RegisterType(aMethod.DeclaringType);
} }
@ -1739,8 +1746,12 @@ namespace Indy.IL2CPU {
aType.GetArrayRank() != 1) { aType.GetArrayRank() != 1) {
throw new Exception("Multidimensional arrays are not yet supported!"); throw new Exception("Multidimensional arrays are not yet supported!");
} }
if (aType.IsArray) { aType = typeof(Array); }
else
{
aType = aType.GetElementType(); aType = aType.GetElementType();
} }
}
Type xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName)); Type xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName));
if (xFoundItem == null) { if (xFoundItem == null) {
mCurrent.mTypes.Add(aType); mCurrent.mTypes.Add(aType);

View file

@ -20,33 +20,29 @@ namespace MatthijsTest
#endregion #endregion
public static void GetResumeAndResume(ref uint aSuspend)
{
aSuspend = 0;
throw new NotImplementedException();
}
public static int GetValue() {
return 5; }
public static void Init() public static void Init()
{ {
Console.Clear(); Console.Clear();
Console.WriteLine("Kernel started!"); Console.WriteLine("Kernel started!");
int xTest = 987; Console.WriteLine("Starting doing tests");
IntPtr xPtr = (IntPtr)xTest; DoIt();
xTest = (int)xPtr; Console.WriteLine("Done");
Console.Write("Value: ");
Console.Write(xTest.ToString());
Console.WriteLine();
}
} }
public interface ITest { public class TestType { public void DoIt(object sender, EventArgs e) { Console.WriteLine("Writeline from an instance method!"); } }
void DoMessage();}
public class TestImpl : ITest { public static void DoIt()
public void DoMessage() { {
Console.WriteLine("Message from interface member"); 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"); }
} }
} }