fix opcodes conflict

This commit is contained in:
MS-DOS1999 2018-12-16 20:03:45 +01:00
commit cc022057ec
344 changed files with 13132 additions and 13369 deletions

View file

@ -28,11 +28,11 @@ namespace ChocolArm64.Decoders
return block;
}
public static (Block[] Graph, Block Root) DecodeSubroutine(
TranslatorCache cache,
CpuThreadState state,
MemoryManager memory,
long start)
public static Block DecodeSubroutine(
TranslatorCache cache,
CpuThreadState state,
MemoryManager memory,
long start)
{
Dictionary<long, Block> visited = new Dictionary<long, Block>();
Dictionary<long, Block> visitedEnd = new Dictionary<long, Block>();
@ -53,7 +53,7 @@ namespace ChocolArm64.Decoders
return output;
}
Block root = Enqueue(start);
Block entry = Enqueue(start);
while (blocks.Count > 0)
{
@ -118,33 +118,7 @@ namespace ChocolArm64.Decoders
visitedEnd.Add(current.EndPosition, current);
}
//Make and sort Graph blocks array by position.
Block[] graph = new Block[visited.Count];
while (visited.Count > 0)
{
ulong firstPos = ulong.MaxValue;
foreach (Block block in visited.Values)
{
if (firstPos > (ulong)block.Position)
firstPos = (ulong)block.Position;
}
Block current = visited[(long)firstPos];
do
{
graph[graph.Length - visited.Count] = current;
visited.Remove(current.Position);
current = current.Next;
}
while (current != null);
}
return (graph, root);
return entry;
}
private static void FillBlock(CpuThreadState state, MemoryManager memory, Block block)

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{
@ -12,8 +11,8 @@ namespace ChocolArm64.Decoders
public OpCodeAlu64(Inst inst, long position, int opCode) : base(inst, position, opCode)
{
Rd = (opCode >> 0) & 0x1f;
Rn = (opCode >> 5) & 0x1f;
Rd = (opCode >> 0) & 0x1f;
Rn = (opCode >> 5) & 0x1f;
DataOp = (DataOp)((opCode >> 24) & 0x3);
RegisterSize = (opCode >> 31) != 0

View file

@ -22,7 +22,7 @@ namespace ChocolArm64.Decoders
Shift = shift;
Rm = (opCode >> 16) & 0x1f;
Rm = (opCode >> 16) & 0x1f;
ShiftType = (ShiftType)((opCode >> 22) & 0x3);
}
}

View file

@ -11,9 +11,9 @@ namespace ChocolArm64.Decoders
public OpCodeAluRx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
{
Shift = (opCode >> 10) & 0x7;
Shift = (opCode >> 10) & 0x7;
IntType = (IntType)((opCode >> 13) & 0x7);
Rm = (opCode >> 16) & 0x1f;
Rm = (opCode >> 16) & 0x1f;
}
}
}

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{

View file

@ -21,9 +21,9 @@ namespace ChocolArm64.Decoders
return;
}
Nzcv = (opCode >> 0) & 0xf;
Nzcv = (opCode >> 0) & 0xf;
Cond = (Cond)((opCode >> 12) & 0xf);
RmImm = (opCode >> 16) & 0x1f;
RmImm = (opCode >> 16) & 0x1f;
Rd = CpuThreadState.ZrIndex;
}

View file

@ -10,7 +10,7 @@ namespace ChocolArm64.Decoders
public OpCodeCsel64(Inst inst, long position, int opCode) : base(inst, position, opCode)
{
Rm = (opCode >> 16) & 0x1f;
Rm = (opCode >> 16) & 0x1f;
Cond = (Cond)((opCode >> 12) & 0xf);
}
}

View file

@ -41,7 +41,7 @@ namespace ChocolArm64.Decoders
if (WBack || Unscaled)
{
//9-bits Signed Immediate.
Imm = (opCode << 43) >> 55;
Imm = (opCode << 11) >> 23;
}
else
{

View file

@ -11,10 +11,10 @@ namespace ChocolArm64.Decoders
public OpCodeMemReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
{
Shift = ((opCode >> 12) & 0x1) != 0;
Shift = ((opCode >> 12) & 0x1) != 0;
IntType = (IntType)((opCode >> 13) & 0x7);
Rm = (opCode >> 16) & 0x1f;
Extend64 = ((opCode >> 22) & 0x3) == 2;
Rm = (opCode >> 16) & 0x1f;
Extend64 = ((opCode >> 22) & 0x3) == 2;
}
}
}

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{
@ -61,12 +60,12 @@ namespace ChocolArm64.Decoders
else if ((modeHigh & 0b110) == 0b100)
{
//16-bits shifted Immediate.
Size = 1; imm <<= (modeHigh & 1) << 3;
Size = 1; imm <<= (modeHigh & 1) << 3;
}
else if ((modeHigh & 0b100) == 0b000)
{
//32-bits shifted Immediate.
Size = 2; imm <<= modeHigh << 3;
Size = 2; imm <<= modeHigh << 3;
}
else if ((modeHigh & 0b111) == 0b110)
{

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{

View file

@ -1,5 +1,4 @@
using ChocolArm64.Instructions;
using ChocolArm64.State;
namespace ChocolArm64.Decoders
{

View file

@ -2,9 +2,9 @@ namespace ChocolArm64.Decoders
{
enum ShiftType
{
Lsl,
Lsr,
Asr,
Ror
Lsl = 0,
Lsr = 1,
Asr = 2,
Ror = 3
}
}

View file

@ -2,11 +2,11 @@ using System;
namespace ChocolArm64.Events
{
public class InvalidAccessEventArgs : EventArgs
public class MemoryAccessEventArgs : EventArgs
{
public long Position { get; private set; }
public InvalidAccessEventArgs(long position)
public MemoryAccessEventArgs(long position)
{
Position = position;
}

View file

@ -48,7 +48,7 @@ namespace ChocolArm64.Instructions
if (context.CurrBlock.Next != null)
{
context.EmitLoadState(context.CurrBlock.Next);
context.EmitLoadState();
}
else
{
@ -73,7 +73,7 @@ namespace ChocolArm64.Instructions
if (context.CurrBlock.Next != null)
{
context.EmitLoadState(context.CurrBlock.Next);
context.EmitLoadState();
}
else
{

View file

@ -58,7 +58,7 @@ namespace ChocolArm64.Instructions
context.Emit(OpCodes.Pop);
context.EmitLoadState(context.CurrBlock.Next);
context.EmitLoadState();
}
else
{
@ -73,13 +73,10 @@ namespace ChocolArm64.Instructions
OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;
context.EmitLdintzr(op.Rn);
context.EmitSttmp();
context.EmitLdc_I(op.Position + 4);
context.EmitStint(CpuThreadState.LrIndex);
context.EmitStoreState();
context.EmitLdtmp();
context.Emit(OpCodes.Ret);
}

View file

@ -60,7 +60,7 @@ namespace ChocolArm64.Instructions
EmitWBackIfNeeded(context);
}
public static void LdrLit(ILEmitterCtx context)
public static void Ldr_Literal(ILEmitterCtx context)
{
IOpCodeLit64 op = (IOpCodeLit64)context.CurrOp;

View file

@ -244,7 +244,7 @@ namespace ChocolArm64.Instructions
EmitFcvt_s_Gp(context, () => { });
}
public static void Fcvtzs_Gp_Fix(ILEmitterCtx context)
public static void Fcvtzs_Gp_Fixed(ILEmitterCtx context)
{
EmitFcvtzs_Gp_Fix(context);
}
@ -264,7 +264,7 @@ namespace ChocolArm64.Instructions
EmitFcvt_u_Gp(context, () => { });
}
public static void Fcvtzu_Gp_Fix(ILEmitterCtx context)
public static void Fcvtzu_Gp_Fixed(ILEmitterCtx context)
{
EmitFcvtzu_Gp_Fix(context);
}

View file

@ -17,18 +17,18 @@ namespace ChocolArm64.Memory
{
private const int PtLvl0Bits = 13;
private const int PtLvl1Bits = 14;
private const int PtPageBits = 12;
public const int PageBits = 12;
private const int PtLvl0Size = 1 << PtLvl0Bits;
private const int PtLvl1Size = 1 << PtLvl1Bits;
public const int PageSize = 1 << PtPageBits;
public const int PageSize = 1 << PageBits;
private const int PtLvl0Mask = PtLvl0Size - 1;
private const int PtLvl1Mask = PtLvl1Size - 1;
public const int PageMask = PageSize - 1;
private const int PtLvl0Bit = PtPageBits + PtLvl1Bits;
private const int PtLvl1Bit = PtPageBits;
private const int PtLvl0Bit = PageBits + PtLvl1Bits;
private const int PtLvl1Bit = PageBits;
private const long ErgMask = (4 << CpuThreadState.ErgSizeLog2) - 1;
@ -53,7 +53,9 @@ namespace ChocolArm64.Memory
private byte*** _pageTable;
public event EventHandler<InvalidAccessEventArgs> InvalidAccess;
public event EventHandler<MemoryAccessEventArgs> InvalidAccess;
public event EventHandler<MemoryAccessEventArgs> ObservedAccess;
public MemoryManager(IntPtr ram)
{
@ -119,6 +121,8 @@ namespace ChocolArm64.Memory
if (!_monitors.TryGetValue(core, out ArmMonitor threadMon))
{
Monitor.Exit(_monitors);
return false;
}
@ -630,7 +634,7 @@ namespace ChocolArm64.Memory
return false;
}
return _pageTable[l0][l1] != null || _observedPages.ContainsKey(position >> PtPageBits);
return _pageTable[l0][l1] != null || _observedPages.ContainsKey(position >> PageBits);
}
public long GetPhysicalAddress(long virtualAddress)
@ -676,14 +680,14 @@ Unmapped:
private byte* HandleNullPte(long position)
{
long key = position >> PtPageBits;
long key = position >> PageBits;
if (_observedPages.TryGetValue(key, out IntPtr ptr))
{
return (byte*)ptr + (position & PageMask);
}
InvalidAccess?.Invoke(this, new InvalidAccessEventArgs(position));
InvalidAccess?.Invoke(this, new MemoryAccessEventArgs(position));
throw new VmmPageFaultException(position);
}
@ -724,16 +728,20 @@ Unmapped:
private byte* HandleNullPteWrite(long position)
{
long key = position >> PtPageBits;
long key = position >> PageBits;
MemoryAccessEventArgs e = new MemoryAccessEventArgs(position);
if (_observedPages.TryGetValue(key, out IntPtr ptr))
{
SetPtEntry(position, (byte*)ptr);
ObservedAccess?.Invoke(this, e);
return (byte*)ptr + (position & PageMask);
}
InvalidAccess?.Invoke(this, new InvalidAccessEventArgs(position));
InvalidAccess?.Invoke(this, e);
throw new VmmPageFaultException(position);
}
@ -782,53 +790,20 @@ Unmapped:
_pageTable[l0][l1] = ptr;
}
public (bool[], int) IsRegionModified(long position, long size)
public void StartObservingRegion(long position, long size)
{
long endPosition = (position + size + PageMask) & ~PageMask;
position &= ~PageMask;
size = endPosition - position;
bool[] modified = new bool[size >> PtPageBits];
int count = 0;
lock (_observedPages)
while ((ulong)position < (ulong)endPosition)
{
for (int page = 0; page < modified.Length; page++)
{
byte* ptr = Translate(position);
_observedPages[position >> PageBits] = (IntPtr)Translate(position);
if (_observedPages.TryAdd(position >> PtPageBits, (IntPtr)ptr))
{
modified[page] = true;
SetPtEntry(position, null);
count++;
}
else
{
long l0 = (position >> PtLvl0Bit) & PtLvl0Mask;
long l1 = (position >> PtLvl1Bit) & PtLvl1Mask;
byte** lvl1 = _pageTable[l0];
if (lvl1 != null)
{
if (modified[page] = lvl1[l1] != null)
{
count++;
}
}
}
SetPtEntry(position, null);
position += PageSize;
}
position += PageSize;
}
return (modified, count);
}
public void StopObservingRegion(long position, long size)
@ -839,7 +814,7 @@ Unmapped:
{
lock (_observedPages)
{
if (_observedPages.TryRemove(position >> PtPageBits, out IntPtr ptr))
if (_observedPages.TryRemove(position >> PageBits, out IntPtr ptr))
{
SetPtEntry(position, (byte*)ptr);
}
@ -889,7 +864,7 @@ Unmapped:
public bool IsValidPosition(long position)
{
return position >> (PtLvl0Bits + PtLvl1Bits + PtPageBits) == 0;
return position >> (PtLvl0Bits + PtLvl1Bits + PageBits) == 0;
}
public void Dispose()

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@ namespace ChocolArm64
public DynamicMethod Method { get; private set; }
public ReadOnlyCollection<Register> Params { get; private set; }
public ReadOnlyCollection<Register> SubArgs { get; private set; }
private HashSet<long> _callers;
@ -34,20 +34,10 @@ namespace ChocolArm64
private bool _needsReJit;
public TranslatedSub(DynamicMethod method, List<Register> Params)
public TranslatedSub(DynamicMethod method, List<Register> subArgs)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
if (Params == null)
{
throw new ArgumentNullException(nameof(Params));
}
Method = method;
this.Params = Params.AsReadOnly();
Method = method ?? throw new ArgumentNullException(nameof(method));;
SubArgs = subArgs?.AsReadOnly() ?? throw new ArgumentNullException(nameof(subArgs));
_callers = new HashSet<long>();
@ -89,7 +79,7 @@ namespace ChocolArm64
generator.EmitLdargSeq(FixedArgTypes.Length);
foreach (Register reg in Params)
foreach (Register reg in SubArgs)
{
generator.EmitLdarg(StateArgIdx);

View file

@ -2,6 +2,6 @@ namespace ChocolArm64.Translation
{
interface IILEmit
{
void Emit(ILEmitter context);
void Emit(ILMethodBuilder context);
}
}

View file

@ -2,6 +2,6 @@ namespace ChocolArm64.Translation
{
struct ILBarrier : IILEmit
{
public void Emit(ILEmitter context) { }
public void Emit(ILMethodBuilder context) { }
}
}

View file

@ -14,19 +14,21 @@ namespace ChocolArm64.Translation
public bool HasStateStore { get; private set; }
public List<IILEmit> IlEmitters { get; private set; }
private List<IILEmit> _emitters;
public int Count => _emitters.Count;
public ILBlock Next { get; set; }
public ILBlock Branch { get; set; }
public ILBlock()
{
IlEmitters = new List<IILEmit>();
_emitters = new List<IILEmit>();
}
public void Add(IILEmit ilEmitter)
public void Add(IILEmit emitter)
{
if (ilEmitter is ILBarrier)
if (emitter is ILBarrier)
{
//Those barriers are used to separate the groups of CIL
//opcodes emitted by each ARM instruction.
@ -35,7 +37,7 @@ namespace ChocolArm64.Translation
IntAwOutputs = IntOutputs;
VecAwOutputs = VecOutputs;
}
else if (ilEmitter is IlOpCodeLoad ld && ILEmitter.IsRegIndex(ld.Index))
else if (emitter is ILOpCodeLoad ld && ILMethodBuilder.IsRegIndex(ld.Index))
{
switch (ld.IoType)
{
@ -44,30 +46,26 @@ namespace ChocolArm64.Translation
case IoType.Vector: VecInputs |= (1L << ld.Index) & ~VecAwOutputs; break;
}
}
else if (ilEmitter is IlOpCodeStore st)
else if (emitter is ILOpCodeStore st && ILMethodBuilder.IsRegIndex(st.Index))
{
if (ILEmitter.IsRegIndex(st.Index))
switch (st.IoType)
{
switch (st.IoType)
{
case IoType.Flag: IntOutputs |= (1L << st.Index) << 32; break;
case IoType.Int: IntOutputs |= 1L << st.Index; break;
case IoType.Vector: VecOutputs |= 1L << st.Index; break;
}
}
if (st.IoType == IoType.Fields)
{
HasStateStore = true;
case IoType.Flag: IntOutputs |= (1L << st.Index) << 32; break;
case IoType.Int: IntOutputs |= 1L << st.Index; break;
case IoType.Vector: VecOutputs |= 1L << st.Index; break;
}
}
else if (emitter is ILOpCodeStoreState)
{
HasStateStore = true;
}
IlEmitters.Add(ilEmitter);
_emitters.Add(emitter);
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
foreach (IILEmit ilEmitter in IlEmitters)
foreach (IILEmit ilEmitter in _emitters)
{
ilEmitter.Emit(context);
}

View file

@ -14,15 +14,20 @@ namespace ChocolArm64.Translation
private Dictionary<long, ILLabel> _labels;
private int _blkIndex;
private long _subPosition;
private int _opcIndex;
private Block[] _graph;
private Block _root;
public Block CurrBlock => _graph[_blkIndex];
public OpCode64 CurrOp => _graph[_blkIndex].OpCodes[_opcIndex];
private Block _currBlock;
private ILEmitter _emitter;
public Block CurrBlock => _currBlock;
public OpCode64 CurrOp => _currBlock?.OpCodes[_opcIndex];
private Dictionary<Block, ILBlock> _visitedBlocks;
private Queue<Block> _branchTargets;
private List<ILBlock> _ilBlocks;
private ILBlock _ilBlock;
@ -33,69 +38,61 @@ namespace ChocolArm64.Translation
//values needed by some functions, since IL doesn't have a swap instruction.
//You can use any value here as long it doesn't conflict with the indices
//for the other registers. Any value >= 64 or < 0 will do.
private const int Tmp1Index = -1;
private const int Tmp2Index = -2;
private const int Tmp3Index = -3;
private const int Tmp4Index = -4;
private const int Tmp5Index = -5;
private const int Tmp6Index = -6;
private const int IntTmpIndex = -1;
private const int RorTmpIndex = -2;
private const int CmpOptTmp1Index = -3;
private const int CmpOptTmp2Index = -4;
private const int VecTmp1Index = -5;
private const int VecTmp2Index = -6;
public ILEmitterCtx(
TranslatorCache cache,
Block[] graph,
Block root,
string subName)
public ILEmitterCtx(TranslatorCache cache, Block graph)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_graph = graph ?? throw new ArgumentNullException(nameof(graph));
_root = root ?? throw new ArgumentNullException(nameof(root));
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_currBlock = graph ?? throw new ArgumentNullException(nameof(graph));
_labels = new Dictionary<long, ILLabel>();
_emitter = new ILEmitter(graph, root, subName);
_visitedBlocks = new Dictionary<Block, ILBlock>();
_ilBlock = _emitter.GetIlBlock(0);
_visitedBlocks.Add(graph, new ILBlock());
_opcIndex = -1;
_branchTargets = new Queue<Block>();
if (graph.Length == 0 || !AdvanceOpCode())
{
throw new ArgumentException(nameof(graph));
}
_ilBlocks = new List<ILBlock>();
_subPosition = graph.Position;
ResetBlockState();
AdvanceOpCode();
}
public TranslatedSub GetSubroutine()
public ILBlock[] GetILBlocks()
{
return _emitter.GetSubroutine();
EmitAllOpCodes();
return _ilBlocks.ToArray();
}
public bool AdvanceOpCode()
private void EmitAllOpCodes()
{
if (_opcIndex + 1 == CurrBlock.OpCodes.Count &&
_blkIndex + 1 == _graph.Length)
do
{
return false;
EmitOpCode();
}
while (++_opcIndex >= (CurrBlock?.OpCodes.Count ?? 0))
{
_blkIndex++;
_opcIndex = -1;
_optOpLastFlagSet = null;
_optOpLastCompare = null;
_ilBlock = _emitter.GetIlBlock(_blkIndex);
}
return true;
while (AdvanceOpCode());
}
public void EmitOpCode()
private void EmitOpCode()
{
if (_currBlock == null)
{
return;
}
if (_opcIndex == 0)
{
MarkLabel(GetLabel(CurrBlock.Position));
MarkLabel(GetLabel(_currBlock.Position));
EmitSynchronization();
}
@ -109,7 +106,7 @@ namespace ChocolArm64.Translation
{
EmitLdarg(TranslatedSub.StateArgIdx);
EmitLdc_I4(CurrBlock.OpCodes.Count);
EmitLdc_I4(_currBlock.OpCodes.Count);
EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.Synchronize));
@ -126,9 +123,86 @@ namespace ChocolArm64.Translation
MarkLabel(lblContinue);
}
private bool AdvanceOpCode()
{
if (_currBlock == null)
{
return false;
}
while (++_opcIndex >= _currBlock.OpCodes.Count)
{
if (!AdvanceBlock())
{
return false;
}
ResetBlockState();
}
return true;
}
private bool AdvanceBlock()
{
if (_currBlock.Branch != null)
{
if (_visitedBlocks.TryAdd(_currBlock.Branch, _ilBlock.Branch))
{
_branchTargets.Enqueue(_currBlock.Branch);
}
}
if (_currBlock.Next != null)
{
if (_visitedBlocks.TryAdd(_currBlock.Next, _ilBlock.Next))
{
_currBlock = _currBlock.Next;
return true;
}
else
{
Emit(OpCodes.Br, GetLabel(_currBlock.Next.Position));
}
}
return _branchTargets.TryDequeue(out _currBlock);
}
private void ResetBlockState()
{
_ilBlock = _visitedBlocks[_currBlock];
_ilBlocks.Add(_ilBlock);
_ilBlock.Next = GetOrCreateILBlock(_currBlock.Next);
_ilBlock.Branch = GetOrCreateILBlock(_currBlock.Branch);
_opcIndex = -1;
_optOpLastFlagSet = null;
_optOpLastCompare = null;
}
private ILBlock GetOrCreateILBlock(Block block)
{
if (block == null)
{
return null;
}
if (_visitedBlocks.TryGetValue(block, out ILBlock ilBlock))
{
return ilBlock;
}
return new ILBlock();
}
public bool TryOptEmitSubroutineCall()
{
if (CurrBlock.Next == null)
if (_currBlock.Next == null)
{
return false;
}
@ -148,7 +222,7 @@ namespace ChocolArm64.Translation
EmitLdarg(index);
}
foreach (Register reg in subroutine.Params)
foreach (Register reg in subroutine.SubArgs)
{
switch (reg.Type)
{
@ -160,7 +234,7 @@ namespace ChocolArm64.Translation
EmitCall(subroutine.Method);
subroutine.AddCaller(_root.Position);
subroutine.AddCaller(_subPosition);
return true;
}
@ -171,11 +245,11 @@ namespace ChocolArm64.Translation
InstEmitAluHelper.EmitDataLoadOpers(this);
Stloc(Tmp4Index, IoType.Int);
Stloc(Tmp3Index, IoType.Int);
Stloc(CmpOptTmp2Index, IoType.Int);
Stloc(CmpOptTmp1Index, IoType.Int);
}
private Dictionary<Cond, System.Reflection.Emit.OpCode> _branchOps = new Dictionary<Cond, System.Reflection.Emit.OpCode>()
private Dictionary<Cond, OpCode> _branchOps = new Dictionary<Cond, OpCode>()
{
{ Cond.Eq, OpCodes.Beq },
{ Cond.Ne, OpCodes.Bne_Un },
@ -191,15 +265,15 @@ namespace ChocolArm64.Translation
public void EmitCondBranch(ILLabel target, Cond cond)
{
System.Reflection.Emit.OpCode ilOp;
OpCode ilOp;
int intCond = (int)cond;
if (_optOpLastCompare != null &&
_optOpLastCompare == _optOpLastFlagSet && _branchOps.ContainsKey(cond))
{
Ldloc(Tmp3Index, IoType.Int, _optOpLastCompare.RegisterSize);
Ldloc(Tmp4Index, IoType.Int, _optOpLastCompare.RegisterSize);
Ldloc(CmpOptTmp1Index, IoType.Int, _optOpLastCompare.RegisterSize);
Ldloc(CmpOptTmp2Index, IoType.Int, _optOpLastCompare.RegisterSize);
ilOp = _branchOps[cond];
}
@ -285,11 +359,11 @@ namespace ChocolArm64.Translation
}
}
public void EmitLsl(int amount) => EmitIlShift(amount, OpCodes.Shl);
public void EmitLsr(int amount) => EmitIlShift(amount, OpCodes.Shr_Un);
public void EmitAsr(int amount) => EmitIlShift(amount, OpCodes.Shr);
public void EmitLsl(int amount) => EmitILShift(amount, OpCodes.Shl);
public void EmitLsr(int amount) => EmitILShift(amount, OpCodes.Shr_Un);
public void EmitAsr(int amount) => EmitILShift(amount, OpCodes.Shr);
private void EmitIlShift(int amount, System.Reflection.Emit.OpCode ilOp)
private void EmitILShift(int amount, OpCode ilOp)
{
if (amount > 0)
{
@ -303,14 +377,14 @@ namespace ChocolArm64.Translation
{
if (amount > 0)
{
Stloc(Tmp2Index, IoType.Int);
Ldloc(Tmp2Index, IoType.Int);
Stloc(RorTmpIndex, IoType.Int);
Ldloc(RorTmpIndex, IoType.Int);
EmitLdc_I4(amount);
Emit(OpCodes.Shr_Un);
Ldloc(Tmp2Index, IoType.Int);
Ldloc(RorTmpIndex, IoType.Int);
EmitLdc_I4(CurrOp.GetBitsCount() - amount);
@ -336,12 +410,12 @@ namespace ChocolArm64.Translation
_ilBlock.Add(label);
}
public void Emit(System.Reflection.Emit.OpCode ilOp)
public void Emit(OpCode ilOp)
{
_ilBlock.Add(new ILOpCode(ilOp));
}
public void Emit(System.Reflection.Emit.OpCode ilOp, ILLabel label)
public void Emit(OpCode ilOp, ILLabel label)
{
_ilBlock.Add(new ILOpCodeBranch(ilOp, label));
}
@ -353,7 +427,7 @@ namespace ChocolArm64.Translation
public void EmitLdarg(int index)
{
_ilBlock.Add(new IlOpCodeLoad(index, IoType.Arg));
_ilBlock.Add(new ILOpCodeLoad(index, IoType.Arg));
}
public void EmitLdintzr(int index)
@ -380,24 +454,29 @@ namespace ChocolArm64.Translation
}
}
public void EmitLoadState(Block retBlk)
public void EmitLoadState()
{
_ilBlock.Add(new IlOpCodeLoad(Array.IndexOf(_graph, retBlk), IoType.Fields));
if (_ilBlock.Next == null)
{
throw new InvalidOperationException("Can't load state for next block, because there's no next block.");
}
_ilBlock.Add(new ILOpCodeLoadState(_ilBlock.Next));
}
public void EmitStoreState()
{
_ilBlock.Add(new IlOpCodeStore(Array.IndexOf(_graph, CurrBlock), IoType.Fields));
_ilBlock.Add(new ILOpCodeStoreState(_ilBlock));
}
public void EmitLdtmp() => EmitLdint(Tmp1Index);
public void EmitSttmp() => EmitStint(Tmp1Index);
public void EmitLdtmp() => EmitLdint(IntTmpIndex);
public void EmitSttmp() => EmitStint(IntTmpIndex);
public void EmitLdvectmp() => EmitLdvec(Tmp5Index);
public void EmitStvectmp() => EmitStvec(Tmp5Index);
public void EmitLdvectmp() => EmitLdvec(VecTmp1Index);
public void EmitStvectmp() => EmitStvec(VecTmp1Index);
public void EmitLdvectmp2() => EmitLdvec(Tmp6Index);
public void EmitStvectmp2() => EmitStvec(Tmp6Index);
public void EmitLdvectmp2() => EmitLdvec(VecTmp2Index);
public void EmitStvectmp2() => EmitStvec(VecTmp2Index);
public void EmitLdint(int index) => Ldloc(index, IoType.Int);
public void EmitStint(int index) => Stloc(index, IoType.Int);
@ -415,17 +494,17 @@ namespace ChocolArm64.Translation
private void Ldloc(int index, IoType ioType)
{
_ilBlock.Add(new IlOpCodeLoad(index, ioType, CurrOp.RegisterSize));
_ilBlock.Add(new ILOpCodeLoad(index, ioType, CurrOp.RegisterSize));
}
private void Ldloc(int index, IoType ioType, RegisterSize registerSize)
{
_ilBlock.Add(new IlOpCodeLoad(index, ioType, registerSize));
_ilBlock.Add(new ILOpCodeLoad(index, ioType, registerSize));
}
private void Stloc(int index, IoType ioType)
{
_ilBlock.Add(new IlOpCodeStore(index, ioType, CurrOp.RegisterSize));
_ilBlock.Add(new ILOpCodeStore(index, ioType, CurrOp.RegisterSize));
}
public void EmitCallPropGet(Type objType, string propName)
@ -536,7 +615,7 @@ namespace ChocolArm64.Translation
EmitZnCheck(OpCodes.Clt, (int)PState.NBit);
}
private void EmitZnCheck(System.Reflection.Emit.OpCode ilCmpOp, int flag)
private void EmitZnCheck(OpCode ilCmpOp, int flag)
{
Emit(OpCodes.Dup);
Emit(OpCodes.Ldc_I4_0);

View file

@ -8,12 +8,12 @@ namespace ChocolArm64.Translation
private Label _lbl;
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
context.Generator.MarkLabel(GetLabel(context));
}
public Label GetLabel(ILEmitter context)
public Label GetLabel(ILMethodBuilder context)
{
if (!_hasLabel)
{

View file

@ -1,4 +1,3 @@
using ChocolArm64.Decoders;
using ChocolArm64.State;
using System;
using System.Collections.Generic;
@ -7,7 +6,7 @@ using System.Runtime.Intrinsics;
namespace ChocolArm64.Translation
{
class ILEmitter
class ILMethodBuilder
{
public LocalAlloc LocalAlloc { get; private set; }
@ -17,70 +16,23 @@ namespace ChocolArm64.Translation
private ILBlock[] _ilBlocks;
private ILBlock _root;
private TranslatedSub _subroutine;
private string _subName;
private int _localsCount;
public ILEmitter(Block[] graph, Block root, string subName)
public ILMethodBuilder(ILBlock[] ilBlocks, string subName)
{
_subName = subName;
_locals = new Dictionary<Register, int>();
_ilBlocks = new ILBlock[graph.Length];
ILBlock GetBlock(int index)
{
if (index < 0 || index >= _ilBlocks.Length)
{
return null;
}
if (_ilBlocks[index] == null)
{
_ilBlocks[index] = new ILBlock();
}
return _ilBlocks[index];
}
for (int index = 0; index < _ilBlocks.Length; index++)
{
ILBlock block = GetBlock(index);
block.Next = GetBlock(Array.IndexOf(graph, graph[index].Next));
block.Branch = GetBlock(Array.IndexOf(graph, graph[index].Branch));
}
_root = _ilBlocks[Array.IndexOf(graph, root)];
_ilBlocks = ilBlocks;
_subName = subName;
}
public ILBlock GetIlBlock(int index) => _ilBlocks[index];
public TranslatedSub GetSubroutine()
{
LocalAlloc = new LocalAlloc(_ilBlocks, _root);
LocalAlloc = new LocalAlloc(_ilBlocks, _ilBlocks[0]);
InitSubroutine();
InitLocals();
List<Register> subArgs = new List<Register>();
foreach (ILBlock ilBlock in _ilBlocks)
{
ilBlock.Emit(this);
}
return _subroutine;
}
private void InitSubroutine()
{
List<Register> Params = new List<Register>();
void SetParams(long inputs, RegisterType baseType)
void SetArgs(long inputs, RegisterType baseType)
{
for (int bit = 0; bit < 64; bit++)
{
@ -88,37 +40,43 @@ namespace ChocolArm64.Translation
if ((inputs & mask) != 0)
{
Params.Add(GetRegFromBit(bit, baseType));
subArgs.Add(GetRegFromBit(bit, baseType));
}
}
}
SetParams(LocalAlloc.GetIntInputs(_root), RegisterType.Int);
SetParams(LocalAlloc.GetVecInputs(_root), RegisterType.Vector);
SetArgs(LocalAlloc.GetIntInputs(_ilBlocks[0]), RegisterType.Int);
SetArgs(LocalAlloc.GetVecInputs(_ilBlocks[0]), RegisterType.Vector);
DynamicMethod mthd = new DynamicMethod(_subName, typeof(long), GetParamTypes(Params));
DynamicMethod method = new DynamicMethod(_subName, typeof(long), GetArgumentTypes(subArgs));
Generator = mthd.GetILGenerator();
Generator = method.GetILGenerator();
_subroutine = new TranslatedSub(mthd, Params);
}
TranslatedSub subroutine = new TranslatedSub(method, subArgs);
private void InitLocals()
{
int paramsStart = TranslatedSub.FixedArgTypes.Length;
int argsStart = TranslatedSub.FixedArgTypes.Length;
_locals = new Dictionary<Register, int>();
for (int index = 0; index < _subroutine.Params.Count; index++)
{
Register reg = _subroutine.Params[index];
_localsCount = 0;
Generator.EmitLdarg(index + paramsStart);
for (int index = 0; index < subroutine.SubArgs.Count; index++)
{
Register reg = subroutine.SubArgs[index];
Generator.EmitLdarg(index + argsStart);
Generator.EmitStloc(GetLocalIndex(reg));
}
foreach (ILBlock ilBlock in _ilBlocks)
{
ilBlock.Emit(this);
}
return subroutine;
}
private Type[] GetParamTypes(IList<Register> Params)
private Type[] GetArgumentTypes(IList<Register> Params)
{
Type[] fixedArgs = TranslatedSub.FixedArgTypes;
@ -140,7 +98,7 @@ namespace ChocolArm64.Translation
{
if (!_locals.TryGetValue(reg, out int index))
{
Generator.DeclareLocal(GetLocalType(reg));
Generator.DeclareLocal(GetFieldType(reg.Type));
index = _localsCount++;
@ -150,9 +108,7 @@ namespace ChocolArm64.Translation
return index;
}
public Type GetLocalType(Register reg) => GetFieldType(reg.Type);
public Type GetFieldType(RegisterType regType)
private static Type GetFieldType(RegisterType regType)
{
switch (regType)
{
@ -182,7 +138,7 @@ namespace ChocolArm64.Translation
public static bool IsRegIndex(int index)
{
return index >= 0 && index < 32;
return (uint)index < 32;
}
}
}

View file

@ -11,7 +11,7 @@ namespace ChocolArm64.Translation
_ilOp = ilOp;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
context.Generator.Emit(_ilOp);
}

View file

@ -13,7 +13,7 @@ namespace ChocolArm64.Translation
_label = label;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
context.Generator.Emit(_ilOp, _label.GetLabel(context));
}

View file

@ -12,7 +12,7 @@ namespace ChocolArm64.Translation
_mthdInfo = mthdInfo;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
context.Generator.Emit(OpCodes.Call, _mthdInfo);
}

View file

@ -51,7 +51,7 @@ namespace ChocolArm64.Translation
_value = new ImmVal { R8 = value };
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
switch (_type)
{

View file

@ -3,7 +3,7 @@ using System.Reflection.Emit;
namespace ChocolArm64.Translation
{
struct IlOpCodeLoad : IILEmit
struct ILOpCodeLoad : IILEmit
{
public int Index { get; private set; }
@ -11,55 +11,26 @@ namespace ChocolArm64.Translation
public RegisterSize RegisterSize { get; private set; }
public IlOpCodeLoad(int index, IoType ioType, RegisterSize registerSize = 0)
public ILOpCodeLoad(int index, IoType ioType, RegisterSize registerSize = 0)
{
Index = index;
IoType = ioType;
RegisterSize = registerSize;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
switch (IoType)
{
case IoType.Arg: context.Generator.EmitLdarg(Index); break;
case IoType.Fields:
{
long intInputs = context.LocalAlloc.GetIntInputs(context.GetIlBlock(Index));
long vecInputs = context.LocalAlloc.GetVecInputs(context.GetIlBlock(Index));
LoadLocals(context, intInputs, RegisterType.Int);
LoadLocals(context, vecInputs, RegisterType.Vector);
break;
}
case IoType.Flag: EmitLdloc(context, Index, RegisterType.Flag); break;
case IoType.Int: EmitLdloc(context, Index, RegisterType.Int); break;
case IoType.Vector: EmitLdloc(context, Index, RegisterType.Vector); break;
}
}
private void LoadLocals(ILEmitter context, long inputs, RegisterType baseType)
{
for (int bit = 0; bit < 64; bit++)
{
long mask = 1L << bit;
if ((inputs & mask) != 0)
{
Register reg = ILEmitter.GetRegFromBit(bit, baseType);
context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
context.Generator.Emit(OpCodes.Ldfld, reg.GetField());
context.Generator.EmitStloc(context.GetLocalIndex(reg));
}
}
}
private void EmitLdloc(ILEmitter context, int index, RegisterType registerType)
private void EmitLdloc(ILMethodBuilder context, int index, RegisterType registerType)
{
Register reg = new Register(index, registerType);

View file

@ -0,0 +1,42 @@
using ChocolArm64.State;
using System.Reflection.Emit;
namespace ChocolArm64.Translation
{
struct ILOpCodeLoadState : IILEmit
{
private ILBlock _block;
public ILOpCodeLoadState(ILBlock block)
{
_block = block;
}
public void Emit(ILMethodBuilder context)
{
long intInputs = context.LocalAlloc.GetIntInputs(_block);
long vecInputs = context.LocalAlloc.GetVecInputs(_block);
LoadLocals(context, intInputs, RegisterType.Int);
LoadLocals(context, vecInputs, RegisterType.Vector);
}
private void LoadLocals(ILMethodBuilder context, long inputs, RegisterType baseType)
{
for (int bit = 0; bit < 64; bit++)
{
long mask = 1L << bit;
if ((inputs & mask) != 0)
{
Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
context.Generator.Emit(OpCodes.Ldfld, reg.GetField());
context.Generator.EmitStloc(context.GetLocalIndex(reg));
}
}
}
}
}

View file

@ -9,7 +9,7 @@ namespace ChocolArm64.Translation
_text = text;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
context.Generator.EmitWriteLine(_text);
}

View file

@ -3,7 +3,7 @@ using System.Reflection.Emit;
namespace ChocolArm64.Translation
{
struct IlOpCodeStore : IILEmit
struct ILOpCodeStore : IILEmit
{
public int Index { get; private set; }
@ -11,55 +11,26 @@ namespace ChocolArm64.Translation
public RegisterSize RegisterSize { get; private set; }
public IlOpCodeStore(int index, IoType ioType, RegisterSize registerSize = 0)
public ILOpCodeStore(int index, IoType ioType, RegisterSize registerSize = 0)
{
Index = index;
IoType = ioType;
RegisterSize = registerSize;
}
public void Emit(ILEmitter context)
public void Emit(ILMethodBuilder context)
{
switch (IoType)
{
case IoType.Arg: context.Generator.EmitStarg(Index); break;
case IoType.Fields:
{
long intOutputs = context.LocalAlloc.GetIntOutputs(context.GetIlBlock(Index));
long vecOutputs = context.LocalAlloc.GetVecOutputs(context.GetIlBlock(Index));
StoreLocals(context, intOutputs, RegisterType.Int);
StoreLocals(context, vecOutputs, RegisterType.Vector);
break;
}
case IoType.Flag: EmitStloc(context, Index, RegisterType.Flag); break;
case IoType.Int: EmitStloc(context, Index, RegisterType.Int); break;
case IoType.Vector: EmitStloc(context, Index, RegisterType.Vector); break;
}
}
private void StoreLocals(ILEmitter context, long outputs, RegisterType baseType)
{
for (int bit = 0; bit < 64; bit++)
{
long mask = 1L << bit;
if ((outputs & mask) != 0)
{
Register reg = ILEmitter.GetRegFromBit(bit, baseType);
context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
context.Generator.EmitLdloc(context.GetLocalIndex(reg));
context.Generator.Emit(OpCodes.Stfld, reg.GetField());
}
}
}
private void EmitStloc(ILEmitter context, int index, RegisterType registerType)
private void EmitStloc(ILMethodBuilder context, int index, RegisterType registerType)
{
Register reg = new Register(index, registerType);

View file

@ -0,0 +1,42 @@
using ChocolArm64.State;
using System.Reflection.Emit;
namespace ChocolArm64.Translation
{
struct ILOpCodeStoreState : IILEmit
{
private ILBlock _block;
public ILOpCodeStoreState(ILBlock block)
{
_block = block;
}
public void Emit(ILMethodBuilder context)
{
long intOutputs = context.LocalAlloc.GetIntOutputs(_block);
long vecOutputs = context.LocalAlloc.GetVecOutputs(_block);
StoreLocals(context, intOutputs, RegisterType.Int);
StoreLocals(context, vecOutputs, RegisterType.Vector);
}
private void StoreLocals(ILMethodBuilder context, long outputs, RegisterType baseType)
{
for (int bit = 0; bit < 64; bit++)
{
long mask = 1L << bit;
if ((outputs & mask) != 0)
{
Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
context.Generator.EmitLdloc(context.GetLocalIndex(reg));
context.Generator.Emit(OpCodes.Stfld, reg.GetField());
}
}
}
}
}

View file

@ -1,15 +1,10 @@
using System;
namespace ChocolArm64.Translation
{
[Flags]
enum IoType
{
Arg,
Fields,
Flag,
Int,
Float,
Vector
}
}

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
namespace ChocolArm64.Translation
@ -65,11 +66,41 @@ namespace ChocolArm64.Translation
public long VecInputs;
public long IntOutputs;
public long VecOutputs;
public override bool Equals(object obj)
{
if (!(obj is BlockIo other))
{
return false;
}
return other.Block == Block &&
other.Entry == Entry &&
other.IntInputs == IntInputs &&
other.VecInputs == VecInputs &&
other.IntOutputs == IntOutputs &&
other.VecOutputs == VecOutputs;
}
public override int GetHashCode()
{
return HashCode.Combine(Block, Entry, IntInputs, VecInputs, IntOutputs, VecOutputs);
}
public static bool operator ==(BlockIo lhs, BlockIo rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(BlockIo lhs, BlockIo rhs)
{
return !(lhs == rhs);
}
}
private const int MaxOptGraphLength = 40;
public LocalAlloc(ILBlock[] graph, ILBlock root)
public LocalAlloc(ILBlock[] graph, ILBlock entry)
{
_intPaths = new Dictionary<ILBlock, PathIo>();
_vecPaths = new Dictionary<ILBlock, PathIo>();
@ -77,7 +108,7 @@ namespace ChocolArm64.Translation
if (graph.Length > 1 &&
graph.Length < MaxOptGraphLength)
{
InitializeOptimal(graph, root);
InitializeOptimal(graph, entry);
}
else
{
@ -85,7 +116,7 @@ namespace ChocolArm64.Translation
}
}
private void InitializeOptimal(ILBlock[] graph, ILBlock root)
private void InitializeOptimal(ILBlock[] graph, ILBlock entry)
{
//This will go through all possible paths on the graph,
//and store all inputs/outputs for each block. A register
@ -93,7 +124,7 @@ namespace ChocolArm64.Translation
//When a block can be reached by more than one path, then the
//output from all paths needs to be set for this block, and
//only outputs present in all of the parent blocks can be considered
//when doing input elimination. Each block chain have a root, that's where
//when doing input elimination. Each block chain have a entry, that's where
//the code starts executing. They are present on the subroutine start point,
//and on call return points too (address written to X30 by BL).
HashSet<BlockIo> visited = new HashSet<BlockIo>();
@ -112,8 +143,8 @@ namespace ChocolArm64.Translation
Enqueue(new BlockIo()
{
Block = root,
Entry = root
Block = entry,
Entry = entry
});
while (unvisited.Count > 0)
@ -146,22 +177,22 @@ namespace ChocolArm64.Translation
void EnqueueFromCurrent(ILBlock block, bool retTarget)
{
BlockIo blkIO = new BlockIo() { Block = block };
BlockIo blockIo = new BlockIo() { Block = block };
if (retTarget)
{
blkIO.Entry = block;
blockIo.Entry = block;
}
else
{
blkIO.Entry = current.Entry;
blkIO.IntInputs = current.IntInputs;
blkIO.VecInputs = current.VecInputs;
blkIO.IntOutputs = current.IntOutputs;
blkIO.VecOutputs = current.VecOutputs;
blockIo.Entry = current.Entry;
blockIo.IntInputs = current.IntInputs;
blockIo.VecInputs = current.VecInputs;
blockIo.IntOutputs = current.IntOutputs;
blockIo.VecOutputs = current.VecOutputs;
}
Enqueue(blkIO);
Enqueue(blockIo);
}
if (current.Block.Next != null)
@ -179,7 +210,7 @@ namespace ChocolArm64.Translation
private void InitializeFast(ILBlock[] graph)
{
//This is WAY faster than InitializeOptimal, but results in
//uneeded loads and stores, so the resulting code will be slower.
//unneeded loads and stores, so the resulting code will be slower.
long intInputs = 0, intOutputs = 0;
long vecInputs = 0, vecOutputs = 0;

View file

@ -83,47 +83,45 @@ namespace ChocolArm64
{
Block block = Decoder.DecodeBasicBlock(state, memory, position);
Block[] graph = new Block[] { block };
ILEmitterCtx context = new ILEmitterCtx(_cache, block);
string subName = GetSubroutineName(position);
ILEmitterCtx context = new ILEmitterCtx(_cache, graph, block, subName);
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName);
do
{
context.EmitOpCode();
}
while (context.AdvanceOpCode());
TranslatedSub subroutine = context.GetSubroutine();
TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
subroutine.SetType(TranslatedSubType.SubTier0);
_cache.AddOrUpdate(position, subroutine, block.OpCodes.Count);
OpCode64 lastOp = block.GetLastOp();
return subroutine;
}
private void TranslateTier1(CpuThreadState state, MemoryManager memory, long position)
{
(Block[] graph, Block root) = Decoder.DecodeSubroutine(_cache, state, memory, position);
Block graph = Decoder.DecodeSubroutine(_cache, state, memory, position);
ILEmitterCtx context = new ILEmitterCtx(_cache, graph);
ILBlock[] ilBlocks = context.GetILBlocks();
string subName = GetSubroutineName(position);
ILEmitterCtx context = new ILEmitterCtx(_cache, graph, root, subName);
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName);
if (context.CurrBlock.Position != position)
TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
subroutine.SetType(TranslatedSubType.SubTier1);
int ilOpCount = 0;
foreach (ILBlock ilBlock in ilBlocks)
{
context.Emit(OpCodes.Br, context.GetLabel(position));
ilOpCount += ilBlock.Count;
}
do
{
context.EmitOpCode();
}
while (context.AdvanceOpCode());
_cache.AddOrUpdate(position, subroutine, ilOpCount);
//Mark all methods that calls this method for ReJiting,
//since we can now call it directly which is faster.
@ -137,29 +135,11 @@ namespace ChocolArm64
}
}
}
TranslatedSub subroutine = context.GetSubroutine();
subroutine.SetType(TranslatedSubType.SubTier1);
_cache.AddOrUpdate(position, subroutine, GetGraphInstCount(graph));
}
private string GetSubroutineName(long position)
{
return $"Sub{position:x16}";
}
private int GetGraphInstCount(Block[] graph)
{
int size = 0;
foreach (Block block in graph)
{
size += block.OpCodes.Count;
}
return size;
}
}
}

View file

@ -9,8 +9,8 @@ namespace ChocolArm64
{
class TranslatorCache
{
//Maximum size of the cache, in bytes, measured in ARM code size.
private const int MaxTotalSize = 4 * 1024 * 256;
//Maximum size of the cache, the unit used is completely arbitrary.
private const int MaxTotalSize = 0x800000;
//Minimum time required in milliseconds for a method to be eligible for deletion.
private const int MinTimeDelta = 2 * 60000;
@ -63,10 +63,10 @@ namespace ChocolArm64
{
ClearCacheIfNeeded();
_totalSize += size;
lock (_sortedCache)
{
_totalSize += size;
LinkedListNode<long> node = _sortedCache.AddLast(position);
CacheBucket newBucket = new CacheBucket(subroutine, node, size);
@ -98,11 +98,18 @@ namespace ChocolArm64
{
try
{
bucket.CallCount = 0;
//The bucket value on the dictionary may have changed between the
//time we get the value from the dictionary, and we acquire the
//lock. So we need to ensure we are working with the latest value,
//we can do that by getting the value again, inside the lock.
if (_cache.TryGetValue(position, out CacheBucket latestBucket))
{
latestBucket.CallCount = 0;
_sortedCache.Remove(bucket.Node);
_sortedCache.Remove(latestBucket.Node);
bucket.UpdateNode(_sortedCache.AddLast(position));
latestBucket.UpdateNode(_sortedCache.AddLast(position));
}
}
finally
{

View file

@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Memory
{
this.Memory = Memory;
Cache = new NvGpuVmmCache();
Cache = new NvGpuVmmCache(Memory);
PageTable = new long[PTLvl0Size][];
}
@ -262,7 +262,7 @@ namespace Ryujinx.Graphics.Memory
public bool IsRegionModified(long PA, long Size, NvGpuBufferType BufferType)
{
return Cache.IsRegionModified(Memory, BufferType, PA, Size);
return Cache.IsRegionModified(PA, Size, BufferType);
}
public bool TryGetHostAddress(long Position, long Size, out IntPtr Ptr)

View file

@ -1,130 +1,83 @@
using ChocolArm64.Events;
using ChocolArm64.Memory;
using System;
using System.Collections.Concurrent;
namespace Ryujinx.Graphics.Memory
{
class NvGpuVmmCache
{
private struct CachedResource
private const int PageBits = MemoryManager.PageBits;
private const long PageSize = MemoryManager.PageSize;
private const long PageMask = MemoryManager.PageMask;
private ConcurrentDictionary<long, int>[] CachedPages;
private MemoryManager _memory;
public NvGpuVmmCache(MemoryManager memory)
{
public long Key;
public int Mask;
_memory = memory;
public CachedResource(long Key, int Mask)
{
this.Key = Key;
this.Mask = Mask;
}
_memory.ObservedAccess += MemoryAccessHandler;
public override int GetHashCode()
{
return (int)(Key * 23 + Mask);
}
public override bool Equals(object obj)
{
return obj is CachedResource Cached && Equals(Cached);
}
public bool Equals(CachedResource other)
{
return Key == other.Key && Mask == other.Mask;
}
CachedPages = new ConcurrentDictionary<long, int>[1 << 20];
}
private ValueRangeSet<CachedResource> CachedRanges;
public NvGpuVmmCache()
private void MemoryAccessHandler(object sender, MemoryAccessEventArgs e)
{
CachedRanges = new ValueRangeSet<CachedResource>();
long pa = _memory.GetPhysicalAddress(e.Position);
CachedPages[pa >> PageBits]?.Clear();
}
public bool IsRegionModified(MemoryManager Memory, NvGpuBufferType BufferType, long Start, long Size)
public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
{
(bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(Start, Size);
long pa = _memory.GetPhysicalAddress(position);
//Remove all modified ranges.
int Index = 0;
long addr = pa;
long Position = Start & ~NvGpuVmm.PageMask;
long endAddr = (addr + size + PageMask) & ~PageMask;
while (ModifiedCount > 0)
int newBuffMask = 1 << (int)bufferType;
_memory.StartObservingRegion(position, size);
long cachedPagesCount = 0;
while (addr < endAddr)
{
if (Modified[Index++])
{
CachedRanges.Remove(new ValueRange<CachedResource>(Position, Position + NvGpuVmm.PageSize));
long page = addr >> PageBits;
ModifiedCount--;
ConcurrentDictionary<long, int> dictionary = CachedPages[page];
if (dictionary == null)
{
dictionary = new ConcurrentDictionary<long, int>();
CachedPages[page] = dictionary;
}
Position += NvGpuVmm.PageSize;
if (dictionary.TryGetValue(pa, out int currBuffMask))
{
if ((currBuffMask & newBuffMask) != 0)
{
cachedPagesCount++;
}
else
{
dictionary[pa] |= newBuffMask;
}
}
else
{
dictionary[pa] = newBuffMask;
}
addr += PageSize;
}
//Mask has the bit set for the current resource type.
//If the region is not yet present on the list, then a new ValueRange
//is directly added with the current resource type as the only bit set.
//Otherwise, it just sets the bit for this new resource type on the current mask.
//The physical address of the resource is used as key, those keys are used to keep
//track of resources that are already on the cache. A resource may be inside another
//resource, and in this case we should return true if the "sub-resource" was not
//yet cached.
int Mask = 1 << (int)BufferType;
CachedResource NewCachedValue = new CachedResource(Start, Mask);
ValueRange<CachedResource> NewCached = new ValueRange<CachedResource>(Start, Start + Size);
ValueRange<CachedResource>[] Ranges = CachedRanges.GetAllIntersections(NewCached);
bool IsKeyCached = Ranges.Length > 0 && Ranges[0].Value.Key == Start;
long LastEnd = NewCached.Start;
long Coverage = 0;
for (Index = 0; Index < Ranges.Length; Index++)
{
ValueRange<CachedResource> Current = Ranges[Index];
CachedResource Cached = Current.Value;
long RgStart = Math.Max(Current.Start, NewCached.Start);
long RgEnd = Math.Min(Current.End, NewCached.End);
if ((Cached.Mask & Mask) != 0)
{
Coverage += RgEnd - RgStart;
}
//Highest key value has priority, this prevents larger resources
//for completely invalidating smaller ones on the cache. For example,
//consider that a resource in the range [100, 200) was added, and then
//another one in the range [50, 200). We prevent the new resource from
//completely replacing the old one by spliting it like this:
//New resource key is added at [50, 100), old key is still present at [100, 200).
if (Cached.Key < Start)
{
Cached.Key = Start;
}
Cached.Mask |= Mask;
CachedRanges.Add(new ValueRange<CachedResource>(RgStart, RgEnd, Cached));
if (RgStart > LastEnd)
{
CachedRanges.Add(new ValueRange<CachedResource>(LastEnd, RgStart, NewCachedValue));
}
LastEnd = RgEnd;
}
if (LastEnd < NewCached.End)
{
CachedRanges.Add(new ValueRange<CachedResource>(LastEnd, NewCached.End, NewCachedValue));
}
return !IsKeyCached || Coverage != Size;
return cachedPagesCount != (endAddr - pa + PageMask) >> PageBits;
}
}
}

View file

@ -1,17 +0,0 @@
namespace Ryujinx.Graphics
{
struct ValueRange<T>
{
public long Start { get; private set; }
public long End { get; private set; }
public T Value { get; set; }
public ValueRange(long Start, long End, T Value = default(T))
{
this.Start = Start;
this.End = End;
this.Value = Value;
}
}
}

View file

@ -1,234 +0,0 @@
using System.Collections.Generic;
namespace Ryujinx.Graphics
{
class ValueRangeSet<T>
{
private List<ValueRange<T>> Ranges;
public ValueRangeSet()
{
Ranges = new List<ValueRange<T>>();
}
public void Add(ValueRange<T> Range)
{
if (Range.End <= Range.Start)
{
//Empty or invalid range, do nothing.
return;
}
int First = BinarySearchFirstIntersection(Range);
if (First == -1)
{
//No intersections case.
//Find first greater than range (after the current one).
//If found, add before, otherwise add to the end of the list.
int GtIndex = BinarySearchGt(Range);
if (GtIndex != -1)
{
Ranges.Insert(GtIndex, Range);
}
else
{
Ranges.Add(Range);
}
return;
}
(int Start, int End) = GetAllIntersectionRanges(Range, First);
ValueRange<T> Prev = Ranges[Start];
ValueRange<T> Next = Ranges[End];
Ranges.RemoveRange(Start, (End - Start) + 1);
InsertNextNeighbour(Start, Range, Next);
int NewIndex = Start;
Ranges.Insert(Start, Range);
InsertPrevNeighbour(Start, Range, Prev);
//Try merging neighbours if the value is equal.
if (NewIndex > 0)
{
Prev = Ranges[NewIndex - 1];
if (Prev.End == Range.Start && CompareValues(Prev, Range))
{
Ranges.RemoveAt(--NewIndex);
Ranges[NewIndex] = new ValueRange<T>(Prev.Start, Range.End, Range.Value);
}
}
if (NewIndex < Ranges.Count - 1)
{
Next = Ranges[NewIndex + 1];
if (Next.Start == Range.End && CompareValues(Next, Range))
{
Ranges.RemoveAt(NewIndex + 1);
Ranges[NewIndex] = new ValueRange<T>(Ranges[NewIndex].Start, Next.End, Range.Value);
}
}
}
private bool CompareValues(ValueRange<T> LHS, ValueRange<T> RHS)
{
return LHS.Value?.Equals(RHS.Value) ?? RHS.Value == null;
}
public void Remove(ValueRange<T> Range)
{
int First = BinarySearchFirstIntersection(Range);
if (First == -1)
{
//Nothing to remove.
return;
}
(int Start, int End) = GetAllIntersectionRanges(Range, First);
ValueRange<T> Prev = Ranges[Start];
ValueRange<T> Next = Ranges[End];
Ranges.RemoveRange(Start, (End - Start) + 1);
InsertNextNeighbour(Start, Range, Next);
InsertPrevNeighbour(Start, Range, Prev);
}
private void InsertNextNeighbour(int Index, ValueRange<T> Range, ValueRange<T> Next)
{
//Split last intersection (ordered by Start) if necessary.
if (Range.End < Next.End)
{
InsertNewRange(Index, Range.End, Next.End, Next.Value);
}
}
private void InsertPrevNeighbour(int Index, ValueRange<T> Range, ValueRange<T> Prev)
{
//Split first intersection (ordered by Start) if necessary.
if (Range.Start > Prev.Start)
{
InsertNewRange(Index, Prev.Start, Range.Start, Prev.Value);
}
}
private void InsertNewRange(int Index, long Start, long End, T Value)
{
Ranges.Insert(Index, new ValueRange<T>(Start, End, Value));
}
public ValueRange<T>[] GetAllIntersections(ValueRange<T> Range)
{
int First = BinarySearchFirstIntersection(Range);
if (First == -1)
{
return new ValueRange<T>[0];
}
(int Start, int End) = GetAllIntersectionRanges(Range, First);
return Ranges.GetRange(Start, (End - Start) + 1).ToArray();
}
private (int Start, int End) GetAllIntersectionRanges(ValueRange<T> Range, int BaseIndex)
{
int Start = BaseIndex;
int End = BaseIndex;
while (Start > 0 && Intersects(Range, Ranges[Start - 1]))
{
Start--;
}
while (End < Ranges.Count - 1 && Intersects(Range, Ranges[End + 1]))
{
End++;
}
return (Start, End);
}
private int BinarySearchFirstIntersection(ValueRange<T> Range)
{
int Left = 0;
int Right = Ranges.Count - 1;
while (Left <= Right)
{
int Size = Right - Left;
int Middle = Left + (Size >> 1);
ValueRange<T> Current = Ranges[Middle];
if (Intersects(Range, Current))
{
return Middle;
}
if (Range.Start < Current.Start)
{
Right = Middle - 1;
}
else
{
Left = Middle + 1;
}
}
return -1;
}
private int BinarySearchGt(ValueRange<T> Range)
{
int GtIndex = -1;
int Left = 0;
int Right = Ranges.Count - 1;
while (Left <= Right)
{
int Size = Right - Left;
int Middle = Left + (Size >> 1);
ValueRange<T> Current = Ranges[Middle];
if (Range.Start < Current.Start)
{
Right = Middle - 1;
if (GtIndex == -1 || Current.Start < Ranges[GtIndex].Start)
{
GtIndex = Middle;
}
}
else
{
Left = Middle + 1;
}
}
return GtIndex;
}
private bool Intersects(ValueRange<T> LHS, ValueRange<T> RHS)
{
return LHS.Start < RHS.End && RHS.Start < LHS.End;
}
}
}

View file

@ -9,107 +9,107 @@ namespace Ryujinx.HLE
public IntPtr RamPointer { get; private set; }
private unsafe byte* RamPtr;
private unsafe byte* _ramPtr;
public unsafe DeviceMemory()
{
RamPointer = Marshal.AllocHGlobal(new IntPtr(RamSize));
RamPtr = (byte*)RamPointer;
_ramPtr = (byte*)RamPointer;
}
public sbyte ReadSByte(long Position)
public sbyte ReadSByte(long position)
{
return (sbyte)ReadByte(Position);
return (sbyte)ReadByte(position);
}
public short ReadInt16(long Position)
public short ReadInt16(long position)
{
return (short)ReadUInt16(Position);
return (short)ReadUInt16(position);
}
public int ReadInt32(long Position)
public int ReadInt32(long position)
{
return (int)ReadUInt32(Position);
return (int)ReadUInt32(position);
}
public long ReadInt64(long Position)
public long ReadInt64(long position)
{
return (long)ReadUInt64(Position);
return (long)ReadUInt64(position);
}
public unsafe byte ReadByte(long Position)
public unsafe byte ReadByte(long position)
{
return *((byte*)(RamPtr + Position));
return *(_ramPtr + position);
}
public unsafe ushort ReadUInt16(long Position)
public unsafe ushort ReadUInt16(long position)
{
return *((ushort*)(RamPtr + Position));
return *((ushort*)(_ramPtr + position));
}
public unsafe uint ReadUInt32(long Position)
public unsafe uint ReadUInt32(long position)
{
return *((uint*)(RamPtr + Position));
return *((uint*)(_ramPtr + position));
}
public unsafe ulong ReadUInt64(long Position)
public unsafe ulong ReadUInt64(long position)
{
return *((ulong*)(RamPtr + Position));
return *((ulong*)(_ramPtr + position));
}
public void WriteSByte(long Position, sbyte Value)
public void WriteSByte(long position, sbyte value)
{
WriteByte(Position, (byte)Value);
WriteByte(position, (byte)value);
}
public void WriteInt16(long Position, short Value)
public void WriteInt16(long position, short value)
{
WriteUInt16(Position, (ushort)Value);
WriteUInt16(position, (ushort)value);
}
public void WriteInt32(long Position, int Value)
public void WriteInt32(long position, int value)
{
WriteUInt32(Position, (uint)Value);
WriteUInt32(position, (uint)value);
}
public void WriteInt64(long Position, long Value)
public void WriteInt64(long position, long value)
{
WriteUInt64(Position, (ulong)Value);
WriteUInt64(position, (ulong)value);
}
public unsafe void WriteByte(long Position, byte Value)
public unsafe void WriteByte(long position, byte value)
{
*((byte*)(RamPtr + Position)) = Value;
*(_ramPtr + position) = value;
}
public unsafe void WriteUInt16(long Position, ushort Value)
public unsafe void WriteUInt16(long position, ushort value)
{
*((ushort*)(RamPtr + Position)) = Value;
*((ushort*)(_ramPtr + position)) = value;
}
public unsafe void WriteUInt32(long Position, uint Value)
public unsafe void WriteUInt32(long position, uint value)
{
*((uint*)(RamPtr + Position)) = Value;
*((uint*)(_ramPtr + position)) = value;
}
public unsafe void WriteUInt64(long Position, ulong Value)
public unsafe void WriteUInt64(long position, ulong value)
{
*((ulong*)(RamPtr + Position)) = Value;
*((ulong*)(_ramPtr + position)) = value;
}
public void FillWithZeros(long Position, int Size)
public void FillWithZeros(long position, int size)
{
int Size8 = Size & ~(8 - 1);
int size8 = size & ~(8 - 1);
for (int Offs = 0; Offs < Size8; Offs += 8)
for (int offs = 0; offs < size8; offs += 8)
{
WriteInt64(Position + Offs, 0);
WriteInt64(position + offs, 0);
}
for (int Offs = Size8; Offs < (Size - Size8); Offs++)
for (int offs = size8; offs < (size - size8); offs++)
{
WriteByte(Position + Offs, 0);
WriteByte(position + offs, 0);
}
}
@ -118,7 +118,7 @@ namespace Ryujinx.HLE
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
Marshal.FreeHGlobal(RamPointer);
}

View file

@ -4,6 +4,6 @@ namespace Ryujinx.HLE.Exceptions
{
public class InvalidNpdmException : Exception
{
public InvalidNpdmException(string ExMsg) : base(ExMsg) { }
public InvalidNpdmException(string message) : base(message) { }
}
}

View file

@ -8,6 +8,6 @@ namespace Ryujinx.HLE.Exceptions
public UndefinedInstructionException() : base() { }
public UndefinedInstructionException(long Position, int OpCode) : base(string.Format(ExMsg, Position, OpCode)) { }
public UndefinedInstructionException(long position, int opCode) : base(string.Format(ExMsg, position, opCode)) { }
}
}

View file

@ -9,297 +9,297 @@ namespace Ryujinx.HLE.FileSystem.Content
{
internal class ContentManager
{
private Dictionary<StorageId, LinkedList<LocationEntry>> LocationEntries;
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries;
private Dictionary<string, long> SharedFontTitleDictionary;
private Dictionary<string, long> _sharedFontTitleDictionary;
private SortedDictionary<(ulong, ContentType), string> ContentDictionary;
private SortedDictionary<(ulong, ContentType), string> _contentDictionary;
private Switch Device;
private Switch _device;
public ContentManager(Switch Device)
public ContentManager(Switch device)
{
ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
LocationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
SharedFontTitleDictionary = new Dictionary<string, long>()
_sharedFontTitleDictionary = new Dictionary<string, long>
{
{ "FontStandard", 0x0100000000000811 },
{ "FontChineseSimplified", 0x0100000000000814 },
{ "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended" , 0x0100000000000810 },
{ "FontNintendoExtended", 0x0100000000000810 }
};
this.Device = Device;
_device = device;
}
public void LoadEntries()
{
ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
foreach (StorageId StorageId in Enum.GetValues(typeof(StorageId)))
foreach (StorageId storageId in Enum.GetValues(typeof(StorageId)))
{
string ContentDirectory = null;
string ContentPathString = null;
string RegisteredDirectory = null;
string contentDirectory = null;
string contentPathString = null;
string registeredDirectory = null;
try
{
ContentPathString = LocationHelper.GetContentRoot(StorageId);
ContentDirectory = LocationHelper.GetRealPath(Device.FileSystem, ContentPathString);
RegisteredDirectory = Path.Combine(ContentDirectory, "registered");
contentPathString = LocationHelper.GetContentRoot(storageId);
contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered");
}
catch (NotSupportedException NEx)
catch (NotSupportedException)
{
continue;
}
Directory.CreateDirectory(RegisteredDirectory);
Directory.CreateDirectory(registeredDirectory);
LinkedList<LocationEntry> LocationList = new LinkedList<LocationEntry>();
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>();
void AddEntry(LocationEntry Entry)
void AddEntry(LocationEntry entry)
{
LocationList.AddLast(Entry);
locationList.AddLast(entry);
}
foreach (string DirectoryPath in Directory.EnumerateDirectories(RegisteredDirectory))
foreach (string directoryPath in Directory.EnumerateDirectories(registeredDirectory))
{
if (Directory.GetFiles(DirectoryPath).Length > 0)
if (Directory.GetFiles(directoryPath).Length > 0)
{
string NcaName = new DirectoryInfo(DirectoryPath).Name.Replace(".nca", string.Empty);
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
using (FileStream NcaFile = new FileStream(Directory.GetFiles(DirectoryPath)[0], FileMode.Open, FileAccess.Read))
using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read))
{
Nca Nca = new Nca(Device.System.KeySet, NcaFile, false);
Nca nca = new Nca(_device.System.KeySet, ncaFile, false);
string SwitchPath = Path.Combine(ContentPathString + ":",
NcaFile.Name.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
string switchPath = Path.Combine(contentPathString + ":",
ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's
SwitchPath = SwitchPath.Replace('\\', '/');
switchPath = switchPath.Replace('\\', '/');
LocationEntry Entry = new LocationEntry(SwitchPath,
LocationEntry entry = new LocationEntry(switchPath,
0,
(long)Nca.Header.TitleId,
Nca.Header.ContentType);
(long)nca.Header.TitleId,
nca.Header.ContentType);
AddEntry(Entry);
AddEntry(entry);
ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
NcaFile.Close();
Nca.Dispose();
NcaFile.Dispose();
ncaFile.Close();
nca.Dispose();
ncaFile.Dispose();
}
}
}
foreach (string FilePath in Directory.EnumerateFiles(ContentDirectory))
foreach (string filePath in Directory.EnumerateFiles(contentDirectory))
{
if (Path.GetExtension(FilePath) == ".nca")
if (Path.GetExtension(filePath) == ".nca")
{
string NcaName = Path.GetFileNameWithoutExtension(FilePath);
string ncaName = Path.GetFileNameWithoutExtension(filePath);
using (FileStream NcaFile = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
Nca Nca = new Nca(Device.System.KeySet, NcaFile, false);
Nca nca = new Nca(_device.System.KeySet, ncaFile, false);
string SwitchPath = Path.Combine(ContentPathString + ":",
FilePath.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
string switchPath = Path.Combine(contentPathString + ":",
filePath.Replace(contentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's
SwitchPath = SwitchPath.Replace('\\', '/');
switchPath = switchPath.Replace('\\', '/');
LocationEntry Entry = new LocationEntry(SwitchPath,
LocationEntry entry = new LocationEntry(switchPath,
0,
(long)Nca.Header.TitleId,
Nca.Header.ContentType);
(long)nca.Header.TitleId,
nca.Header.ContentType);
AddEntry(Entry);
AddEntry(entry);
ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
NcaFile.Close();
Nca.Dispose();
NcaFile.Dispose();
ncaFile.Close();
nca.Dispose();
ncaFile.Dispose();
}
}
}
if(LocationEntries.ContainsKey(StorageId) && LocationEntries[StorageId]?.Count == 0)
if(_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0)
{
LocationEntries.Remove(StorageId);
_locationEntries.Remove(storageId);
}
if (!LocationEntries.ContainsKey(StorageId))
if (!_locationEntries.ContainsKey(storageId))
{
LocationEntries.Add(StorageId, LocationList);
_locationEntries.Add(storageId, locationList);
}
}
}
public void ClearEntry(long TitleId, ContentType ContentType,StorageId StorageId)
public void ClearEntry(long titleId, ContentType contentType,StorageId storageId)
{
RemoveLocationEntry(TitleId, ContentType, StorageId);
RemoveLocationEntry(titleId, contentType, storageId);
}
public void RefreshEntries(StorageId StorageId, int Flag)
public void RefreshEntries(StorageId storageId, int flag)
{
LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
LinkedListNode<LocationEntry> LocationEntry = LocationList.First;
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
LinkedListNode<LocationEntry> locationEntry = locationList.First;
while (LocationEntry != null)
while (locationEntry != null)
{
LinkedListNode<LocationEntry> NextLocationEntry = LocationEntry.Next;
LinkedListNode<LocationEntry> nextLocationEntry = locationEntry.Next;
if (LocationEntry.Value.Flag == Flag)
if (locationEntry.Value.Flag == flag)
{
LocationList.Remove(LocationEntry.Value);
locationList.Remove(locationEntry.Value);
}
LocationEntry = NextLocationEntry;
locationEntry = nextLocationEntry;
}
}
public bool HasNca(string NcaId, StorageId StorageId)
public bool HasNca(string ncaId, StorageId storageId)
{
if (ContentDictionary.ContainsValue(NcaId))
if (_contentDictionary.ContainsValue(ncaId))
{
var Content = ContentDictionary.FirstOrDefault(x => x.Value == NcaId);
long TitleId = (long)Content.Key.Item1;
ContentType ContentType = Content.Key.Item2;
StorageId Storage = GetInstalledStorage(TitleId, ContentType, StorageId);
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
long titleId = (long)content.Key.Item1;
ContentType contentType = content.Key.Item2;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
return Storage == StorageId;
return storage == storageId;
}
return false;
}
public UInt128 GetInstalledNcaId(long TitleId, ContentType ContentType)
public UInt128 GetInstalledNcaId(long titleId, ContentType contentType)
{
if (ContentDictionary.ContainsKey(((ulong)TitleId,ContentType)))
if (_contentDictionary.ContainsKey(((ulong)titleId,contentType)))
{
return new UInt128(ContentDictionary[((ulong)TitleId,ContentType)]);
return new UInt128(_contentDictionary[((ulong)titleId,contentType)]);
}
return new UInt128();
}
public StorageId GetInstalledStorage(long TitleId, ContentType ContentType, StorageId StorageId)
public StorageId GetInstalledStorage(long titleId, ContentType contentType, StorageId storageId)
{
LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
return LocationEntry.ContentPath != null ?
LocationHelper.GetStorageId(LocationEntry.ContentPath) : StorageId.None;
return locationEntry.ContentPath != null ?
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
}
public string GetInstalledContentPath(long TitleId, StorageId StorageId, ContentType ContentType)
public string GetInstalledContentPath(long titleId, StorageId storageId, ContentType contentType)
{
LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
if (VerifyContentType(LocationEntry, ContentType))
if (VerifyContentType(locationEntry, contentType))
{
return LocationEntry.ContentPath;
return locationEntry.ContentPath;
}
return string.Empty;
}
public void RedirectLocation(LocationEntry NewEntry, StorageId StorageId)
public void RedirectLocation(LocationEntry newEntry, StorageId storageId)
{
LocationEntry LocationEntry = GetLocation(NewEntry.TitleId, NewEntry.ContentType, StorageId);
LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId);
if (LocationEntry.ContentPath != null)
if (locationEntry.ContentPath != null)
{
RemoveLocationEntry(NewEntry.TitleId, NewEntry.ContentType, StorageId);
RemoveLocationEntry(newEntry.TitleId, newEntry.ContentType, storageId);
}
AddLocationEntry(NewEntry, StorageId);
AddLocationEntry(newEntry, storageId);
}
private bool VerifyContentType(LocationEntry LocationEntry, ContentType ContentType)
private bool VerifyContentType(LocationEntry locationEntry, ContentType contentType)
{
if (LocationEntry.ContentPath == null)
if (locationEntry.ContentPath == null)
{
return false;
}
StorageId StorageId = LocationHelper.GetStorageId(LocationEntry.ContentPath);
string InstalledPath = Device.FileSystem.SwitchPathToSystemPath(LocationEntry.ContentPath);
StorageId storageId = LocationHelper.GetStorageId(locationEntry.ContentPath);
string installedPath = _device.FileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
if (!string.IsNullOrWhiteSpace(InstalledPath))
if (!string.IsNullOrWhiteSpace(installedPath))
{
if (File.Exists(InstalledPath))
if (File.Exists(installedPath))
{
FileStream File = new FileStream(InstalledPath, FileMode.Open, FileAccess.Read);
Nca Nca = new Nca(Device.System.KeySet, File, false);
bool ContentCheck = Nca.Header.ContentType == ContentType;
FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, file, false);
bool contentCheck = nca.Header.ContentType == contentType;
Nca.Dispose();
File.Dispose();
nca.Dispose();
file.Dispose();
return ContentCheck;
return contentCheck;
}
}
return false;
}
private void AddLocationEntry(LocationEntry Entry, StorageId StorageId)
private void AddLocationEntry(LocationEntry entry, StorageId storageId)
{
LinkedList<LocationEntry> LocationList = null;
LinkedList<LocationEntry> locationList = null;
if (LocationEntries.ContainsKey(StorageId))
if (_locationEntries.ContainsKey(storageId))
{
LocationList = LocationEntries[StorageId];
locationList = _locationEntries[storageId];
}
if (LocationList != null)
if (locationList != null)
{
if (LocationList.Contains(Entry))
if (locationList.Contains(entry))
{
LocationList.Remove(Entry);
locationList.Remove(entry);
}
LocationList.AddLast(Entry);
locationList.AddLast(entry);
}
}
private void RemoveLocationEntry(long TitleId, ContentType ContentType, StorageId StorageId)
private void RemoveLocationEntry(long titleId, ContentType contentType, StorageId storageId)
{
LinkedList<LocationEntry> LocationList = null;
LinkedList<LocationEntry> locationList = null;
if (LocationEntries.ContainsKey(StorageId))
if (_locationEntries.ContainsKey(storageId))
{
LocationList = LocationEntries[StorageId];
locationList = _locationEntries[storageId];
}
if (LocationList != null)
if (locationList != null)
{
LocationEntry Entry =
LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
LocationEntry entry =
locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
if (Entry.ContentPath != null)
if (entry.ContentPath != null)
{
LocationList.Remove(Entry);
locationList.Remove(entry);
}
}
}
public bool TryGetFontTitle(string FontName, out long TitleId)
public bool TryGetFontTitle(string fontName, out long titleId)
{
return SharedFontTitleDictionary.TryGetValue(FontName, out TitleId);
return _sharedFontTitleDictionary.TryGetValue(fontName, out titleId);
}
private LocationEntry GetLocation(long TitleId, ContentType ContentType,StorageId StorageId)
private LocationEntry GetLocation(long titleId, ContentType contentType,StorageId storageId)
{
LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
return LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
return locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
}
}
}

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using LibHac;
using LibHac;
namespace Ryujinx.HLE.FileSystem.Content
{
@ -12,17 +9,17 @@ namespace Ryujinx.HLE.FileSystem.Content
public long TitleId { get; private set; }
public ContentType ContentType { get; private set; }
public LocationEntry(string ContentPath, int Flag, long TitleId, ContentType ContentType)
public LocationEntry(string contentPath, int flag, long titleId, ContentType contentType)
{
this.ContentPath = ContentPath;
this.Flag = Flag;
this.TitleId = TitleId;
this.ContentType = ContentType;
ContentPath = contentPath;
Flag = flag;
TitleId = titleId;
ContentType = contentType;
}
public void SetFlag(int Flag)
public void SetFlag(int flag)
{
this.Flag = Flag;
Flag = flag;
}
}
}

View file

@ -7,30 +7,30 @@ namespace Ryujinx.HLE.FileSystem.Content
{
internal static class LocationHelper
{
public static string GetRealPath(VirtualFileSystem FileSystem, string SwitchContentPath)
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
{
string BasePath = FileSystem.GetBasePath();
string basePath = fileSystem.GetBasePath();
switch (SwitchContentPath)
switch (switchContentPath)
{
case ContentPath.SystemContent:
return Path.Combine(FileSystem.GetBasePath(), SystemNandPath, "Contents");
return Path.Combine(fileSystem.GetBasePath(), SystemNandPath, "Contents");
case ContentPath.UserContent:
return Path.Combine(FileSystem.GetBasePath(), UserNandPath, "Contents");
return Path.Combine(fileSystem.GetBasePath(), UserNandPath, "Contents");
case ContentPath.SdCardContent:
return Path.Combine(FileSystem.GetSdCardPath(), "Nintendo", "Contents");
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents");
case ContentPath.System:
return Path.Combine(BasePath, SystemNandPath);
return Path.Combine(basePath, SystemNandPath);
case ContentPath.User:
return Path.Combine(BasePath, UserNandPath);
return Path.Combine(basePath, UserNandPath);
default:
throw new NotSupportedException($"Content Path `{SwitchContentPath}` is not supported.");
throw new NotSupportedException($"Content Path `{switchContentPath}` is not supported.");
}
}
public static string GetContentPath(ContentStorageId ContentStorageId)
public static string GetContentPath(ContentStorageId contentStorageId)
{
switch (ContentStorageId)
switch (contentStorageId)
{
case ContentStorageId.NandSystem:
return ContentPath.SystemContent;
@ -39,13 +39,13 @@ namespace Ryujinx.HLE.FileSystem.Content
case ContentStorageId.SdCard:
return ContentPath.SdCardContent;
default:
throw new NotSupportedException($"Content Storage `{ContentStorageId}` is not supported.");
throw new NotSupportedException($"Content Storage `{contentStorageId}` is not supported.");
}
}
public static string GetContentRoot(StorageId StorageId)
public static string GetContentRoot(StorageId storageId)
{
switch (StorageId)
switch (storageId)
{
case StorageId.NandSystem:
return ContentPath.SystemContent;
@ -54,15 +54,15 @@ namespace Ryujinx.HLE.FileSystem.Content
case StorageId.SdCard:
return ContentPath.SdCardContent;
default:
throw new NotSupportedException($"Storage Id `{StorageId}` is not supported.");
throw new NotSupportedException($"Storage Id `{storageId}` is not supported.");
}
}
public static StorageId GetStorageId(string ContentPathString)
public static StorageId GetStorageId(string contentPathString)
{
string CleanedPath = ContentPathString.Split(':')[0];
string cleanedPath = contentPathString.Split(':')[0];
switch (CleanedPath)
switch (cleanedPath)
{
case ContentPath.SystemContent:
case ContentPath.System:

View file

@ -10,228 +10,228 @@ namespace Ryujinx.HLE.FileSystem
{
class FileSystemProvider : IFileSystemProvider
{
private readonly string BasePath;
private readonly string RootPath;
private readonly string _basePath;
private readonly string _rootPath;
public FileSystemProvider(string BasePath, string RootPath)
public FileSystemProvider(string basePath, string rootPath)
{
this.BasePath = BasePath;
this.RootPath = RootPath;
_basePath = basePath;
_rootPath = rootPath;
CheckIfDescendentOfRootPath(BasePath);
CheckIfDescendentOfRootPath(basePath);
}
public long CreateDirectory(string Name)
public long CreateDirectory(string name)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
if (Directory.Exists(Name))
if (Directory.Exists(name))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
Directory.CreateDirectory(Name);
Directory.CreateDirectory(name);
return 0;
}
public long CreateFile(string Name, long Size)
public long CreateFile(string name, long size)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
if (File.Exists(Name))
if (File.Exists(name))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
using (FileStream NewFile = File.Create(Name))
using (FileStream newFile = File.Create(name))
{
NewFile.SetLength(Size);
newFile.SetLength(size);
}
return 0;
}
public long DeleteDirectory(string Name, bool Recursive)
public long DeleteDirectory(string name, bool recursive)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
string DirName = Name;
string dirName = name;
if (!Directory.Exists(DirName))
if (!Directory.Exists(dirName))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
Directory.Delete(DirName, Recursive);
Directory.Delete(dirName, recursive);
return 0;
}
public long DeleteFile(string Name)
public long DeleteFile(string name)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
if (!File.Exists(Name))
if (!File.Exists(name))
{
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
else
{
File.Delete(Name);
File.Delete(name);
}
return 0;
}
public DirectoryEntry[] GetDirectories(string Path)
public DirectoryEntry[] GetDirectories(string path)
{
CheckIfDescendentOfRootPath(Path);
CheckIfDescendentOfRootPath(path);
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach(string Directory in Directory.EnumerateDirectories(Path))
foreach(string directory in Directory.EnumerateDirectories(path))
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
return Entries.ToArray();
return entries.ToArray();
}
public DirectoryEntry[] GetEntries(string Path)
public DirectoryEntry[] GetEntries(string path)
{
CheckIfDescendentOfRootPath(Path);
CheckIfDescendentOfRootPath(path);
if (Directory.Exists(Path))
if (Directory.Exists(path))
{
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach (string Directory in Directory.EnumerateDirectories(Path))
foreach (string directory in Directory.EnumerateDirectories(path))
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
foreach (string File in Directory.EnumerateFiles(Path))
foreach (string file in Directory.EnumerateFiles(path))
{
FileInfo FileInfo = new FileInfo(File);
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
FileInfo fileInfo = new FileInfo(file);
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
}
return null;
}
public DirectoryEntry[] GetFiles(string Path)
public DirectoryEntry[] GetFiles(string path)
{
CheckIfDescendentOfRootPath(Path);
CheckIfDescendentOfRootPath(path);
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach (string File in Directory.EnumerateFiles(Path))
foreach (string file in Directory.EnumerateFiles(path))
{
FileInfo FileInfo = new FileInfo(File);
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
FileInfo fileInfo = new FileInfo(file);
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
return Entries.ToArray();
return entries.ToArray();
}
public long GetFreeSpace(ServiceCtx Context)
public long GetFreeSpace(ServiceCtx context)
{
return Context.Device.FileSystem.GetDrive().AvailableFreeSpace;
return context.Device.FileSystem.GetDrive().AvailableFreeSpace;
}
public string GetFullPath(string Name)
public string GetFullPath(string name)
{
if (Name.StartsWith("//"))
if (name.StartsWith("//"))
{
Name = Name.Substring(2);
name = name.Substring(2);
}
else if (Name.StartsWith('/'))
else if (name.StartsWith('/'))
{
Name = Name.Substring(1);
name = name.Substring(1);
}
else
{
return null;
}
string FullPath = Path.Combine(BasePath, Name);
string fullPath = Path.Combine(_basePath, name);
CheckIfDescendentOfRootPath(FullPath);
CheckIfDescendentOfRootPath(fullPath);
return FullPath;
return fullPath;
}
public long GetTotalSpace(ServiceCtx Context)
public long GetTotalSpace(ServiceCtx context)
{
return Context.Device.FileSystem.GetDrive().TotalSize;
return context.Device.FileSystem.GetDrive().TotalSize;
}
public bool DirectoryExists(string Name)
public bool DirectoryExists(string name)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
return Directory.Exists(Name);
return Directory.Exists(name);
}
public bool FileExists(string Name)
public bool FileExists(string name)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
return File.Exists(Name);
return File.Exists(name);
}
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
if (Directory.Exists(Name))
if (Directory.Exists(name))
{
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
directoryInterface = new IDirectory(name, filterFlags, this);
return 0;
}
DirectoryInterface = null;
directoryInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long OpenFile(string Name, out IFile FileInterface)
public long OpenFile(string name, out IFile fileInterface)
{
CheckIfDescendentOfRootPath(Name);
CheckIfDescendentOfRootPath(name);
if (File.Exists(Name))
if (File.Exists(name))
{
FileStream Stream = new FileStream(Name, FileMode.Open);
FileStream stream = new FileStream(name, FileMode.Open);
FileInterface = new IFile(Stream, Name);
fileInterface = new IFile(stream, name);
return 0;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(NewName);
CheckIfDescendentOfRootPath(oldName);
CheckIfDescendentOfRootPath(newName);
if (Directory.Exists(OldName))
if (Directory.Exists(oldName))
{
Directory.Move(OldName, NewName);
Directory.Move(oldName, newName);
}
else
{
@ -241,14 +241,14 @@ namespace Ryujinx.HLE.FileSystem
return 0;
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(NewName);
CheckIfDescendentOfRootPath(oldName);
CheckIfDescendentOfRootPath(newName);
if (File.Exists(OldName))
if (File.Exists(oldName))
{
File.Move(OldName, NewName);
File.Move(oldName, newName);
}
else
{
@ -258,24 +258,24 @@ namespace Ryujinx.HLE.FileSystem
return 0;
}
public void CheckIfDescendentOfRootPath(string Path)
public void CheckIfDescendentOfRootPath(string path)
{
DirectoryInfo PathInfo = new DirectoryInfo(Path);
DirectoryInfo RootInfo = new DirectoryInfo(RootPath);
DirectoryInfo pathInfo = new DirectoryInfo(path);
DirectoryInfo rootInfo = new DirectoryInfo(_rootPath);
while (PathInfo.Parent != null)
while (pathInfo.Parent != null)
{
if (PathInfo.Parent.FullName == RootInfo.FullName)
if (pathInfo.Parent.FullName == rootInfo.FullName)
{
return;
}
else
{
PathInfo = PathInfo.Parent;
pathInfo = pathInfo.Parent;
}
}
throw new InvalidOperationException($"Path {Path} is not a child directory of {RootPath}");
throw new InvalidOperationException($"Path {path} is not a child directory of {_rootPath}");
}
}
}

View file

@ -1,41 +1,40 @@
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.FspSrv;
using System;
namespace Ryujinx.HLE.FileSystem
{
interface IFileSystemProvider
{
long CreateFile(string Name, long Size);
long CreateFile(string name, long size);
long CreateDirectory(string Name);
long CreateDirectory(string name);
long RenameFile(string OldName, string NewName);
long RenameFile(string oldName, string newName);
long RenameDirectory(string OldName, string NewName);
long RenameDirectory(string oldName, string newName);
DirectoryEntry[] GetEntries(string Path);
DirectoryEntry[] GetEntries(string path);
DirectoryEntry[] GetDirectories(string Path);
DirectoryEntry[] GetDirectories(string path);
DirectoryEntry[] GetFiles(string Path);
DirectoryEntry[] GetFiles(string path);
long DeleteFile(string Name);
long DeleteFile(string name);
long DeleteDirectory(string Name, bool Recursive);
long DeleteDirectory(string name, bool recursive);
bool FileExists(string Name);
bool FileExists(string name);
bool DirectoryExists(string Name);
bool DirectoryExists(string name);
long OpenFile(string Name, out IFile FileInterface);
long OpenFile(string name, out IFile fileInterface);
long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface);
long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface);
string GetFullPath(string Name);
string GetFullPath(string name);
long GetFreeSpace(ServiceCtx Context);
long GetFreeSpace(ServiceCtx context);
long GetTotalSpace(ServiceCtx Context);
long GetTotalSpace(ServiceCtx context);
}
}

View file

@ -12,98 +12,98 @@ namespace Ryujinx.HLE.FileSystem
{
class PFsProvider : IFileSystemProvider
{
private Pfs Pfs;
private Pfs _pfs;
public PFsProvider(Pfs Pfs)
public PFsProvider(Pfs pfs)
{
this.Pfs = Pfs;
_pfs = pfs;
}
public long CreateDirectory(string Name)
public long CreateDirectory(string name)
{
throw new NotSupportedException();
}
public long CreateFile(string Name, long Size)
public long CreateFile(string name, long size)
{
throw new NotSupportedException();
}
public long DeleteDirectory(string Name, bool Recursive)
public long DeleteDirectory(string name, bool recursive)
{
throw new NotSupportedException();
}
public long DeleteFile(string Name)
public long DeleteFile(string name)
{
throw new NotSupportedException();
}
public DirectoryEntry[] GetDirectories(string Path)
public DirectoryEntry[] GetDirectories(string path)
{
return new DirectoryEntry[0];
}
public DirectoryEntry[] GetEntries(string Path)
public DirectoryEntry[] GetEntries(string path)
{
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach (PfsFileEntry File in Pfs.Files)
foreach (PfsFileEntry file in _pfs.Files)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
return Entries.ToArray();
return entries.ToArray();
}
public DirectoryEntry[] GetFiles(string Path)
public DirectoryEntry[] GetFiles(string path)
{
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach (PfsFileEntry File in Pfs.Files)
foreach (PfsFileEntry file in _pfs.Files)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
return Entries.ToArray();
return entries.ToArray();
}
public long GetFreeSpace(ServiceCtx Context)
public long GetFreeSpace(ServiceCtx context)
{
return 0;
}
public string GetFullPath(string Name)
public string GetFullPath(string name)
{
return Name;
return name;
}
public long GetTotalSpace(ServiceCtx Context)
public long GetTotalSpace(ServiceCtx context)
{
return Pfs.Files.Sum(x => x.Size);
return _pfs.Files.Sum(x => x.Size);
}
public bool DirectoryExists(string Name)
public bool DirectoryExists(string name)
{
return Name == "/" ? true : false;
return name == "/";
}
public bool FileExists(string Name)
public bool FileExists(string name)
{
Name = Name.TrimStart('/');
name = name.TrimStart('/');
return Pfs.FileExists(Name);
return _pfs.FileExists(name);
}
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
{
if (Name == "/")
if (name == "/")
{
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
directoryInterface = new IDirectory(name, filterFlags, this);
return 0;
}
@ -111,34 +111,34 @@ namespace Ryujinx.HLE.FileSystem
throw new NotSupportedException();
}
public long OpenFile(string Name, out IFile FileInterface)
public long OpenFile(string name, out IFile fileInterface)
{
Name = Name.TrimStart('/');
name = name.TrimStart('/');
if (Pfs.FileExists(Name))
if (_pfs.FileExists(name))
{
Stream Stream = Pfs.OpenFile(Name);
FileInterface = new IFile(Stream, Name);
Stream stream = _pfs.OpenFile(name);
fileInterface = new IFile(stream, name);
return 0;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
throw new NotSupportedException();
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
throw new NotSupportedException();
}
public void CheckIfOutsideBasePath(string Path)
public void CheckIfOutsideBasePath(string path)
{
throw new NotSupportedException();
}

View file

@ -12,150 +12,150 @@ namespace Ryujinx.HLE.FileSystem
{
class RomFsProvider : IFileSystemProvider
{
private Romfs RomFs;
private Romfs _romFs;
public RomFsProvider(Stream StorageStream)
public RomFsProvider(Stream storageStream)
{
RomFs = new Romfs(StorageStream);
_romFs = new Romfs(storageStream);
}
public long CreateDirectory(string Name)
public long CreateDirectory(string name)
{
throw new NotSupportedException();
}
public long CreateFile(string Name, long Size)
public long CreateFile(string name, long size)
{
throw new NotSupportedException();
}
public long DeleteDirectory(string Name, bool Recursive)
public long DeleteDirectory(string name, bool recursive)
{
throw new NotSupportedException();
}
public long DeleteFile(string Name)
public long DeleteFile(string name)
{
throw new NotSupportedException();
}
public DirectoryEntry[] GetDirectories(string Path)
public DirectoryEntry[] GetDirectories(string path)
{
List<DirectoryEntry> Directories = new List<DirectoryEntry>();
List<DirectoryEntry> directories = new List<DirectoryEntry>();
foreach(RomfsDir Directory in RomFs.Directories)
foreach(RomfsDir directory in _romFs.Directories)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory);
Directories.Add(DirectoryEntry);
directories.Add(directoryEntry);
}
return Directories.ToArray();
return directories.ToArray();
}
public DirectoryEntry[] GetEntries(string Path)
public DirectoryEntry[] GetEntries(string path)
{
List<DirectoryEntry> Entries = new List<DirectoryEntry>();
List<DirectoryEntry> entries = new List<DirectoryEntry>();
foreach (RomfsDir Directory in RomFs.Directories)
foreach (RomfsDir directory in _romFs.Directories)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
foreach (RomfsFile File in RomFs.Files)
foreach (RomfsFile file in _romFs.Files)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
return Entries.ToArray();
return entries.ToArray();
}
public DirectoryEntry[] GetFiles(string Path)
public DirectoryEntry[] GetFiles(string path)
{
List<DirectoryEntry> Files = new List<DirectoryEntry>();
List<DirectoryEntry> files = new List<DirectoryEntry>();
foreach (RomfsFile File in RomFs.Files)
foreach (RomfsFile file in _romFs.Files)
{
DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength);
Files.Add(DirectoryEntry);
files.Add(directoryEntry);
}
return Files.ToArray();
return files.ToArray();
}
public long GetFreeSpace(ServiceCtx Context)
public long GetFreeSpace(ServiceCtx context)
{
return 0;
}
public string GetFullPath(string Name)
public string GetFullPath(string name)
{
return Name;
return name;
}
public long GetTotalSpace(ServiceCtx Context)
public long GetTotalSpace(ServiceCtx context)
{
return RomFs.Files.Sum(x => x.DataLength);
return _romFs.Files.Sum(x => x.DataLength);
}
public bool DirectoryExists(string Name)
public bool DirectoryExists(string name)
{
return RomFs.Directories.Exists(x=>x.Name == Name);
return _romFs.Directories.Exists(x=>x.Name == name);
}
public bool FileExists(string Name)
public bool FileExists(string name)
{
return RomFs.FileExists(Name);
return _romFs.FileExists(name);
}
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
{
RomfsDir Directory = RomFs.Directories.Find(x => x.Name == Name);
RomfsDir directory = _romFs.Directories.Find(x => x.Name == name);
if (Directory != null)
if (directory != null)
{
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
directoryInterface = new IDirectory(name, filterFlags, this);
return 0;
}
DirectoryInterface = null;
directoryInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long OpenFile(string Name, out IFile FileInterface)
public long OpenFile(string name, out IFile fileInterface)
{
if (RomFs.FileExists(Name))
if (_romFs.FileExists(name))
{
Stream Stream = RomFs.OpenFile(Name);
Stream stream = _romFs.OpenFile(name);
FileInterface = new IFile(Stream, Name);
fileInterface = new IFile(stream, name);
return 0;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
throw new NotSupportedException();
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
throw new NotSupportedException();
}
public void CheckIfOutsideBasePath(string Path)
public void CheckIfOutsideBasePath(string path)
{
throw new NotSupportedException();
}

View file

@ -7,39 +7,39 @@ namespace Ryujinx.HLE.FileSystem
{
static class SaveHelper
{
public static string GetSavePath(SaveInfo SaveMetaData, ServiceCtx Context)
public static string GetSavePath(SaveInfo saveMetaData, ServiceCtx context)
{
string BaseSavePath = NandPath;
long CurrentTitleId = SaveMetaData.TitleId;
string baseSavePath = NandPath;
long currentTitleId = saveMetaData.TitleId;
switch (SaveMetaData.SaveSpaceId)
switch (saveMetaData.SaveSpaceId)
{
case SaveSpaceId.NandUser:
BaseSavePath = UserNandPath;
baseSavePath = UserNandPath;
break;
case SaveSpaceId.NandSystem:
BaseSavePath = SystemNandPath;
baseSavePath = SystemNandPath;
break;
case SaveSpaceId.SdCard:
BaseSavePath = Path.Combine(SdCardPath, "Nintendo");
baseSavePath = Path.Combine(SdCardPath, "Nintendo");
break;
}
BaseSavePath = Path.Combine(BaseSavePath, "save");
baseSavePath = Path.Combine(baseSavePath, "save");
if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData)
if (saveMetaData.TitleId == 0 && saveMetaData.SaveDataType == SaveDataType.SaveData)
{
CurrentTitleId = Context.Process.TitleId;
currentTitleId = context.Process.TitleId;
}
string SaveAccount = SaveMetaData.UserId.IsZero() ? "savecommon" : SaveMetaData.UserId.ToString();
string saveAccount = saveMetaData.UserId.IsZero() ? "savecommon" : saveMetaData.UserId.ToString();
string SavePath = Path.Combine(BaseSavePath,
SaveMetaData.SaveId.ToString("x16"),
SaveAccount,
SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("x16") : string.Empty);
string savePath = Path.Combine(baseSavePath,
saveMetaData.SaveId.ToString("x16"),
saveAccount,
saveMetaData.SaveDataType == SaveDataType.SaveData ? currentTitleId.ToString("x16") : string.Empty);
return SavePath;
return savePath;
}
}
}

View file

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.FileSystem
{
struct SaveInfo
{
public long TitleId { get; private set; }
public long SaveId { get; private set; }
public long TitleId { get; private set; }
public long SaveId { get; private set; }
public UInt128 UserId { get; private set; }
public SaveDataType SaveDataType { get; private set; }
public SaveSpaceId SaveSpaceId { get; private set; }
public SaveInfo(
long TitleId,
long SaveId,
SaveDataType SaveDataType,
UInt128 UserId,
SaveSpaceId SaveSpaceId)
long titleId,
long saveId,
SaveDataType saveDataType,
UInt128 userId,
SaveSpaceId saveSpaceId)
{
this.TitleId = TitleId;
this.UserId = UserId;
this.SaveId = SaveId;
this.SaveDataType = SaveDataType;
this.SaveSpaceId = SaveSpaceId;
TitleId = titleId;
UserId = userId;
SaveId = saveId;
SaveDataType = saveDataType;
SaveSpaceId = saveSpaceId;
}
}
}

View file

@ -18,40 +18,40 @@ namespace Ryujinx.HLE.FileSystem
public Stream RomFs { get; private set; }
public void LoadRomFs(string FileName)
public void LoadRomFs(string fileName)
{
RomFs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
}
public void SetRomFs(Stream RomfsStream)
public void SetRomFs(Stream romfsStream)
{
RomFs?.Close();
RomFs = RomfsStream;
RomFs = romfsStream;
}
public string GetFullPath(string BasePath, string FileName)
public string GetFullPath(string basePath, string fileName)
{
if (FileName.StartsWith("//"))
if (fileName.StartsWith("//"))
{
FileName = FileName.Substring(2);
fileName = fileName.Substring(2);
}
else if (FileName.StartsWith('/'))
else if (fileName.StartsWith('/'))
{
FileName = FileName.Substring(1);
fileName = fileName.Substring(1);
}
else
{
return null;
}
string FullPath = Path.GetFullPath(Path.Combine(BasePath, FileName));
string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName));
if (!FullPath.StartsWith(GetBasePath()))
if (!fullPath.StartsWith(GetBasePath()))
{
return null;
}
return FullPath;
return fullPath;
}
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
@ -60,84 +60,84 @@ namespace Ryujinx.HLE.FileSystem
public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
public string GetGameSavePath(SaveInfo Save, ServiceCtx Context)
public string GetGameSavePath(SaveInfo save, ServiceCtx context)
{
return MakeDirAndGetFullPath(SaveHelper.GetSavePath(Save, Context));
return MakeDirAndGetFullPath(SaveHelper.GetSavePath(save, context));
}
public string GetFullPartitionPath(string PartitionPath)
public string GetFullPartitionPath(string partitionPath)
{
return MakeDirAndGetFullPath(PartitionPath);
return MakeDirAndGetFullPath(partitionPath);
}
public string SwitchPathToSystemPath(string SwitchPath)
public string SwitchPathToSystemPath(string switchPath)
{
string[] Parts = SwitchPath.Split(":");
string[] parts = switchPath.Split(":");
if (Parts.Length != 2)
if (parts.Length != 2)
{
return null;
}
return GetFullPath(MakeDirAndGetFullPath(Parts[0]), Parts[1]);
return GetFullPath(MakeDirAndGetFullPath(parts[0]), parts[1]);
}
public string SystemPathToSwitchPath(string SystemPath)
public string SystemPathToSwitchPath(string systemPath)
{
string BaseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
if (SystemPath.StartsWith(BaseSystemPath))
if (systemPath.StartsWith(baseSystemPath))
{
string RawPath = SystemPath.Replace(BaseSystemPath, "");
int FirstSeparatorOffset = RawPath.IndexOf(Path.DirectorySeparatorChar);
string rawPath = systemPath.Replace(baseSystemPath, "");
int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar);
if (FirstSeparatorOffset == -1)
if (firstSeparatorOffset == -1)
{
return $"{RawPath}:/";
return $"{rawPath}:/";
}
string BasePath = RawPath.Substring(0, FirstSeparatorOffset);
string FileName = RawPath.Substring(FirstSeparatorOffset + 1);
string basePath = rawPath.Substring(0, firstSeparatorOffset);
string fileName = rawPath.Substring(firstSeparatorOffset + 1);
return $"{BasePath}:/{FileName}";
return $"{basePath}:/{fileName}";
}
return null;
}
private string MakeDirAndGetFullPath(string Dir)
private string MakeDirAndGetFullPath(string dir)
{
// Handles Common Switch Content Paths
switch (Dir)
switch (dir)
{
case ContentPath.SdCard:
case "@Sdcard":
Dir = SdCardPath;
dir = SdCardPath;
break;
case ContentPath.User:
Dir = UserNandPath;
dir = UserNandPath;
break;
case ContentPath.System:
Dir = SystemNandPath;
dir = SystemNandPath;
break;
case ContentPath.SdCardContent:
Dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
break;
case ContentPath.UserContent:
Dir = Path.Combine(UserNandPath, "Contents");
dir = Path.Combine(UserNandPath, "Contents");
break;
case ContentPath.SystemContent:
Dir = Path.Combine(SystemNandPath, "Contents");
dir = Path.Combine(SystemNandPath, "Contents");
break;
}
string FullPath = Path.Combine(GetBasePath(), Dir);
string fullPath = Path.Combine(GetBasePath(), dir);
if (!Directory.Exists(FullPath))
if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(FullPath);
Directory.CreateDirectory(fullPath);
}
return FullPath;
return fullPath;
}
public DriveInfo GetDrive()
@ -147,9 +147,9 @@ namespace Ryujinx.HLE.FileSystem
public string GetBasePath()
{
string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(AppDataPath, BasePath);
return Path.Combine(appDataPath, BasePath);
}
public void Dispose()

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ArraySubscriptingExpression : BaseNode
{
private BaseNode LeftNode;
private BaseNode Subscript;
private BaseNode _leftNode;
private BaseNode _subscript;
public ArraySubscriptingExpression(BaseNode LeftNode, BaseNode Subscript) : base(NodeType.ArraySubscriptingExpression)
public ArraySubscriptingExpression(BaseNode leftNode, BaseNode subscript) : base(NodeType.ArraySubscriptingExpression)
{
this.LeftNode = LeftNode;
this.Subscript = Subscript;
_leftNode = leftNode;
_subscript = subscript;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
LeftNode.Print(Writer);
Writer.Write(")[");
Subscript.Print(Writer);
Writer.Write("]");
writer.Write("(");
_leftNode.Print(writer);
writer.Write(")[");
_subscript.Print(writer);
writer.Write("]");
}
}
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ArrayType : BaseNode
{
private BaseNode Base;
private BaseNode DimensionExpression;
private string DimensionString;
private BaseNode _base;
private BaseNode _dimensionExpression;
private string _dimensionString;
public ArrayType(BaseNode Base, BaseNode DimensionExpression = null) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionExpression = DimensionExpression;
_base = Base;
_dimensionExpression = dimensionExpression;
}
public ArrayType(BaseNode Base, string DimensionString) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, string dimensionString) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionString = DimensionString;
_base = Base;
_dimensionString = dimensionString;
}
public override bool HasRightPart()
@ -30,30 +30,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Base.PrintLeft(Writer);
_base.PrintLeft(writer);
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
// FIXME: detect if previous char was a ].
Writer.Write(" ");
writer.Write(" ");
Writer.Write("[");
writer.Write("[");
if (DimensionString != null)
if (_dimensionString != null)
{
Writer.Write(DimensionString);
writer.Write(_dimensionString);
}
else if (DimensionExpression != null)
else if (_dimensionExpression != null)
{
DimensionExpression.Print(Writer);
_dimensionExpression.Print(writer);
}
Writer.Write("]");
writer.Write("]");
Base.PrintRight(Writer);
_base.PrintRight(writer);
}
}
}

View file

@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public enum NodeType
{
CVQualifierType,
CvQualifierType,
SimpleReferenceType,
NameType,
EncodedFunction,
@ -62,22 +62,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public NodeType Type { get; protected set; }
public BaseNode(NodeType Type)
public BaseNode(NodeType type)
{
this.Type = Type;
Type = type;
}
public virtual void Print(TextWriter Writer)
public virtual void Print(TextWriter writer)
{
PrintLeft(Writer);
PrintLeft(writer);
if (HasRightPart())
{
PrintRight(Writer);
PrintRight(writer);
}
}
public abstract void PrintLeft(TextWriter Writer);
public abstract void PrintLeft(TextWriter writer);
public virtual bool HasRightPart()
{
@ -99,15 +99,15 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null;
}
public virtual void PrintRight(TextWriter Writer) {}
public virtual void PrintRight(TextWriter writer) {}
public override string ToString()
{
StringWriter Writer = new StringWriter();
StringWriter writer = new StringWriter();
Print(Writer);
Print(writer);
return Writer.ToString();
return writer.ToString();
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BinaryExpression : BaseNode
{
private BaseNode LeftPart;
private string Name;
private BaseNode RightPart;
private BaseNode _leftPart;
private string _name;
private BaseNode _rightPart;
public BinaryExpression(BaseNode LeftPart, string Name, BaseNode RightPart) : base(NodeType.BinaryExpression)
public BinaryExpression(BaseNode leftPart, string name, BaseNode rightPart) : base(NodeType.BinaryExpression)
{
this.LeftPart = LeftPart;
this.Name = Name;
this.RightPart = RightPart;
_leftPart = leftPart;
_name = name;
_rightPart = rightPart;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Name.Equals(">"))
if (_name.Equals(">"))
{
Writer.Write("(");
writer.Write("(");
}
Writer.Write("(");
LeftPart.Print(Writer);
Writer.Write(") ");
writer.Write("(");
_leftPart.Print(writer);
writer.Write(") ");
Writer.Write(Name);
writer.Write(_name);
Writer.Write(" (");
RightPart.Print(Writer);
Writer.Write(")");
writer.Write(" (");
_rightPart.Print(writer);
writer.Write(")");
if (Name.Equals(">"))
if (_name.Equals(">"))
{
Writer.Write(")");
writer.Write(")");
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BracedExpression : BaseNode
{
private BaseNode Element;
private BaseNode Expression;
private bool IsArrayExpression;
private BaseNode _element;
private BaseNode _expression;
private bool _isArrayExpression;
public BracedExpression(BaseNode Element, BaseNode Expression, bool IsArrayExpression) : base(NodeType.BracedExpression)
public BracedExpression(BaseNode element, BaseNode expression, bool isArrayExpression) : base(NodeType.BracedExpression)
{
this.Element = Element;
this.Expression = Expression;
this.IsArrayExpression = IsArrayExpression;
_element = element;
_expression = expression;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[");
Element.Print(Writer);
Writer.Write("]");
writer.Write("[");
_element.Print(writer);
writer.Write("]");
}
else
{
Writer.Write(".");
Element.Print(Writer);
writer.Write(".");
_element.Print(writer);
}
if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression))
{
Writer.Write(" = ");
writer.Write(" = ");
}
Expression.Print(Writer);
_expression.Print(writer);
}
}
}

View file

@ -4,31 +4,31 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BracedRangeExpression : BaseNode
{
private BaseNode FirstNode;
private BaseNode LastNode;
private BaseNode Expression;
private BaseNode _firstNode;
private BaseNode _lastNode;
private BaseNode _expression;
public BracedRangeExpression(BaseNode FirstNode, BaseNode LastNode, BaseNode Expression) : base(NodeType.BracedRangeExpression)
public BracedRangeExpression(BaseNode firstNode, BaseNode lastNode, BaseNode expression) : base(NodeType.BracedRangeExpression)
{
this.FirstNode = FirstNode;
this.LastNode = LastNode;
this.Expression = Expression;
_firstNode = firstNode;
_lastNode = lastNode;
_expression = expression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("[");
FirstNode.Print(Writer);
Writer.Write(" ... ");
LastNode.Print(Writer);
Writer.Write("]");
writer.Write("[");
_firstNode.Print(writer);
writer.Write(" ... ");
_lastNode.Print(writer);
writer.Write("]");
if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression))
{
Writer.Write(" = ");
writer.Write(" = ");
}
Expression.Print(Writer);
_expression.Print(writer);
}
}
}

View file

@ -5,20 +5,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CallExpression : NodeArray
{
private BaseNode Callee;
private BaseNode _callee;
public CallExpression(BaseNode Callee, List<BaseNode> Nodes) : base(Nodes, NodeType.CallExpression)
public CallExpression(BaseNode callee, List<BaseNode> nodes) : base(nodes, NodeType.CallExpression)
{
this.Callee = Callee;
_callee = callee;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Callee.Print(Writer);
_callee.Print(writer);
Writer.Write("(");
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write(")");
writer.Write("(");
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(")");
}
}
}

View file

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CastExpression : BaseNode
{
private string Kind;
private BaseNode To;
private BaseNode From;
private string _kind;
private BaseNode _to;
private BaseNode _from;
public CastExpression(string Kind, BaseNode To, BaseNode From) : base(NodeType.CastExpression)
public CastExpression(string kind, BaseNode to, BaseNode from) : base(NodeType.CastExpression)
{
this.Kind = Kind;
this.To = To;
this.From = From;
_kind = kind;
_to = to;
_from = from;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Kind);
Writer.Write("<");
To.PrintLeft(Writer);
Writer.Write(">(");
From.PrintLeft(Writer);
Writer.Write(")");
writer.Write(_kind);
writer.Write("<");
_to.PrintLeft(writer);
writer.Write(">(");
_from.PrintLeft(writer);
writer.Write(")");
}
}
}

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConditionalExpression : BaseNode
{
private BaseNode ThenNode;
private BaseNode ElseNode;
private BaseNode ConditionNode;
private BaseNode _thenNode;
private BaseNode _elseNode;
private BaseNode _conditionNode;
public ConditionalExpression(BaseNode ConditionNode, BaseNode ThenNode, BaseNode ElseNode) : base(NodeType.ConditionalExpression)
public ConditionalExpression(BaseNode conditionNode, BaseNode thenNode, BaseNode elseNode) : base(NodeType.ConditionalExpression)
{
this.ThenNode = ThenNode;
this.ConditionNode = ConditionNode;
this.ElseNode = ElseNode;
_thenNode = thenNode;
_conditionNode = conditionNode;
_elseNode = elseNode;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
ConditionNode.Print(Writer);
Writer.Write(") ? (");
ThenNode.Print(Writer);
Writer.Write(") : (");
ElseNode.Print(Writer);
Writer.Write(")");
writer.Write("(");
_conditionNode.Print(writer);
writer.Write(") ? (");
_thenNode.Print(writer);
writer.Write(") : (");
_elseNode.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConversionExpression : BaseNode
{
private BaseNode TypeNode;
private BaseNode Expressions;
private BaseNode _typeNode;
private BaseNode _expressions;
public ConversionExpression(BaseNode TypeNode, BaseNode Expressions) : base(NodeType.ConversionExpression)
public ConversionExpression(BaseNode typeNode, BaseNode expressions) : base(NodeType.ConversionExpression)
{
this.TypeNode = TypeNode;
this.Expressions = Expressions;
_typeNode = typeNode;
_expressions = expressions;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
TypeNode.Print(Writer);
Writer.Write(")(");
Expressions.Print(Writer);
writer.Write("(");
_typeNode.Print(writer);
writer.Write(")(");
_expressions.Print(writer);
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConversionOperatorType : ParentNode
{
public ConversionOperatorType(BaseNode Child) : base(NodeType.ConversionOperatorType, Child) { }
public ConversionOperatorType(BaseNode child) : base(NodeType.ConversionOperatorType, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("operator ");
Child.Print(Writer);
writer.Write("operator ");
Child.Print(writer);
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CtorDtorNameType : ParentNode
{
private bool IsDestructor;
private bool _isDestructor;
public CtorDtorNameType(BaseNode Name, bool IsDestructor) : base(NodeType.CtorDtorNameType, Name)
public CtorDtorNameType(BaseNode name, bool isDestructor) : base(NodeType.CtorDtorNameType, name)
{
this.IsDestructor = IsDestructor;
_isDestructor = isDestructor;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsDestructor)
if (_isDestructor)
{
Writer.Write("~");
writer.Write("~");
}
Writer.Write(Child.GetName());
writer.Write(Child.GetName());
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CtorVtableSpecialName : BaseNode
{
private BaseNode FirstType;
private BaseNode SecondType;
private BaseNode _firstType;
private BaseNode _secondType;
public CtorVtableSpecialName(BaseNode FirstType, BaseNode SecondType) : base(NodeType.CtorVtableSpecialName)
public CtorVtableSpecialName(BaseNode firstType, BaseNode secondType) : base(NodeType.CtorVtableSpecialName)
{
this.FirstType = FirstType;
this.SecondType = SecondType;
_firstType = firstType;
_secondType = secondType;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("construction vtable for ");
FirstType.Print(Writer);
Writer.Write("-in-");
SecondType.Print(Writer);
writer.Write("construction vtable for ");
_firstType.Print(writer);
writer.Write("-in-");
_secondType.Print(writer);
}
}
}

View file

@ -4,30 +4,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DeleteExpression : ParentNode
{
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
private bool _isArrayExpression;
public DeleteExpression(BaseNode Child, bool IsGlobal, bool IsArrayExpression) : base(NodeType.DeleteExpression, Child)
public DeleteExpression(BaseNode child, bool isGlobal, bool isArrayExpression) : base(NodeType.DeleteExpression, child)
{
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsGlobal)
if (_isGlobal)
{
Writer.Write("::");
writer.Write("::");
}
Writer.Write("delete");
writer.Write("delete");
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[] ");
writer.Write("[] ");
}
Child.Print(Writer);
Child.Print(writer);
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DtorName : ParentNode
{
public DtorName(BaseNode Name) : base(NodeType.DtOrName, Name) { }
public DtorName(BaseNode name) : base(NodeType.DtOrName, name) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("~");
Child.PrintLeft(Writer);
writer.Write("~");
Child.PrintLeft(writer);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DynamicExceptionSpec : ParentNode
{
public DynamicExceptionSpec(BaseNode Child) : base(NodeType.DynamicExceptionSpec, Child) { }
public DynamicExceptionSpec(BaseNode child) : base(NodeType.DynamicExceptionSpec, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("throw(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("throw(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,18 +4,18 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ElaboratedType : ParentNode
{
private string Elaborated;
private string _elaborated;
public ElaboratedType(string Elaborated, BaseNode Type) : base(NodeType.ElaboratedType, Type)
public ElaboratedType(string elaborated, BaseNode type) : base(NodeType.ElaboratedType, type)
{
this.Elaborated = Elaborated;
_elaborated = elaborated;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Elaborated);
Writer.Write(" ");
Child.Print(Writer);
writer.Write(_elaborated);
writer.Write(" ");
Child.Print(writer);
}
}
}

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class EnclosedExpression : BaseNode
{
private string Prefix;
private BaseNode Expression;
private string Postfix;
private string _prefix;
private BaseNode _expression;
private string _postfix;
public EnclosedExpression(string Prefix, BaseNode Expression, string Postfix) : base(NodeType.EnclosedExpression)
public EnclosedExpression(string prefix, BaseNode expression, string postfix) : base(NodeType.EnclosedExpression)
{
this.Prefix = Prefix;
this.Expression = Expression;
this.Postfix = Postfix;
_prefix = prefix;
_expression = expression;
_postfix = postfix;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Prefix);
Expression.Print(Writer);
Writer.Write(Postfix);
writer.Write(_prefix);
_expression.Print(writer);
writer.Write(_postfix);
}
}
}

View file

@ -4,36 +4,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class EncodedFunction : BaseNode
{
private BaseNode Name;
private BaseNode Params;
private BaseNode CV;
private BaseNode Ref;
private BaseNode Attrs;
private BaseNode Ret;
private BaseNode _name;
private BaseNode _params;
private BaseNode _cv;
private BaseNode _ref;
private BaseNode _attrs;
private BaseNode _ret;
public EncodedFunction(BaseNode Name, BaseNode Params, BaseNode CV, BaseNode Ref, BaseNode Attrs, BaseNode Ret) : base(NodeType.NameType)
public EncodedFunction(BaseNode name, BaseNode Params, BaseNode cv, BaseNode Ref, BaseNode attrs, BaseNode ret) : base(NodeType.NameType)
{
this.Name = Name;
this.Params = Params;
this.CV = CV;
this.Ref = Ref;
this.Attrs = Attrs;
this.Ret = Ret;
_name = name;
_params = Params;
_cv = cv;
_ref = Ref;
_attrs = attrs;
_ret = ret;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Ret != null)
if (_ret != null)
{
Ret.PrintLeft(Writer);
_ret.PrintLeft(writer);
if (!Ret.HasRightPart())
if (!_ret.HasRightPart())
{
Writer.Write(" ");
writer.Write(" ");
}
}
Name.Print(Writer);
_name.Print(writer);
}
@ -42,35 +42,35 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Writer.Write("(");
writer.Write("(");
if (Params != null)
if (_params != null)
{
Params.Print(Writer);
_params.Print(writer);
}
Writer.Write(")");
writer.Write(")");
if (Ret != null)
if (_ret != null)
{
Ret.PrintRight(Writer);
_ret.PrintRight(writer);
}
if (CV != null)
if (_cv != null)
{
CV.Print(Writer);
_cv.Print(writer);
}
if (Ref != null)
if (_ref != null)
{
Ref.Print(Writer);
_ref.Print(writer);
}
if (Attrs != null)
if (_attrs != null)
{
Attrs.Print(Writer);
_attrs.Print(writer);
}
}
}

View file

@ -4,45 +4,45 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FoldExpression : BaseNode
{
private bool IsLeftFold;
private string OperatorName;
private BaseNode Expression;
private BaseNode Initializer;
private bool _isLeftFold;
private string _operatorName;
private BaseNode _expression;
private BaseNode _initializer;
public FoldExpression(bool IsLeftFold, string OperatorName, BaseNode Expression, BaseNode Initializer) : base(NodeType.FunctionParameter)
public FoldExpression(bool isLeftFold, string operatorName, BaseNode expression, BaseNode initializer) : base(NodeType.FunctionParameter)
{
this.IsLeftFold = IsLeftFold;
this.OperatorName = OperatorName;
this.Expression = Expression;
this.Initializer = Initializer;
_isLeftFold = isLeftFold;
_operatorName = operatorName;
_expression = expression;
_initializer = initializer;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
writer.Write("(");
if (IsLeftFold && Initializer != null)
if (_isLeftFold && _initializer != null)
{
Initializer.Print(Writer);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(IsLeftFold ? "... " : " ");
Writer.Write(OperatorName);
Writer.Write(!IsLeftFold ? " ..." : " ");
Expression.Print(Writer);
writer.Write(_isLeftFold ? "... " : " ");
writer.Write(_operatorName);
writer.Write(!_isLeftFold ? " ..." : " ");
_expression.Print(writer);
if (!IsLeftFold && Initializer != null)
if (!_isLeftFold && _initializer != null)
{
Initializer.Print(Writer);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(")");
writer.Write(")");
}
}
}

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
// TODO: Compute inside the Demangler
public BaseNode Reference;
private int Index;
private int _index;
public ForwardTemplateReference(int Index) : base(NodeType.ForwardTemplateReference)
public ForwardTemplateReference(int index) : base(NodeType.ForwardTemplateReference)
{
this.Index = Index;
_index = index;
}
public override string GetName()
@ -18,14 +18,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Reference.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Reference.PrintLeft(Writer);
Reference.PrintLeft(writer);
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Reference.PrintRight(Writer);
Reference.PrintRight(writer);
}
public override bool HasRightPart()

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionParameter : BaseNode
{
private string Number;
private string _number;
public FunctionParameter(string Number) : base(NodeType.FunctionParameter)
public FunctionParameter(string number) : base(NodeType.FunctionParameter)
{
this.Number = Number;
_number = number;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("fp ");
writer.Write("fp ");
if (Number != null)
if (_number != null)
{
Writer.Write(Number);
writer.Write(_number);
}
}
}

View file

@ -4,47 +4,47 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionType : BaseNode
{
private BaseNode ReturnType;
private BaseNode Params;
private BaseNode CVQualifier;
private SimpleReferenceType ReferenceQualifier;
private BaseNode ExceptionSpec;
private BaseNode _returnType;
private BaseNode _params;
private BaseNode _cvQualifier;
private SimpleReferenceType _referenceQualifier;
private BaseNode _exceptionSpec;
public FunctionType(BaseNode ReturnType, BaseNode Params, BaseNode CVQualifier, SimpleReferenceType ReferenceQualifier, BaseNode ExceptionSpec) : base(NodeType.FunctionType)
public FunctionType(BaseNode returnType, BaseNode Params, BaseNode cvQualifier, SimpleReferenceType referenceQualifier, BaseNode exceptionSpec) : base(NodeType.FunctionType)
{
this.ReturnType = ReturnType;
this.Params = Params;
this.CVQualifier = CVQualifier;
this.ReferenceQualifier = ReferenceQualifier;
this.ExceptionSpec = ExceptionSpec;
_returnType = returnType;
_params = Params;
_cvQualifier = cvQualifier;
_referenceQualifier = referenceQualifier;
_exceptionSpec = exceptionSpec;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
ReturnType.PrintLeft(Writer);
Writer.Write(" ");
_returnType.PrintLeft(writer);
writer.Write(" ");
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Writer.Write("(");
Params.Print(Writer);
Writer.Write(")");
writer.Write("(");
_params.Print(writer);
writer.Write(")");
ReturnType.PrintRight(Writer);
_returnType.PrintRight(writer);
CVQualifier.Print(Writer);
_cvQualifier.Print(writer);
if (ReferenceQualifier.Qualifier != Reference.None)
if (_referenceQualifier.Qualifier != Reference.None)
{
Writer.Write(" ");
ReferenceQualifier.PrintQualifier(Writer);
writer.Write(" ");
_referenceQualifier.PrintQualifier(writer);
}
if (ExceptionSpec != null)
if (_exceptionSpec != null)
{
Writer.Write(" ");
ExceptionSpec.Print(Writer);
writer.Write(" ");
_exceptionSpec.Print(writer);
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class GlobalQualifiedName : ParentNode
{
public GlobalQualifiedName(BaseNode Child) : base(NodeType.GlobalQualifiedName, Child) { }
public GlobalQualifiedName(BaseNode child) : base(NodeType.GlobalQualifiedName, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("::");
Child.Print(Writer);
writer.Write("::");
Child.Print(writer);
}
}
}

View file

@ -5,25 +5,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class InitListExpression : BaseNode
{
private BaseNode TypeNode;
private List<BaseNode> Nodes;
private BaseNode _typeNode;
private List<BaseNode> _nodes;
public InitListExpression(BaseNode TypeNode, List<BaseNode> Nodes) : base(NodeType.InitListExpression)
public InitListExpression(BaseNode typeNode, List<BaseNode> nodes) : base(NodeType.InitListExpression)
{
this.TypeNode = TypeNode;
this.Nodes = Nodes;
_typeNode = typeNode;
_nodes = nodes;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (TypeNode != null)
if (_typeNode != null)
{
TypeNode.Print(Writer);
_typeNode.Print(writer);
}
Writer.Write("{");
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write("}");
writer.Write("{");
writer.Write(string.Join<BaseNode>(", ", _nodes.ToArray()));
writer.Write("}");
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class IntegerCastExpression : ParentNode
{
private string Number;
private string _number;
public IntegerCastExpression(BaseNode Type, string Number) : base(NodeType.IntegerCastExpression, Type)
public IntegerCastExpression(BaseNode type, string number) : base(NodeType.IntegerCastExpression, type)
{
this.Number = Number;
_number = number;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Number);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_number);
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class IntegerLiteral : BaseNode
{
private string LitteralName;
private string LitteralValue;
private string _literalName;
private string _literalValue;
public IntegerLiteral(string LitteralName, string LitteralValue) : base(NodeType.IntegerLiteral)
public IntegerLiteral(string literalName, string literalValue) : base(NodeType.IntegerLiteral)
{
this.LitteralValue = LitteralValue;
this.LitteralName = LitteralName;
_literalValue = literalValue;
_literalName = literalName;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (LitteralName.Length > 3)
if (_literalName.Length > 3)
{
Writer.Write("(");
Writer.Write(LitteralName);
Writer.Write(")");
writer.Write("(");
writer.Write(_literalName);
writer.Write(")");
}
if (LitteralValue[0] == 'n')
if (_literalValue[0] == 'n')
{
Writer.Write("-");
Writer.Write(LitteralValue.Substring(1));
writer.Write("-");
writer.Write(_literalValue.Substring(1));
}
else
{
Writer.Write(LitteralValue);
writer.Write(_literalValue);
}
if (LitteralName.Length <= 3)
if (_literalName.Length <= 3)
{
Writer.Write(LitteralName);
writer.Write(_literalName);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class LiteralOperator : ParentNode
{
public LiteralOperator(BaseNode Child) : base(NodeType.LiteralOperator, Child) { }
public LiteralOperator(BaseNode child) : base(NodeType.LiteralOperator, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("operator \"");
Child.PrintLeft(Writer);
Writer.Write("\"");
writer.Write("operator \"");
Child.PrintLeft(writer);
writer.Write("\"");
}
}
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class LocalName : BaseNode
{
private BaseNode Encoding;
private BaseNode Entity;
private BaseNode _encoding;
private BaseNode _entity;
public LocalName(BaseNode Encoding, BaseNode Entity) : base(NodeType.LocalName)
public LocalName(BaseNode encoding, BaseNode entity) : base(NodeType.LocalName)
{
this.Encoding = Encoding;
this.Entity = Entity;
_encoding = encoding;
_entity = entity;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Encoding.Print(Writer);
Writer.Write("::");
Entity.Print(Writer);
_encoding.Print(writer);
writer.Write("::");
_entity.Print(writer);
}
}
}

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class MemberExpression : BaseNode
{
private BaseNode LeftNode;
private string Kind;
private BaseNode RightNode;
private BaseNode _leftNode;
private string _kind;
private BaseNode _rightNode;
public MemberExpression(BaseNode LeftNode, string Kind, BaseNode RightNode) : base(NodeType.MemberExpression)
public MemberExpression(BaseNode leftNode, string kind, BaseNode rightNode) : base(NodeType.MemberExpression)
{
this.LeftNode = LeftNode;
this.Kind = Kind;
this.RightNode = RightNode;
_leftNode = leftNode;
_kind = kind;
_rightNode = rightNode;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
LeftNode.Print(Writer);
Writer.Write(Kind);
RightNode.Print(Writer);
_leftNode.Print(writer);
writer.Write(_kind);
_rightNode.Print(writer);
}
}
}

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NameType : BaseNode
{
private string NameValue;
private string _nameValue;
public NameType(string NameValue, NodeType Type) : base(Type)
public NameType(string nameValue, NodeType type) : base(type)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
public NameType(string NameValue) : base(NodeType.NameType)
public NameType(string nameValue) : base(NodeType.NameType)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
public override string GetName()
{
return NameValue;
return _nameValue;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(NameValue);
writer.Write(_nameValue);
}
}
}

View file

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NameTypeWithTemplateArguments : BaseNode
{
private BaseNode Prev;
private BaseNode TemplateArgument;
private BaseNode _prev;
private BaseNode _templateArgument;
public NameTypeWithTemplateArguments(BaseNode Prev, BaseNode TemplateArgument) : base(NodeType.NameTypeWithTemplateArguments)
public NameTypeWithTemplateArguments(BaseNode prev, BaseNode templateArgument) : base(NodeType.NameTypeWithTemplateArguments)
{
this.Prev = Prev;
this.TemplateArgument = TemplateArgument;
_prev = prev;
_templateArgument = templateArgument;
}
public override string GetName()
{
return Prev.GetName();
return _prev.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Prev.Print(Writer);
TemplateArgument.Print(Writer);
_prev.Print(writer);
_templateArgument.Print(writer);
}
}
}

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NestedName : ParentNode
{
private BaseNode Name;
private BaseNode _name;
public NestedName(BaseNode Name, BaseNode Type) : base(NodeType.NestedName, Type)
public NestedName(BaseNode name, BaseNode type) : base(NodeType.NestedName, type)
{
this.Name = Name;
_name = name;
}
public override string GetName()
{
return Name.GetName();
return _name.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.Print(Writer);
Writer.Write("::");
Name.Print(Writer);
Child.Print(writer);
writer.Write("::");
_name.Print(writer);
}
}
}

View file

@ -4,51 +4,51 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NewExpression : BaseNode
{
private NodeArray Expressions;
private BaseNode TypeNode;
private NodeArray Initializers;
private NodeArray _expressions;
private BaseNode _typeNode;
private NodeArray _initializers;
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
private bool _isArrayExpression;
public NewExpression(NodeArray Expressions, BaseNode TypeNode, NodeArray Initializers, bool IsGlobal, bool IsArrayExpression) : base(NodeType.NewExpression)
public NewExpression(NodeArray expressions, BaseNode typeNode, NodeArray initializers, bool isGlobal, bool isArrayExpression) : base(NodeType.NewExpression)
{
this.Expressions = Expressions;
this.TypeNode = TypeNode;
this.Initializers = Initializers;
_expressions = expressions;
_typeNode = typeNode;
_initializers = initializers;
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsGlobal)
if (_isGlobal)
{
Writer.Write("::operator ");
writer.Write("::operator ");
}
Writer.Write("new ");
writer.Write("new ");
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[] ");
writer.Write("[] ");
}
if (Expressions.Nodes.Count != 0)
if (_expressions.Nodes.Count != 0)
{
Writer.Write("(");
Expressions.Print(Writer);
Writer.Write(")");
writer.Write("(");
_expressions.Print(writer);
writer.Write(")");
}
TypeNode.Print(Writer);
_typeNode.Print(writer);
if (Initializers.Nodes.Count != 0)
if (_initializers.Nodes.Count != 0)
{
Writer.Write("(");
Initializers.Print(Writer);
Writer.Write(")");
writer.Write("(");
_initializers.Print(writer);
writer.Write(")");
}
}
}

View file

@ -7,14 +7,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public List<BaseNode> Nodes { get; protected set; }
public NodeArray(List<BaseNode> Nodes) : base(NodeType.NodeArray)
public NodeArray(List<BaseNode> nodes) : base(NodeType.NodeArray)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public NodeArray(List<BaseNode> Nodes, NodeType Type) : base(Type)
public NodeArray(List<BaseNode> nodes, NodeType type) : base(type)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public override bool IsArray()
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NoexceptSpec : ParentNode
{
public NoexceptSpec(BaseNode Child) : base(NodeType.NoexceptSpec, Child) { }
public NoexceptSpec(BaseNode child) : base(NodeType.NoexceptSpec, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("noexcept(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("noexcept(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PackedTemplateParameter : NodeArray
{
public PackedTemplateParameter(List<BaseNode> Nodes) : base(Nodes, NodeType.PackedTemplateParameter) { }
public PackedTemplateParameter(List<BaseNode> nodes) : base(nodes, NodeType.PackedTemplateParameter) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
Node.PrintLeft(Writer);
node.PrintLeft(writer);
}
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
Node.PrintLeft(Writer);
node.PrintLeft(writer);
}
}
public override bool HasRightPart()
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
if (Node.HasRightPart())
if (node.HasRightPart())
{
return true;
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PackedTemplateParameterExpansion : ParentNode
{
public PackedTemplateParameterExpansion(BaseNode Child) : base(NodeType.PackedTemplateParameterExpansion, Child) {}
public PackedTemplateParameterExpansion(BaseNode child) : base(NodeType.PackedTemplateParameterExpansion, child) {}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Child is PackedTemplateParameter)
{
if (((PackedTemplateParameter)Child).Nodes.Count != 0)
{
Child.Print(Writer);
Child.Print(writer);
}
}
else
{
Writer.Write("...");
writer.Write("...");
}
}
}

View file

@ -4,9 +4,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public BaseNode Child { get; private set; }
public ParentNode(NodeType Type, BaseNode Child) : base(Type)
public ParentNode(NodeType type, BaseNode child) : base(type)
{
this.Child = Child;
Child = child;
}
public override string GetName()

View file

@ -4,42 +4,42 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PointerType : BaseNode
{
private BaseNode Child;
private BaseNode _child;
public PointerType(BaseNode Child) : base(NodeType.PointerType)
public PointerType(BaseNode child) : base(NodeType.PointerType)
{
this.Child = Child;
_child = child;
}
public override bool HasRightPart()
{
return Child.HasRightPart();
return _child.HasRightPart();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.PrintLeft(Writer);
if (Child.IsArray())
_child.PrintLeft(writer);
if (_child.IsArray())
{
Writer.Write(" ");
writer.Write(" ");
}
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write("(");
writer.Write("(");
}
Writer.Write("*");
writer.Write("*");
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write(")");
writer.Write(")");
}
Child.PrintRight(Writer);
_child.PrintRight(writer);
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PostfixExpression : ParentNode
{
private string Operator;
private string _operator;
public PostfixExpression(BaseNode Type, string Operator) : base(NodeType.PostfixExpression, Type)
public PostfixExpression(BaseNode type, string Operator) : base(NodeType.PostfixExpression, type)
{
this.Operator = Operator;
_operator = Operator;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Operator);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_operator);
}
}
}

Some files were not shown because too many files have changed in this diff Show more