Fix memory leak during collapsing in PDT.
This commit is contained in:
@@ -24,8 +24,8 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// <param name="exp">The expression to evaluate.</param>
|
/// <param name="exp">The expression to evaluate.</param>
|
||||||
/// <returns>Whether the evaluaton succeeded.</returns>
|
/// <returns>Whether the evaluaton succeeded.</returns>
|
||||||
public bool Evaluate(PdtOperator target, PdtExpression exp) {
|
public bool Evaluate(PdtOperator target, PdtExpression exp) {
|
||||||
try {
|
|
||||||
var prevFrameCount = _framecount;
|
var prevFrameCount = _framecount;
|
||||||
|
try {
|
||||||
_revokepttconst = false;
|
_revokepttconst = false;
|
||||||
for (var ip = exp.Instructions.First; ip != null; ip = ip.Next)
|
for (var ip = exp.Instructions.First; ip != null; ip = ip.Next)
|
||||||
ip.Value.Execute(this, ref ip);
|
ip.Value.Execute(this, ref ip);
|
||||||
@@ -33,12 +33,14 @@ namespace Cryville.Common.Pdt {
|
|||||||
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
||||||
}
|
}
|
||||||
var ret = Operate(target, _framecount - prevFrameCount, true);
|
var ret = Operate(target, _framecount - prevFrameCount, true);
|
||||||
for (var i = prevFrameCount; i < _framecount; i++) DiscardStack();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new EvaluationFailureException(exp, ex);
|
throw new EvaluationFailureException(exp, ex);
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
for (var i = prevFrameCount; i < _framecount; i++) DiscardStack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Optimizes an expression by merging its instructions.
|
/// Optimizes an expression by merging its instructions.
|
||||||
@@ -205,7 +207,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
var frame = _stack[--_framecount];
|
var frame = _stack[--_framecount];
|
||||||
if (frame.Type == PdtInternalType.Error) {
|
if (frame.Type == PdtInternalType.Error) {
|
||||||
_framecount -= pc - i - 1;
|
_framecount -= pc - i - 1;
|
||||||
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 };
|
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = -1, Length = 0 };
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length));
|
op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length));
|
||||||
@@ -218,13 +220,15 @@ namespace Cryville.Common.Pdt {
|
|||||||
internal unsafe void Collapse(int name, ref LinkedListNode<PdtInstruction> self, LinkedListNode<PdtInstruction> target) {
|
internal unsafe void Collapse(int name, ref LinkedListNode<PdtInstruction> self, LinkedListNode<PdtInstruction> target) {
|
||||||
fixed (byte* pmem = _mem) {
|
fixed (byte* pmem = _mem) {
|
||||||
var frame = _stack[--_framecount];
|
var frame = _stack[--_framecount];
|
||||||
|
_goffset -= frame.Length;
|
||||||
if (frame.Type == PdtInternalType.Error) {
|
if (frame.Type == PdtInternalType.Error) {
|
||||||
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 };
|
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = -1, Length = 0 };
|
||||||
self = target;
|
self = target;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
||||||
_framecount++;
|
_framecount++;
|
||||||
|
_goffset += frame.Length;
|
||||||
self = target;
|
self = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user