mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 05:18:38 +00:00
Multicast delegates
This commit is contained in:
parent
2b2ca11fd4
commit
cf7d99acb7
15 changed files with 247 additions and 99 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
<Compile Include="CustomImplementations\System\ArrayImpl.cs" />
|
||||
<Compile Include="CustomImplementations\System\Assemblers\Array_InternalCopy.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\DelegateImpl.cs" />
|
||||
<Compile Include="CustomImplementations\System\EnumImpl.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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
12
source/Indy.IL2CPU.IL/INeedsMethodInfo.cs
Normal file
12
source/Indy.IL2CPU.IL/INeedsMethodInfo.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@
|
|||
<Compile Include="Extensions.cs" />
|
||||
<Compile Include="ILReader.cs" />
|
||||
<Compile Include="ILReader.Utilities.cs" />
|
||||
<Compile Include="INeedsMethodInfo.cs" />
|
||||
<Compile Include="InitVmtImplementationOp.cs" />
|
||||
<Compile Include="MainEntryPointOp.cs" />
|
||||
<Compile Include="MethodFooterOp.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,
|
||||
|
|
|
|||
|
|
@ -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<PlugMethodAttribute>().FirstOrDefault();
|
||||
PlugMethodAttribute xAttrib = aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast<PlugMethodAttribute>().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) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<string, TypeInformation.Field> aTypeFields,
|
||||
private static void GetTypeFieldInfoImpl(List<KeyValuePair<string, TypeInformation.Field>> 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<string,TypeInformation.Field>(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<string,TypeInformation.Field>(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<string, TypeInformation.Field> GetTypeFieldInfo(Type aType,
|
||||
out int aObjectStorageSize) {
|
||||
Dictionary<string, TypeInformation.Field> xTypeFields = new Dictionary<string, TypeInformation.Field>();
|
||||
var xTypeFields = new List<KeyValuePair<string, TypeInformation.Field>>();
|
||||
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<string, TypeInformation.Field> xResult = new Dictionary<string, TypeInformation.Field>();
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue