mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +00:00
This commit is contained in:
parent
65be2a5545
commit
1ca3b7a4c5
1 changed files with 38 additions and 18 deletions
|
|
@ -2,10 +2,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Indy.IL2CPU.Assembler {
|
namespace Indy.IL2CPU.Assembler {
|
||||||
public class ElementReference {
|
public class ElementReference {
|
||||||
|
|
||||||
public ElementReference(string aName, int aOffset)
|
public ElementReference(string aName, int aOffset)
|
||||||
: this(aName) {
|
: this(aName) {
|
||||||
Offset = aOffset;
|
Offset = aOffset;
|
||||||
|
|
@ -24,28 +24,48 @@ namespace Indy.IL2CPU.Assembler {
|
||||||
|
|
||||||
private ulong? mActualAddress;
|
private ulong? mActualAddress;
|
||||||
|
|
||||||
|
private static ReaderWriterLockSlim mCacheLocker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
|
||||||
|
private static SortedList<string, BaseAssemblerElement> mCache = new SortedList<string, BaseAssemblerElement>();
|
||||||
|
|
||||||
|
private static BaseAssemblerElement DoResolve(Assembler aAssembler, string aName) {
|
||||||
|
mCacheLocker.EnterReadLock();
|
||||||
|
try {
|
||||||
|
BaseAssemblerElement xTempResult;
|
||||||
|
if (mCache.TryGetValue(aName, out xTempResult)) {
|
||||||
|
return xTempResult;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
mCacheLocker.ExitReadLock();
|
||||||
|
}
|
||||||
|
mCacheLocker.EnterWriteLock();
|
||||||
|
try {
|
||||||
|
BaseAssemblerElement xTempResult;
|
||||||
|
if (mCache.TryGetValue(aName, out xTempResult)) {
|
||||||
|
return xTempResult;
|
||||||
|
}
|
||||||
|
xTempResult = (from item in aAssembler.Instructions
|
||||||
|
let xLabel = item as Label
|
||||||
|
where xLabel != null && xLabel.QualifiedName.Equals(aName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
select item).SingleOrDefault();
|
||||||
|
if (xTempResult == null) {
|
||||||
|
xTempResult = (from item in aAssembler.DataMembers
|
||||||
|
where item.Name.Equals(aName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
select item).SingleOrDefault();
|
||||||
|
}
|
||||||
|
mCache.Add(aName, xTempResult);
|
||||||
|
return xTempResult;
|
||||||
|
} finally {
|
||||||
|
mCacheLocker.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Resolve(Assembler aAssembler, out ulong aAddress) {
|
public bool Resolve(Assembler aAssembler, out ulong aAddress) {
|
||||||
|
//
|
||||||
if (mActualAddress != null) {
|
if (mActualAddress != null) {
|
||||||
aAddress = mActualAddress.Value;
|
aAddress = mActualAddress.Value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var xItems = (from item in aAssembler.Instructions
|
var xElement = DoResolve(aAssembler, Name);
|
||||||
let xLabel = item as Label
|
|
||||||
where xLabel != null && xLabel.QualifiedName.Equals(Name, StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
select item).ToArray();
|
|
||||||
if (xItems.Count() > 1) {
|
|
||||||
Console.Write("");
|
|
||||||
}
|
|
||||||
BaseAssemblerElement xElement = (from item in aAssembler.Instructions
|
|
||||||
let xLabel = item as Label
|
|
||||||
where xLabel != null && xLabel.QualifiedName.Equals(Name, StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
select item).SingleOrDefault();
|
|
||||||
if (xElement == null) {
|
|
||||||
xElement = (from item in aAssembler.DataMembers
|
|
||||||
where item.Name.Equals(Name, StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
select item).SingleOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xElement != null) {
|
if (xElement != null) {
|
||||||
if (xElement.ActualAddress.HasValue) {
|
if (xElement.ActualAddress.HasValue) {
|
||||||
mActualAddress = (ulong)((long)xElement.ActualAddress.Value + Offset);
|
mActualAddress = (ulong)((long)xElement.ActualAddress.Value + Offset);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue