Introduce IdentifierManager to improve PDT evaluator performance.
This commit is contained in:
@@ -47,7 +47,7 @@ namespace Cryville.Common.Pdt {
|
||||
var i = _rip.Value;
|
||||
if (i is PdtInstruction.Operate) {
|
||||
int fc0 = _framecount;
|
||||
int fc1 = ((PdtInstruction.Operate)i).ParamCount;
|
||||
int fc1 = ((PdtInstruction.Operate)i).Signature.ParamCount;
|
||||
try { i.Execute(this); } catch (Exception) { }
|
||||
if (fc0 - _framecount == fc1) {
|
||||
unsafe {
|
||||
@@ -137,7 +137,7 @@ namespace Cryville.Common.Pdt {
|
||||
_goffset += value.Length;
|
||||
}
|
||||
}
|
||||
internal unsafe void PushVariable(ref string name) {
|
||||
internal unsafe void PushVariable(int name) {
|
||||
fixed (StackFrame* frame = &_stack[_framecount++]) {
|
||||
byte[] value;
|
||||
GetVariable(name, out frame->Type, out value);
|
||||
@@ -153,12 +153,12 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="name">The name of the variable.</param>
|
||||
/// <param name="type">The type of the variable.</param>
|
||||
/// <param name="value">The value of the variable.</param>
|
||||
protected abstract void GetVariable(string name, out int type, out byte[] value);
|
||||
internal void Operate(ref string name, int pc) {
|
||||
protected abstract void GetVariable(int name, out int type, out byte[] value);
|
||||
internal void Operate(PdtOperatorSignature sig) {
|
||||
PdtOperator op;
|
||||
try { op = GetOperator(name, pc); }
|
||||
catch (Exception) { _framecount -= pc; return; }
|
||||
Operate(op, pc);
|
||||
try { op = GetOperator(sig); }
|
||||
catch (Exception) { _framecount -= sig.ParamCount; return; }
|
||||
Operate(op, sig.ParamCount);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets an operator of the specified name and the suggested parameter count.
|
||||
@@ -167,7 +167,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="pc">Suggested parameter count.</param>
|
||||
/// <returns>An operator of the specific name.</returns>
|
||||
/// <remarks>The parameter count of the returned operator does not necessarily equal to <paramref name="pc" />.</remarks>
|
||||
protected abstract PdtOperator GetOperator(string name, int pc);
|
||||
protected abstract PdtOperator GetOperator(PdtOperatorSignature sig);
|
||||
unsafe void Operate(PdtOperator op, int pc, bool noset = false) {
|
||||
fixed (byte* pmem = _mem) {
|
||||
op.Begin(this);
|
||||
@@ -179,7 +179,7 @@ namespace Cryville.Common.Pdt {
|
||||
op.Call(pmem + _goffset, noset);
|
||||
}
|
||||
}
|
||||
internal unsafe void Collapse(ref string name, LinkedListNode<PdtInstruction> target) {
|
||||
internal unsafe void Collapse(int name, LinkedListNode<PdtInstruction> target) {
|
||||
fixed (byte* pmem = _mem) {
|
||||
var frame = _stack[--_framecount];
|
||||
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
||||
@@ -194,7 +194,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="name">The name of the collapse operator.</param>
|
||||
/// <param name="param">The top frame in the stack as the parameter.</param>
|
||||
/// <returns>Whether to jump to the target of the collapse instruction.</returns>
|
||||
protected abstract bool Collapse(string name, PdtVariableMemory param);
|
||||
protected abstract bool Collapse(int name, PdtVariableMemory param);
|
||||
internal unsafe PdtVariableMemory StackAlloc(int type, byte* ptr, int len) {
|
||||
fixed (StackFrame* frame = &_stack[_framecount++]) {
|
||||
frame->Type = type;
|
||||
|
@@ -50,43 +50,38 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
}
|
||||
public class PushVariable : PdtInstruction {
|
||||
private string m_name;
|
||||
public string Name { get { return m_name; } }
|
||||
public int Name { get; private set; }
|
||||
public PushVariable(string name) {
|
||||
m_name = name;
|
||||
Name = IdentifierManager.SharedInstance.Request(name);
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
etor.PushVariable(ref m_name);
|
||||
etor.PushVariable(Name);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("pushv {0}", Name);
|
||||
}
|
||||
}
|
||||
public class Operate : PdtInstruction {
|
||||
private string m_name;
|
||||
public string Name { get { return m_name; } }
|
||||
public int ParamCount { get; private set; }
|
||||
public PdtOperatorSignature Signature { get; private set; }
|
||||
public Operate(string name, int paramCount) {
|
||||
m_name = name;
|
||||
ParamCount = paramCount;
|
||||
Signature = new PdtOperatorSignature(name, paramCount);
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
etor.Operate(ref m_name, ParamCount);
|
||||
etor.Operate(Signature);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("op {0}({1})", Name, ParamCount);
|
||||
return string.Format("op {0}", Signature);
|
||||
}
|
||||
}
|
||||
public class Collapse : PdtInstruction {
|
||||
private string m_name;
|
||||
public string Name { get { return m_name; } }
|
||||
public int Name { get; private set; }
|
||||
public LinkedListNode<PdtInstruction> Target { get; internal set; }
|
||||
public Collapse(string name, LinkedListNode<PdtInstruction> target) {
|
||||
m_name = name;
|
||||
Name = IdentifierManager.SharedInstance.Request(name);
|
||||
Target = target;
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
etor.Collapse(ref m_name, Target);
|
||||
etor.Collapse(Name, Target);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("col {0}{{{1}}}", Name, Target.Value);
|
||||
|
@@ -74,4 +74,48 @@ namespace Cryville.Common.Pdt {
|
||||
return _etor.StackAlloc(type, _prmem, len);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The signature of a <see cref="PdtOperator" />.
|
||||
/// </summary>
|
||||
public struct PdtOperatorSignature : IEquatable<PdtOperatorSignature> {
|
||||
/// <summary>
|
||||
/// The name of the operator.
|
||||
/// </summary>
|
||||
public int Name { get; private set; }
|
||||
/// <summary>
|
||||
/// The parameter count.
|
||||
/// </summary>
|
||||
public int ParamCount { get; private set; }
|
||||
readonly int _hash;
|
||||
/// <summary>
|
||||
/// Creates an operator signature.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the operator.</param>
|
||||
/// <param name="paramCount">The parameter count.</param>
|
||||
public PdtOperatorSignature(string name, int paramCount)
|
||||
: this(IdentifierManager.SharedInstance.Request(name), paramCount) { }
|
||||
/// <summary>
|
||||
/// Creates an operator signature.
|
||||
/// </summary>
|
||||
/// <param name="name">The identifier of the operator.</param>
|
||||
/// <param name="paramCount">The parameter count.</param>
|
||||
public PdtOperatorSignature(int name, int paramCount) {
|
||||
Name = name;
|
||||
ParamCount = paramCount;
|
||||
_hash = Name ^ ((ParamCount << 16) | (ParamCount >> 16));
|
||||
}
|
||||
public override bool Equals(object obj) {
|
||||
if (!(obj is PdtOperatorSignature)) return false;
|
||||
return Equals((PdtOperatorSignature)obj);
|
||||
}
|
||||
public bool Equals(PdtOperatorSignature other) {
|
||||
return Name == other.Name && ParamCount == other.ParamCount;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return _hash;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0}({1})", Name, ParamCount);
|
||||
}
|
||||
}
|
||||
}
|
@@ -101,11 +101,10 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="offset">The offset on the span to start reading from.</param>
|
||||
/// <returns>The name of an undefined identifier.</returns>
|
||||
/// <exception cref="InvalidCastException">The span does not represent an undefined identifier.</exception>
|
||||
public string AsIdentifier(int offset = 0) {
|
||||
public int AsIdentifier(int offset = 0) {
|
||||
if (Type != PdtInternalType.Undefined && Type != PdtInternalType.Array)
|
||||
throw new InvalidCastException("Not an identifier");
|
||||
var len = *(int*)(_ptr + offset);
|
||||
return new string((char*)(_ptr + offset + sizeof(int)), 0, len);
|
||||
return *(int*)(_ptr + offset);
|
||||
}
|
||||
internal void* TrustedAsOfLength(int len) {
|
||||
if (Length < len)
|
||||
|
Reference in New Issue
Block a user