This commit is contained in:
kudzu_cp 2009-09-08 18:33:09 +00:00
parent 4e3c52a3e9
commit 59f2668d90
2 changed files with 220 additions and 261 deletions

View file

@ -9,8 +9,7 @@ namespace Cosmos.IL2CPU {
public abstract class Assembler { public abstract class Assembler {
protected ILOp[] mILOpsLo = new ILOp[256]; protected ILOp[] mILOpsLo = new ILOp[256];
protected ILOp[] mILOpsHi = new ILOp[256]; protected ILOp[] mILOpsHi = new ILOp[256];
public virtual void Initialize() public virtual void Initialize() {
{
} }
// Contains info on the current stack structure. What type are on the stack, etc // Contains info on the current stack structure. What type are on the stack, etc
public readonly StackContents Stack = new StackContents(); public readonly StackContents Stack = new StackContents();
@ -20,50 +19,41 @@ namespace Cosmos.IL2CPU {
private List<DataMember> mDataMembers = new List<DataMember>(); private List<DataMember> mDataMembers = new List<DataMember>();
private System.IO.TextWriter mLog; private System.IO.TextWriter mLog;
#region Properties #region Properties
public List<DataMember> DataMembers public List<DataMember> DataMembers {
{
get { return mDataMembers; } get { return mDataMembers; }
} }
public List<Instruction> Instructions public List<Instruction> Instructions {
{
get { return mInstructions; } get { return mInstructions; }
} }
public static Assembler CurrentInstance public static Assembler CurrentInstance {
{ get {
get
{
return mCurrentInstance; return mCurrentInstance;
} }
} }
internal int AllAssemblerElementCount internal int AllAssemblerElementCount {
{ get {
get
{
return mInstructions.Count + mDataMembers.Count; return mInstructions.Count + mDataMembers.Count;
} }
} }
#endregion #endregion
public Assembler() public Assembler() {
{
mLog = new System.IO.StreamWriter("Cosmos.Assembler.Log"); mLog = new System.IO.StreamWriter("Cosmos.Assembler.Log");
InitILOps(); InitILOps();
mCurrentInstance = this; mCurrentInstance = this;
} }
public static ulong ConstructLabel(uint aMethod, uint aOpCode, byte aSubLabel) public static ulong ConstructLabel(uint aMethod, uint aOpCode, byte aSubLabel) {
{
/* Explanation: /* Explanation:
* * This method generates labels. labels are 64bit: * * This method generates labels. labels are 64bit:
* * First 24 bits (high to low) is the method number * * First 24 bits (high to low) is the method number
* * then 32 bits is the opcode offset in the il * * then 32 bits is the opcode offset in the il
* * then 8 bits for a sub label. * * then 8 bits for a sub label.
*/ */
if (aMethod > 0x00FFFFFF) if (aMethod > 0x00FFFFFF) {
{
throw new Exception("Error Method id too high!"); throw new Exception("Error Method id too high!");
} }
ulong xResult = aMethod << 40; ulong xResult = aMethod << 40;
@ -72,8 +62,7 @@ namespace Cosmos.IL2CPU {
return xResult; return xResult;
} }
public void Dispose() public void Dispose() {
{
// MtW: I know, IDisposable usage for this isn't really nice, but for now this should be fine. // MtW: I know, IDisposable usage for this isn't really nice, but for now this should be fine.
// Anyhow, we need a way to clear the CurrentInstance property // Anyhow, we need a way to clear the CurrentInstance property
//mInstructions.Clear(); //mInstructions.Clear();
@ -84,50 +73,44 @@ namespace Cosmos.IL2CPU {
//} //}
} }
public BaseAssemblerElement GetAssemblerElement( int aIndex ) public BaseAssemblerElement GetAssemblerElement(int aIndex) {
{ if (aIndex >= mInstructions.Count) {
if( aIndex >= mInstructions.Count )
{
return mDataMembers[aIndex - mInstructions.Count]; return mDataMembers[aIndex - mInstructions.Count];
} }
return mInstructions[aIndex]; return mInstructions[aIndex];
} }
public BaseAssemblerElement TryResolveReference( ElementReference aReference ) public BaseAssemblerElement TryResolveReference(ElementReference aReference) {
{ foreach (var xInstruction in mInstructions) {
foreach( var xInstruction in mInstructions )
{
var xLabel = xInstruction as Label; var xLabel = xInstruction as Label;
if( xLabel != null ) if (xLabel != null) {
{ if (xLabel.QualifiedName.Equals(aReference.Name, StringComparison.InvariantCultureIgnoreCase)) {
if( xLabel.QualifiedName.Equals( aReference.Name, StringComparison.InvariantCultureIgnoreCase ) )
{
return xLabel; return xLabel;
} }
} }
} }
foreach( var xDataMember in mDataMembers ) foreach (var xDataMember in mDataMembers) {
{ if (xDataMember.Name.Equals(aReference.Name, StringComparison.InvariantCultureIgnoreCase)) {
if( xDataMember.Name.Equals( aReference.Name, StringComparison.InvariantCultureIgnoreCase ) )
{
return xDataMember; return xDataMember;
} }
} }
return null; return null;
} }
public void Add( params Instruction[] aReaders ) public void Add(params Instruction[] aReaders) {
{ foreach (Instruction xInstruction in aReaders) {
foreach( Instruction xInstruction in aReaders )
{
mInstructions.Add(xInstruction); mInstructions.Add(xInstruction);
} }
} }
public void ProcessMethod(MethodInfo aMethod, List<ILOpCode> aOpCodes) { public void ProcessMethod(MethodInfo aMethod, List<ILOpCode> aOpCodes) {
if (aOpCodes.Count == 0) { // We check this here and not scanner as when scanner makes these
return; // plugs may still have not yet been scanned that it will depend on.
// But by the time we make it here, they have to be resolved.
if (aMethod.Type == MethodInfo.TypeEnum.NeedsPlug && aMethod.PlugMethod == null) {
throw new Exception("Method needs plug, but no plug was assigned.");
} }
// todo: MtW: how to do this? we need some extra space. // todo: MtW: how to do this? we need some extra space.
// see ConstructLabel for extra info // see ConstructLabel for extra info
if (aMethod.UID > 0x00FFFFFF) { if (aMethod.UID > 0x00FFFFFF) {
@ -152,20 +135,16 @@ namespace Cosmos.IL2CPU {
/// <summary> /// <summary>
/// allows to emit footers to the code and datamember sections /// allows to emit footers to the code and datamember sections
/// </summary> /// </summary>
protected virtual void OnBeforeFlush() protected virtual void OnBeforeFlush() {
{
} }
private uint mDataMemberCounter = 0; private uint mDataMemberCounter = 0;
public string GetIdentifier( string aPrefix ) public string GetIdentifier(string aPrefix) {
{
mDataMemberCounter++; mDataMemberCounter++;
return aPrefix + mDataMemberCounter.ToString("X8").ToUpper(); return aPrefix + mDataMemberCounter.ToString("X8").ToUpper();
} }
private bool mFlushInitializationDone = false; private bool mFlushInitializationDone = false;
protected void BeforeFlush() protected void BeforeFlush() {
{ if (mFlushInitializationDone) {
if( mFlushInitializationDone )
{
return; return;
} }
mFlushInitializationDone = true; mFlushInitializationDone = true;
@ -173,21 +152,17 @@ namespace Cosmos.IL2CPU {
//MergeAllElements(); //MergeAllElements();
} }
public virtual void FlushBinary( Stream aOutput, ulong aBaseAddress ) public virtual void FlushBinary(Stream aOutput, ulong aBaseAddress) {
{
BeforeFlush(); BeforeFlush();
var xMax = AllAssemblerElementCount; var xMax = AllAssemblerElementCount;
var xCurrentAddresss = aBaseAddress; var xCurrentAddresss = aBaseAddress;
for( int i = 0; i < xMax; i++ ) for (int i = 0; i < xMax; i++) {
{
GetAssemblerElement(i).UpdateAddress(this, ref xCurrentAddresss); GetAssemblerElement(i).UpdateAddress(this, ref xCurrentAddresss);
} }
aOutput.SetLength(aOutput.Length + (long)(xCurrentAddresss - aBaseAddress)); aOutput.SetLength(aOutput.Length + (long)(xCurrentAddresss - aBaseAddress));
for( int i = 0; i < xMax; i++ ) for (int i = 0; i < xMax; i++) {
{
var xItem = GetAssemblerElement(i); var xItem = GetAssemblerElement(i);
if( !xItem.IsComplete( this ) ) if (!xItem.IsComplete(this)) {
{
throw new Exception("Incomplete element encountered."); throw new Exception("Incomplete element encountered.");
} }
//var xBuff = xItem.GetData(this); //var xBuff = xItem.GetData(this);
@ -196,36 +171,27 @@ namespace Cosmos.IL2CPU {
} }
} }
public virtual void FlushText( TextWriter aOutput ) public virtual void FlushText(TextWriter aOutput) {
{
BeforeFlush(); BeforeFlush();
if( mDataMembers.Count > 0 ) if (mDataMembers.Count > 0) {
{
aOutput.WriteLine(); aOutput.WriteLine();
foreach( DataMember xMember in mDataMembers ) foreach (DataMember xMember in mDataMembers) {
{
aOutput.Write("\t"); aOutput.Write("\t");
xMember.WriteText(this, aOutput); xMember.WriteText(this, aOutput);
aOutput.WriteLine(); aOutput.WriteLine();
} }
aOutput.WriteLine(); aOutput.WriteLine();
} }
if( mInstructions.Count > 0 ) if (mInstructions.Count > 0) {
{ for (int i = 0; i < mInstructions.Count; i++) {
for( int i = 0; i < mInstructions.Count; i++ )
{
//foreach (Instruction x in mInstructions) { //foreach (Instruction x in mInstructions) {
var x = mInstructions[i]; var x = mInstructions[i];
string prefix = "\t\t\t"; string prefix = "\t\t\t";
Label xLabel = x as Label; Label xLabel = x as Label;
if( xLabel != null ) if (xLabel != null) {
{ if (xLabel.Name[0] == '.') {
if( xLabel.Name[ 0 ] == '.' )
{
prefix = "\t\t"; prefix = "\t\t";
} } else {
else
{
prefix = "\t"; prefix = "\t";
} }
//string xFullName; //string xFullName;
@ -242,7 +208,6 @@ namespace Cosmos.IL2CPU {
} }
} }
protected abstract void InitILOps(); protected abstract void InitILOps();
protected virtual void InitILOps(Type aAssemblerBaseOp) { protected virtual void InitILOps(Type aAssemblerBaseOp) {

View file

@ -203,12 +203,6 @@ namespace Cosmos.IL2CPU {
// and we dont start at 0 // and we dont start at 0
for (int i = mMethodsToProcessStart; i < mMethodsToProcess.Count; i++) { for (int i = mMethodsToProcessStart; i < mMethodsToProcess.Count; i++) {
var xMethod = mMethodsToProcess[i]; var xMethod = mMethodsToProcess[i];
//TODO: In assembler, throw exceptino if NeedsPlug is true
// but not plug is found
// dont do it here, because we might need to resolve against a future plug
// which hasnt been scanned yet
// Also modify and move this comment so someone doesnt move the
// code back into scanner.
if (xMethod.Type != MethodInfo.TypeEnum.NeedsPlug) { if (xMethod.Type != MethodInfo.TypeEnum.NeedsPlug) {
ScanMethod(xMethod); ScanMethod(xMethod);
} }