mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-20 04:48:53 +00:00
This commit is contained in:
parent
b8b6100333
commit
dea9bfb587
2 changed files with 218 additions and 240 deletions
|
|
@ -6,242 +6,219 @@ using Cosmos.IL2CPU.ILOpCodes;
|
|||
using Cosmos.IL2CPU.IL.CustomImplementations.System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cosmos.IL2CPU.X86.IL
|
||||
{
|
||||
[Cosmos.IL2CPU.OpCode( ILOpCode.Code.Newobj )]
|
||||
public class Newobj : ILOp
|
||||
{
|
||||
public Newobj( Cosmos.Compiler.Assembler.Assembler aAsmblr )
|
||||
: base( aAsmblr )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
|
||||
{
|
||||
OpMethod xMethod = ( OpMethod )aOpCode;
|
||||
string xCurrentLabel = GetLabel( aMethod, aOpCode );
|
||||
var xType = xMethod.Value.DeclaringType;
|
||||
|
||||
Assemble(Assembler, aMethod, xMethod, xCurrentLabel, xType, xMethod.Value);
|
||||
}
|
||||
|
||||
public static void Assemble(Assembler aAssembler, MethodInfo aMethod, OpMethod xMethod, string currentLabel, Type objectType, MethodBase constructor)
|
||||
{
|
||||
// call cctor:
|
||||
if (aMethod != null)
|
||||
{
|
||||
var xCctor = (objectType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();
|
||||
if (xCctor != null)
|
||||
{
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(xCctor) };
|
||||
ILOp.EmitExceptionLogic(aAssembler, aMethod, xMethod, true, null, ".AfterCCTorExceptionCheck");
|
||||
new Label(".AfterCCTorExceptionCheck");
|
||||
}
|
||||
}
|
||||
|
||||
// If not ValueType, then we need gc
|
||||
if (!objectType.IsValueType)
|
||||
{
|
||||
var xParams = constructor.GetParameters();
|
||||
for (int i = 0; i < xParams.Length; i++)
|
||||
{
|
||||
aAssembler.Stack.Pop();
|
||||
}
|
||||
|
||||
// array length +8
|
||||
|
||||
bool xHasCalcSize = false;
|
||||
// try calculating size:
|
||||
if (constructor.DeclaringType == typeof(string))
|
||||
{
|
||||
if (xParams.Length == 1 && xParams[0].ParameterType == typeof(char[]))
|
||||
{
|
||||
xHasCalcSize = true;
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true, SourceDisplacement = 8 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceValue = 2 };
|
||||
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
}
|
||||
else if (xParams.Length == 3
|
||||
&& xParams[0].ParameterType == typeof(char[])
|
||||
&& xParams[1].ParameterType == typeof(int)
|
||||
&& xParams[2].ParameterType == typeof(int))
|
||||
{
|
||||
xHasCalcSize = true;
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
}
|
||||
}
|
||||
uint xMemSize = GetStorageSize(objectType);
|
||||
int xExtraSize = 20;
|
||||
new CPUx86.Push { DestinationValue = (uint)(xMemSize + xExtraSize) };
|
||||
if (xHasCalcSize)
|
||||
{
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX };
|
||||
}
|
||||
|
||||
// todo: probably we want to check for exceptions after calling Alloc
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(GCImplementationRefs.AllocNewObjectRef) };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
|
||||
//? ?? uint xObjSize;// = 0;
|
||||
//int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
|
||||
//where item.NeedsGC
|
||||
//select item ).Count();
|
||||
|
||||
//int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
|
||||
//where item.NeedsGC
|
||||
//select item ).Count();
|
||||
int xGCFieldCount = objectType.GetFields().Count(x => x.FieldType.IsValueType);
|
||||
|
||||
// todo: use a cleaner approach here. this class shouldnt assemble the string
|
||||
string strTypeId = GetTypeIDLabel(constructor.DeclaringType);
|
||||
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EBX, SourceRef = ElementReference.New(strTypeId), SourceIsIndirect = true };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EBX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32 };
|
||||
uint xSize = (uint)(((from item in xParams
|
||||
let xQSize = Align(SizeOfType(item.ParameterType), 4)
|
||||
select (int)xQSize).Take(xParams.Length).Sum()));
|
||||
|
||||
foreach (var xParam in xParams)
|
||||
{
|
||||
uint xParamSize = Align(SizeOfType(xParam.ParameterType), 4);
|
||||
new Comment(aAssembler, String.Format("Arg {0}: {1}", xParam.Name, xParamSize));
|
||||
for (int i = 0; i < xParamSize; i += 4) {
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4) };
|
||||
}
|
||||
}
|
||||
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(constructor) };
|
||||
if (aMethod != null)
|
||||
{
|
||||
new CPUx86.Test { DestinationReg = CPUx86.Registers.ECX, SourceValue = 2 };
|
||||
string xNoErrorLabel = currentLabel + "_NO_ERROR_" + MethodInfoLabelGenerator.LabelCount.ToString();
|
||||
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = xNoErrorLabel };
|
||||
|
||||
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
|
||||
//{
|
||||
// new CPUx86.Add
|
||||
// {
|
||||
// DestinationReg = CPUx86.Registers.ESP,
|
||||
// SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
|
||||
// ? aCtorMethodInfo.Arguments[ i ].Size
|
||||
// : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
|
||||
// };
|
||||
//}
|
||||
PushAlignedParameterSize(constructor);
|
||||
// an exception occurred, we need to cleanup the stack, and jump to the exit
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
|
||||
new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]");
|
||||
//foreach( var xStackInt in Assembler.Stack )
|
||||
//{
|
||||
// new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = ( uint )xStackInt.Size };
|
||||
//}
|
||||
|
||||
uint xESPOffset = 0;
|
||||
foreach (var xParam in xParams) {
|
||||
xESPOffset += Align(SizeOfType(xParam.ParameterType), 4);
|
||||
}
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = xESPOffset };
|
||||
|
||||
new Comment(aAssembler, "[ Newobj.Execute cleanup end ]");
|
||||
Jump_Exception(aMethod);
|
||||
new Label(xNoErrorLabel);
|
||||
}
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
|
||||
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
|
||||
//{
|
||||
// new CPUx86.Add
|
||||
// {
|
||||
// DestinationReg = CPUx86.Registers.ESP,
|
||||
// SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
|
||||
// ? aCtorMethodInfo.Arguments[ i ].Size
|
||||
// : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
|
||||
// };
|
||||
//}
|
||||
PushAlignedParameterSize(constructor);
|
||||
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
aAssembler.Stack.Push(4, constructor.DeclaringType);
|
||||
}
|
||||
else
|
||||
{
|
||||
//throw new Exception("Not implemented yet: .ctor on value type");
|
||||
/*
|
||||
* Current sitation on stack:
|
||||
* $ESP Arg
|
||||
* $ESP+.. other items
|
||||
*
|
||||
* What should happen:
|
||||
* + The stack should be increased to allow space to contain:
|
||||
* + .ctor arguments
|
||||
* + struct _pointer_ (ref to start of emptied space)
|
||||
* + empty space for struct
|
||||
* + arguments should be copied to the new place
|
||||
* + old place where arguments were should be cleared
|
||||
* + pointer should be set
|
||||
* + call .ctor
|
||||
*/
|
||||
var xStorageSize = Align(SizeOfType(objectType), 4);
|
||||
//var xStorageSize = aCtorDeclTypeInfo.StorageSize;
|
||||
//uint xArgSize = 0;
|
||||
var xParams = constructor.GetParameters();
|
||||
uint xArgSize = (uint)(((from item in xParams.Skip(1)
|
||||
let xQSize = Align(SizeOfType(item.ParameterType), 4)
|
||||
select (int)xQSize).Take(xParams.Length - 1).Sum()));
|
||||
|
||||
//foreach( var xArg in aCtorMethodInfo.Arguments.Skip( 1 ) )
|
||||
//{
|
||||
// xArgSize += xArg.Size + ( xArg.Size % 4 == 0
|
||||
// ? 0
|
||||
// : ( 4 - ( xArg.Size % 4 ) ) );
|
||||
//}
|
||||
int xExtraArgSize = (int)(xStorageSize - xArgSize);
|
||||
if (xExtraArgSize < 0)
|
||||
{
|
||||
xExtraArgSize = 0;
|
||||
}
|
||||
if (xExtraArgSize > 0) {
|
||||
new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xExtraArgSize };
|
||||
}
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP };
|
||||
aAssembler.Stack.Push(new StackContents.Item(4, null));
|
||||
//at this point, we need to move copy all arguments over.
|
||||
for (int i = 0; i < (xArgSize / 4); i++)
|
||||
{
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xStorageSize + 4) }; // + 4 because the ptr is pushed too
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xStorageSize + 4 + 4), SourceValue = 0, Size = 32 };
|
||||
}
|
||||
new Call(aAssembler).Execute(aMethod, xMethod);
|
||||
//var xCall = new Call( aCtorDef,
|
||||
// ( uint )aCurrentILOffset,
|
||||
// true,
|
||||
// aNextLabel );
|
||||
//xCall.SetServiceProvider( aServiceProvider );
|
||||
//xCall.Assembler = aAssembler;
|
||||
//xCall.Assemble();
|
||||
aAssembler.Stack.Push(new StackContents.Item(xStorageSize, objectType));
|
||||
}
|
||||
}
|
||||
|
||||
private static void PushAlignedParameterSize( System.Reflection.MethodBase aMethod )
|
||||
{
|
||||
System.Reflection.ParameterInfo[] xParams = aMethod.GetParameters();
|
||||
|
||||
uint xSize;
|
||||
new Comment("[ Newobj.PushAlignedParameterSize start count = " + xParams.Length.ToString() + " ]" );
|
||||
for( int i = 0; i < xParams.Length; i++ )
|
||||
{
|
||||
xSize = SizeOfType( xParams[ i ].ParameterType );
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = Align( xSize, 4 ) };
|
||||
}
|
||||
new Comment("[ Newobj.PushAlignedParameterSize end ]" );
|
||||
}
|
||||
namespace Cosmos.IL2CPU.X86.IL {
|
||||
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Newobj)]
|
||||
public class Newobj : ILOp {
|
||||
public Newobj(Cosmos.Compiler.Assembler.Assembler aAsmblr)
|
||||
: base(aAsmblr) {
|
||||
}
|
||||
|
||||
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) {
|
||||
OpMethod xMethod = (OpMethod)aOpCode;
|
||||
string xCurrentLabel = GetLabel(aMethod, aOpCode);
|
||||
var xType = xMethod.Value.DeclaringType;
|
||||
|
||||
Assemble(Assembler, aMethod, xMethod, xCurrentLabel, xType, xMethod.Value);
|
||||
}
|
||||
|
||||
public static void Assemble(Assembler aAssembler, MethodInfo aMethod, OpMethod xMethod, string currentLabel, Type objectType, MethodBase constructor) {
|
||||
// call cctor:
|
||||
if (aMethod != null) {
|
||||
var xCctor = (objectType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();
|
||||
if (xCctor != null) {
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(xCctor) };
|
||||
ILOp.EmitExceptionLogic(aAssembler, aMethod, xMethod, true, null, ".AfterCCTorExceptionCheck");
|
||||
new Label(".AfterCCTorExceptionCheck");
|
||||
}
|
||||
}
|
||||
|
||||
if (objectType.IsValueType) {
|
||||
/*
|
||||
* Current sitation on stack:
|
||||
* $ESP Arg
|
||||
* $ESP+.. other items
|
||||
*
|
||||
* What should happen:
|
||||
* + The stack should be increased to allow space to contain:
|
||||
* + .ctor arguments
|
||||
* + struct _pointer_ (ref to start of emptied space)
|
||||
* + empty space for struct
|
||||
* + arguments should be copied to the new place
|
||||
* + old place where arguments were should be cleared
|
||||
* + pointer should be set
|
||||
* + call .ctor
|
||||
*/
|
||||
var xStorageSize = Align(SizeOfType(objectType), 4);
|
||||
//var xStorageSize = aCtorDeclTypeInfo.StorageSize;
|
||||
//uint xArgSize = 0;
|
||||
var xParams = constructor.GetParameters();
|
||||
uint xArgSize = (uint)(((from item in xParams.Skip(1)
|
||||
let xQSize = Align(SizeOfType(item.ParameterType), 4)
|
||||
select (int)xQSize).Take(xParams.Length - 1).Sum()));
|
||||
|
||||
//foreach( var xArg in aCtorMethodInfo.Arguments.Skip( 1 ) )
|
||||
//{
|
||||
// xArgSize += xArg.Size + ( xArg.Size % 4 == 0
|
||||
// ? 0
|
||||
// : ( 4 - ( xArg.Size % 4 ) ) );
|
||||
//}
|
||||
int xExtraArgSize = (int)(xStorageSize - xArgSize);
|
||||
if (xExtraArgSize < 0) {
|
||||
xExtraArgSize = 0;
|
||||
}
|
||||
if (xExtraArgSize > 0) {
|
||||
new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xExtraArgSize };
|
||||
}
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP };
|
||||
aAssembler.Stack.Push(new StackContents.Item(4, null));
|
||||
//at this point, we need to move copy all arguments over.
|
||||
for (int i = 0; i < (xArgSize / 4); i++) {
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xStorageSize + 4) }; // + 4 because the ptr is pushed too
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xStorageSize + 4 + 4), SourceValue = 0, Size = 32 };
|
||||
}
|
||||
new Call(aAssembler).Execute(aMethod, xMethod);
|
||||
//var xCall = new Call( aCtorDef,
|
||||
// ( uint )aCurrentILOffset,
|
||||
// true,
|
||||
// aNextLabel );
|
||||
//xCall.SetServiceProvider( aServiceProvider );
|
||||
//xCall.Assembler = aAssembler;
|
||||
//xCall.Assemble();
|
||||
aAssembler.Stack.Push(new StackContents.Item(xStorageSize, objectType));
|
||||
} else {
|
||||
// If not ValueType, then we need gc
|
||||
var xParams = constructor.GetParameters();
|
||||
for (int i = 0; i < xParams.Length; i++) {
|
||||
aAssembler.Stack.Pop();
|
||||
}
|
||||
|
||||
// array length +8
|
||||
|
||||
bool xHasCalcSize = false;
|
||||
// try calculating size:
|
||||
if (constructor.DeclaringType == typeof(string)) {
|
||||
if (xParams.Length == 1 && xParams[0].ParameterType == typeof(char[])) {
|
||||
xHasCalcSize = true;
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true, SourceDisplacement = 8 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceValue = 2 };
|
||||
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
} else if (xParams.Length == 3
|
||||
&& xParams[0].ParameterType == typeof(char[])
|
||||
&& xParams[1].ParameterType == typeof(int)
|
||||
&& xParams[2].ParameterType == typeof(int)) {
|
||||
xHasCalcSize = true;
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
}
|
||||
}
|
||||
uint xMemSize = GetStorageSize(objectType);
|
||||
int xExtraSize = 20;
|
||||
new CPUx86.Push { DestinationValue = (uint)(xMemSize + xExtraSize) };
|
||||
if (xHasCalcSize) {
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX };
|
||||
}
|
||||
|
||||
// todo: probably we want to check for exceptions after calling Alloc
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(GCImplementationRefs.AllocNewObjectRef) };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
|
||||
|
||||
//? ?? uint xObjSize;// = 0;
|
||||
//int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
|
||||
//where item.NeedsGC
|
||||
//select item ).Count();
|
||||
|
||||
//int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
|
||||
//where item.NeedsGC
|
||||
//select item ).Count();
|
||||
int xGCFieldCount = objectType.GetFields().Count(x => x.FieldType.IsValueType);
|
||||
|
||||
// todo: use a cleaner approach here. this class shouldnt assemble the string
|
||||
string strTypeId = GetTypeIDLabel(constructor.DeclaringType);
|
||||
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EBX, SourceRef = ElementReference.New(strTypeId), SourceIsIndirect = true };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EBX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32 };
|
||||
uint xSize = (uint)(((from item in xParams
|
||||
let xQSize = Align(SizeOfType(item.ParameterType), 4)
|
||||
select (int)xQSize).Take(xParams.Length).Sum()));
|
||||
|
||||
foreach (var xParam in xParams) {
|
||||
uint xParamSize = Align(SizeOfType(xParam.ParameterType), 4);
|
||||
new Comment(aAssembler, String.Format("Arg {0}: {1}", xParam.Name, xParamSize));
|
||||
for (int i = 0; i < xParamSize; i += 4) {
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4) };
|
||||
}
|
||||
}
|
||||
|
||||
new CPUx86.Call { DestinationLabel = MethodInfoLabelGenerator.GenerateLabelName(constructor) };
|
||||
if (aMethod != null) {
|
||||
new CPUx86.Test { DestinationReg = CPUx86.Registers.ECX, SourceValue = 2 };
|
||||
string xNoErrorLabel = currentLabel + "_NO_ERROR_" + MethodInfoLabelGenerator.LabelCount.ToString();
|
||||
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = xNoErrorLabel };
|
||||
|
||||
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
|
||||
//{
|
||||
// new CPUx86.Add
|
||||
// {
|
||||
// DestinationReg = CPUx86.Registers.ESP,
|
||||
// SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
|
||||
// ? aCtorMethodInfo.Arguments[ i ].Size
|
||||
// : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
|
||||
// };
|
||||
//}
|
||||
PushAlignedParameterSize(constructor);
|
||||
// an exception occurred, we need to cleanup the stack, and jump to the exit
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
|
||||
new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]");
|
||||
//foreach( var xStackInt in Assembler.Stack )
|
||||
//{
|
||||
// new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = ( uint )xStackInt.Size };
|
||||
//}
|
||||
|
||||
uint xESPOffset = 0;
|
||||
foreach (var xParam in xParams) {
|
||||
xESPOffset += Align(SizeOfType(xParam.ParameterType), 4);
|
||||
}
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = xESPOffset };
|
||||
|
||||
new Comment(aAssembler, "[ Newobj.Execute cleanup end ]");
|
||||
Jump_Exception(aMethod);
|
||||
new Label(xNoErrorLabel);
|
||||
}
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
|
||||
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
|
||||
//{
|
||||
// new CPUx86.Add
|
||||
// {
|
||||
// DestinationReg = CPUx86.Registers.ESP,
|
||||
// SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
|
||||
// ? aCtorMethodInfo.Arguments[ i ].Size
|
||||
// : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
|
||||
// };
|
||||
//}
|
||||
PushAlignedParameterSize(constructor);
|
||||
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
aAssembler.Stack.Push(4, constructor.DeclaringType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PushAlignedParameterSize(System.Reflection.MethodBase aMethod) {
|
||||
System.Reflection.ParameterInfo[] xParams = aMethod.GetParameters();
|
||||
|
||||
uint xSize;
|
||||
new Comment("[ Newobj.PushAlignedParameterSize start count = " + xParams.Length.ToString() + " ]");
|
||||
for (int i = 0; i < xParams.Length; i++) {
|
||||
xSize = SizeOfType(xParams[i].ParameterType);
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = Align(xSize, 4) };
|
||||
}
|
||||
new Comment("[ Newobj.PushAlignedParameterSize end ]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,13 +18,14 @@ namespace BreakpointsKernel {
|
|||
}
|
||||
|
||||
public override void Run() {
|
||||
UInt32 x = 32;
|
||||
UInt32 x = 1;
|
||||
|
||||
UInt32? xSize;
|
||||
xSize = 8;
|
||||
xSize = 2;
|
||||
|
||||
aSize = 3;
|
||||
|
||||
mSize = 7;
|
||||
mSize = 4;
|
||||
bool xHasValue = mSize.HasValue; // .HasValue is false
|
||||
Chk(xHasValue);
|
||||
x = mSize.Value;
|
||||
|
|
|
|||
Loading…
Reference in a new issue