Skip to content
This repository has been archived by the owner on Nov 22, 2023. It is now read-only.

TryPop shouldn't change the state of the stack when returns false #304

Merged
merged 1 commit into from
Mar 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/neo-vm/EvaluationStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ internal bool Reverse(int n)
return true;
}

public bool TryPeek<T>(out T item) where T : StackItem
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
if (innerList.Count == 0)
{
item = default;
return false;
}
item = innerList[^1] as T;
return item != null;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryPop<T>(out T item) where T : StackItem
{
Expand Down
35 changes: 30 additions & 5 deletions src/neo-vm/ExecutionEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1274,17 +1274,19 @@ public bool TryPop(out bool b)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryPop(out ReadOnlySpan<byte> b)
{
if (!TryPop(out StackItem item))
if (!CurrentContext.EvaluationStack.TryPeek(out StackItem item))
{
b = default;
return false;
}
switch (item)
{
case PrimitiveType primitive:
CurrentContext.EvaluationStack.Pop();
b = primitive.Span;
return true;
case Buffer buffer:
CurrentContext.EvaluationStack.Pop();
b = buffer.InnerBuffer;
return true;
default:
Expand All @@ -1311,16 +1313,39 @@ public bool TryPop(out BigInteger i)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryPop(out int i)
{
if (!TryPop(out BigInteger item) || item < int.MinValue || item > int.MaxValue)
if (!CurrentContext.EvaluationStack.TryPeek(out PrimitiveType item))
{
i = default;
return false;
}
else
BigInteger bi = item.ToBigInteger();
if (bi < int.MinValue || bi > int.MaxValue)
{
i = (int)item;
return true;
i = default;
return false;
}
CurrentContext.EvaluationStack.Pop();
i = (int)bi;
return true;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryPop(out uint i)
{
if (!CurrentContext.EvaluationStack.TryPeek(out PrimitiveType item))
{
i = default;
return false;
}
BigInteger bi = item.ToBigInteger();
if (bi < uint.MinValue || bi > uint.MaxValue)
{
i = default;
return false;
}
CurrentContext.EvaluationStack.Pop();
i = (uint)bi;
return true;
}
}
}