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

Stack Isolation #39

Merged
merged 11 commits into from
Jun 24, 2018
26 changes: 9 additions & 17 deletions src/neo-vm/ExecutionContext.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace Neo.VM
{
public class ExecutionContext : IDisposable
{
private ExecutionEngine engine;
public readonly byte[] Script;
public readonly bool PushOnly;
internal readonly int RVCount;
internal readonly BinaryReader OpReader;
internal readonly HashSet<uint> BreakPoints;
private readonly ICrypto crypto;

public RandomAccessStack<StackItem> EvaluationStack { get; } = new RandomAccessStack<StackItem>();
public RandomAccessStack<StackItem> AltStack { get; } = new RandomAccessStack<StackItem>();

public int InstructionPointer
{
Expand All @@ -32,26 +33,17 @@ public byte[] ScriptHash
get
{
if (_script_hash == null)
_script_hash = engine.Crypto.Hash160(Script);
_script_hash = crypto.Hash160(Script);
return _script_hash;
}
}

internal ExecutionContext(ExecutionEngine engine, byte[] script, bool push_only, HashSet<uint> break_points = null)
internal ExecutionContext(ExecutionEngine engine, byte[] script, int rvcount)
{
this.engine = engine;
this.Script = script;
this.PushOnly = push_only;
this.RVCount = rvcount;
this.OpReader = new BinaryReader(new MemoryStream(script, false));
this.BreakPoints = break_points ?? new HashSet<uint>();
}

public ExecutionContext Clone()
{
return new ExecutionContext(engine, Script, PushOnly, BreakPoints)
{
InstructionPointer = InstructionPointer
};
this.crypto = engine.Crypto;
}

public void Dispose()
Expand Down
549 changes: 311 additions & 238 deletions src/neo-vm/ExecutionEngine.cs

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/neo-vm/HashComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Neo.VM
{
internal class HashComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
return x.SequenceEqual(y);
}

public int GetHashCode(byte[] obj)
{
return BitConverter.ToInt32(obj, 0);
}
}
}
8 changes: 4 additions & 4 deletions src/neo-vm/InteropService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,25 @@ internal bool Invoke(string method, ExecutionEngine engine)

private static bool GetScriptContainer(ExecutionEngine engine)
{
engine.EvaluationStack.Push(StackItem.FromInterface(engine.ScriptContainer));
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(engine.ScriptContainer));
return true;
}

private static bool GetExecutingScriptHash(ExecutionEngine engine)
{
engine.EvaluationStack.Push(engine.CurrentContext.ScriptHash);
engine.CurrentContext.EvaluationStack.Push(engine.CurrentContext.ScriptHash);
return true;
}

private static bool GetCallingScriptHash(ExecutionEngine engine)
{
engine.EvaluationStack.Push(engine.CallingContext.ScriptHash);
engine.CurrentContext.EvaluationStack.Push(engine.CallingContext.ScriptHash);
return true;
}

private static bool GetEntryScriptHash(ExecutionEngine engine)
{
engine.EvaluationStack.Push(engine.EntryContext.ScriptHash);
engine.CurrentContext.EvaluationStack.Push(engine.EntryContext.ScriptHash);
return true;
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/neo-vm/OpCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ public enum OpCode : byte
KEYS = 0xCC,
VALUES = 0xCD,


// Stack isolation
CALL_I = 0xE0,
CALL_E = 0xE1,
CALL_ED = 0xE2,
CALL_ET = 0xE3,
CALL_EDT = 0xE4,


// Exceptions
THROW = 0xF0,
THROWIFNOT = 0xF1
Expand Down
27 changes: 23 additions & 4 deletions src/neo-vm/RandomAccessStack.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Neo.VM
{
Expand All @@ -15,6 +16,15 @@ public void Clear()
list.Clear();
}

public void CopyTo(RandomAccessStack<T> stack, int count = -1)
{
if (count == 0) return;
if (count == -1)
stack.list.AddRange(list);
else
stack.list.AddRange(list.Skip(list.Count - count));
}

public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
Expand All @@ -34,7 +44,10 @@ public void Insert(int index, T item)
public T Peek(int index = 0)
{
if (index >= list.Count) throw new InvalidOperationException();
return list[list.Count - 1 - index];
if (index < 0) index += list.Count;
if (index < 0) throw new InvalidOperationException();
index = list.Count - index - 1;
return list[index];
}

public T Pop()
Expand All @@ -50,15 +63,21 @@ public void Push(T item)
public T Remove(int index)
{
if (index >= list.Count) throw new InvalidOperationException();
T item = list[list.Count - index - 1];
list.RemoveAt(list.Count - index - 1);
if (index < 0) index += list.Count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (index < 0) index = list.Count; ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+=

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to pass -2 or -3?

if (index < 0) throw new InvalidOperationException();
index = list.Count - index - 1;
T item = list[index];
list.RemoveAt(index);
return item;
}

public void Set(int index, T item)
{
if (index >= list.Count) throw new InvalidOperationException();
list[list.Count - index - 1] = item;
if (index < 0) index += list.Count;
if (index < 0) throw new InvalidOperationException();
index = list.Count - index - 1;
list[index] = item;
}
}
}
2 changes: 1 addition & 1 deletion src/neo-vm/neo-vm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Copyright>2016-2017 The Neo Project</Copyright>
<AssemblyTitle>Neo.VM</AssemblyTitle>
<Description>Neo.VM</Description>
<Version>2.2.1</Version>
<Version>2.3.0</Version>
<Authors>The Neo Project</Authors>
<TargetFrameworks>netstandard1.6;net461</TargetFrameworks>
<AssemblyName>Neo.VM</AssemblyName>
Expand Down