Cosmos/source/Indy.IL2CPU.IL.X86/Call.cs
2007-09-22 17:31:13 +00:00

58 lines
No EOL
1.5 KiB
C#

using System;
using System.IO;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Asm = Indy.IL2CPU.Assembler;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Call)]
public class Call: Op {
private string LabelName;
private bool HasResult;
private int? TotalArgumentSize = null;
public Call(MethodReference aMethod)
: base(null, null) {
if (aMethod == null) {
throw new ArgumentNullException("aMethod");
}
Initialize(aMethod);
}
private void Initialize(MethodReference aMethod) {
HasResult = !aMethod.ReturnType.ReturnType.FullName.Contains("System.Void");
LabelName = new Asm.Label(aMethod).Name;
Engine.QueueMethodRef(aMethod);
bool needsCleanup = false;
foreach (ParameterDefinition xParam in aMethod.Parameters) {
if (xParam.IsOut) {
needsCleanup = true;
break;
}
}
if (needsCleanup) {
TotalArgumentSize = aMethod.Parameters.Count * 4;
if (Engine.GetDefinitionFromMethodReference(aMethod).IsStatic) {
TotalArgumentSize += 4;
}
}
// todo: add support for other argument sizes
}
public Call(Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
MethodReference xMethod = ((MethodReference)aInstruction.Operand);
Initialize(xMethod);
}
public void Assemble(string aMethod) {
Call(aMethod);
if (HasResult) {
Push(Assembler, "eax");
}
}
public override void DoAssemble() {
Assemble(LabelName);
}
}
}