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 {
[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() {

View file

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

View file

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

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 = "$$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; }
}
}

View file

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

View file

@ -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" />

View file

@ -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");

View file

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

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="ILReader.cs" />
<Compile Include="ILReader.Utilities.cs" />
<Compile Include="INeedsMethodInfo.cs" />
<Compile Include="InitVmtImplementationOp.cs" />
<Compile Include="MainEntryPointOp.cs" />
<Compile Include="MethodFooterOp.cs" />

View file

@ -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,

View file

@ -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) {
}

View file

@ -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) {

View file

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