Fixed position labels for new assembler.

This commit is contained in:
kudzu_cp 2009-09-08 21:53:19 +00:00
parent 100a788757
commit dc9165e7a1
4 changed files with 46 additions and 8 deletions

View file

@ -22,16 +22,24 @@ namespace Cosmos.IL2CPU.X86 {
base.MethodEnd(aMethod);
}
protected override void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode) {
base.BeforeOp(aMethod, aOpCode);
new Label(TmpPosLabel(aMethod, aOpCode));
}
// These are all temp functions until we move to the new assembler.
// They are used to clean up the old assembler slightly while retaining compatibiltiy for now
public static string TmpPosLabel(MethodInfo aMethod, ILOpCode aOpCode) {
public static string TmpPosLabel(MethodInfo aMethod, int xOffset) {
//TODO: Change to Hex output, will be smaller and slightly faster for NASM
return "_" + aMethod.UID + "_" + aOpCode.Position + "__";
return "POS_" + aMethod.UID + "_" + xOffset;
}
public static string TmpPosLabel(MethodInfo aMethod, ILOpCode aOpCode) {
return TmpPosLabel(aMethod, aOpCode.Position);
}
public static string TmpBranchLabel(MethodInfo aMethod, ILOpCode aOpCode) {
//TODO: Change to Hex output, will be smaller and slightly faster for NASM
return "_" + aMethod.UID + "_" + ((ILOpCodes.OpBranch)aOpCode).Value + "__";
return TmpPosLabel(aMethod, ((ILOpCodes.OpBranch)aOpCode).Value);
}
}

View file

@ -19,8 +19,10 @@ namespace Cosmos.IL2CPU.X86.IL
{
new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceValue = ( uint )i };
//string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) );
//string DestLabel = "_" + aMethod.UID + "_" + OpSw.BranchLocations[ i ] + "__";
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = "_" + aMethod.UID + "_" + OpSw.BranchLocations[ i ] + "__" };
string xDestLabel = AssemblerNasm.TmpPosLabel(aMethod, OpSw.BranchLocations[i]);
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal
, DestinationLabel = xDestLabel
};
}
Assembler.Stack.Pop();
}

View file

@ -107,7 +107,9 @@ namespace Cosmos.IL2CPU {
protected virtual void MethodBegin(MethodInfo aMethod) {
new Comment(this, "---------------------------------------------------------");
new Comment(this, "Begin Method: " + aMethod.MethodBase.Name);
new Comment(this, "Type: " + aMethod.MethodBase.DeclaringType.ToString());
new Comment(this, "Name: " + aMethod.MethodBase.Name);
new Comment(this, "Plugged: " + (aMethod.PlugMethod == null ? "No" : "Yes"));
}
protected virtual void MethodEnd(MethodInfo aMethod) {
@ -139,6 +141,7 @@ namespace Cosmos.IL2CPU {
}
//mLog.Write ( "[" + xILOp.ToString() + "] \t Stack start: " + Stack.Count.ToString() );
new Comment(this, "[" + xILOp.ToString() + "]");
BeforeOp(aMethod, xOpCode);
xILOp.Execute(aMethod, xOpCode);
//mLog.WriteLine( " end: " + Stack.Count.ToString() );
//mLog.Flush();
@ -146,6 +149,9 @@ namespace Cosmos.IL2CPU {
MethodEnd(aMethod);
}
protected virtual void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode) {
}
/// <summary>
/// allows to emit footers to the code and datamember sections
/// </summary>

View file

@ -50,6 +50,7 @@ namespace Cosmos.IL2CPU {
public ILScanner(Assembler aAsmblr) {
mAsmblr = aAsmblr;
mReader = new ILReader();
mThrowHelper = typeof(object).Assembly.GetType("System.ThrowHelper");
}
public void Execute(System.Reflection.MethodInfo aStartMethod) {
@ -273,10 +274,29 @@ namespace Cosmos.IL2CPU {
}
// Assemble the method
mAsmblr.ProcessMethod(aMethodInfo, xOpCodes);
if (aMethodInfo.MethodBase.DeclaringType != mThrowHelper) {
mAsmblr.ProcessMethod(aMethodInfo, xOpCodes);
}
}
}
// System.ThrowHelper exists in MS .NET twice...
// Its an internal class that exists in both mscorlib and system assemblies.
// They are separate types though, so normally the scanner scans both and
// then we get conflicting labels. MS included it twice to make exception
// throwing code smaller. They are internal though, so we cannot
// reference them directly and only via finding them as they come along.
// We find it here, not via QueueType so we only check it here. Later
// we might have to checkin QueueType also.
// For now we accept both types, and just emit code for only one. This works
// with the current Nasm assembler as we resolve by name in the assembler.
// However with other assemblers this approach may not work.
// If AssemblerNASM adds assembly name to the label, this will allow
// both to exist as they do in BCL.
// So in the future we might be able to remove this hack, or change
// how it works.
private Type mThrowHelper;
public uint QueueMethod(MethodBase aMethodBase, bool aIsPlug) {
uint xResult;
@ -346,6 +366,8 @@ namespace Cosmos.IL2CPU {
QueueType(aType.BaseType);
}
// queue static constructor
//TODO: Should QueueMethod call QueueType with DeclaringType
// so its static constructors will get added?
foreach (var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) {
if (xCctor.DeclaringType == aType) {
QueueMethod(xCctor, false);