Beispiel #1
0
        internal static void Print(int index)
        {
            if (methods.Count == 0 || methods.Count <= index || index < 0)
            {
                return;
            }

#if NET_2_0
            Stack <Data> temp = new Stack <Data>(index - 1);
#else
            DataStack temp = new DataStack(index - 1);
#endif
            for (int i = 0; i < index; i++)
            {
                temp.Push(methods.Pop());
            }

            Data data = methods.Peek();
            for (int i = 0; i < temp.Count; i++)
            {
                methods.Push(temp.Pop());
            }
            temp = null;

            Debug.WriteLine(data.method.DeclaringType.Name + "." + data.method.Name);
        }
Beispiel #2
0
        public void Perform(object next)
        {
            ++NumOps;
            if (next == null)
            {
                throw new NullValueException();
            }

            PerformPrelude(next);
            switch (next)
            {
            case EOperation op when _actions.TryGetValue(op, out var action):
                action();

                break;

            case EOperation op:
                throw new NotImplementedException($"Operation {op} not implemented");

            default:
                if (!TryResolve(next, out var eval))
                {
                    throw new UnknownIdentifierException(next);
                }

                DataStack.Push(eval);
                break;
            }
        }
Beispiel #3
0
        internal static void Print(string methodName, string parameterName)
        {
            if (methods.Count == 0)
            {
                return;
            }

#if NET_2_0
            Stack <Data> temp = new Stack <Data>();
#else
            DataStack temp = new DataStack();
#endif
            Data data    = methods.Peek();
            bool foundit = false;
            for (int i = 0; i < methods.Count; i++)
            {
                data = methods.Peek();
                if (data.method.Name.Equals(methodName))
                {
                    foundit = true;
                    break;
                }
                temp.Push(methods.Pop());
            }

            for (int i = 0; i < temp.Count; i++)
            {
                methods.Push(temp.Pop());
            }
            temp = null;

            if (!foundit)
            {
                return;
            }

            Debug.WriteLine(data.method.DeclaringType.Name + "." + data.method.Name);
            ParameterInfo[] pi = data.method.GetParameters();

            for (int i = 0; i < pi.Length; i++)
            {
                if (pi[i].Name == parameterName)
                {
                    Debug.Indent();
                    Debug.Write(parameterName + "=");
                    if (pi[i].ParameterType == typeof(IntPtr))
                    {
                        Debug.WriteLine(String.Format("0x{0:x}", ((IntPtr)data.args[i]).ToInt32()));
                    }
                    else
                    {
                        Debug.WriteLine(data.args[i]);
                    }
                    Debug.Unindent();
                }
            }
        }
Beispiel #4
0
        public void Push(object obj)
        {
            if (obj == null)
            {
                throw new NullValueException();
            }

            DataStack.Push(obj);
        }
Beispiel #5
0
        public void Test()
        {
            var a = new List <int> {
                1, 2, 3
            };

            DataStack.Push(a);
            RhoRun(
                @"
a = {1 2 3}
a[1]
");
            Assert.AreEqual(2, Pop <int>());
        }
Beispiel #6
0
        public void Step()
        {
            byte next            = Execution.Pop();
            bool branchIsRunning = RunBranch.Items.All(b => b);

            if (branchIsRunning)
            {
                if (Opcodes.IsFastPush(next))
                {
                    Main.Push(Execution.Pop(next));
                }
                else
                {
                    switch ((Op)next)
                    {
                    case Op.False:
                        Main.Push(false);
                        break;

                    case Op.PushData1:
                        int i = new SignedInt(Execution.Pop()).Value;
                        Main.Push(Execution.Pop(i));
                        break;

                    case Op.PushData2:
                        Main.Push(Execution.Pop(new SignedInt(Execution.Pop(2)).Value));
                        break;

                    case Op.PushData4:
                        Main.Push(Execution.Pop(new SignedInt(Execution.Pop(4)).Value));
                        break;

                    case Op.Negate1:
                        Main.Push(-1);
                        break;

                    case Op.True:
                        Main.Push(true);
                        break;

                    case Op.Num2:
                        Main.Push(2);
                        break;

                    case Op.Num3:
                        Main.Push(3);
                        break;

                    case Op.Num4:
                        Main.Push(4);
                        break;

                    case Op.Num5:
                        Main.Push(5);
                        break;

                    case Op.Num6:
                        Main.Push(6);
                        break;

                    case Op.Num7:
                        Main.Push(7);
                        break;

                    case Op.Num8:
                        Main.Push(8);
                        break;

                    case Op.Num9:
                        Main.Push(9);
                        break;

                    case Op.Num10:
                        Main.Push(10);
                        break;

                    case Op.Num11:
                        Main.Push(11);
                        break;

                    case Op.Num12:
                        Main.Push(12);
                        break;

                    case Op.Num13:
                        Main.Push(13);
                        break;

                    case Op.Num14:
                        Main.Push(14);
                        break;

                    case Op.Num15:
                        Main.Push(15);
                        break;

                    case Op.Num16:
                        Main.Push(16);
                        break;

                    case Op.Verify:
                        if (!Main.PopTruth())
                        {
                            throw new Exception();
                        }
                        break;

                    case Op.Return:
                        throw new Exception();

                    case Op.ToAltStack:
                        Alt.Push(Main.Pop());
                        break;

                    case Op.FromAltStack:
                        Main.Push(Alt.Pop());
                        break;

                    case Op.IfDup:
                        if (Main.IsTrue)
                        {
                            Main.Push(Main[0]);
                        }
                        break;

                    case Op.Depth:
                        Main.Push(Main.Count);
                        break;

                    case Op.Drop:
                        Main.Pop();
                        break;

                    case Op.Dup:
                        Main.Push(Main[0]);
                        break;

                    case Op.Nip:
                        Main.RemoveAt(1);
                        break;

                    case Op.Over:
                        Main.Push(Main[1]);
                        break;

                    case Op.Pick:
                        Main.Push(Main[Main.PopInt()]);
                        break;

                    case Op.Roll:
                        int    index = Main.PopInt();
                        byte[] roll  = Main[index];
                        Main.RemoveAt(index);
                        Main.Push(roll);
                        break;

                    case Op.Rot:
                        byte[][] rot = Main.Pop(3);
                        Main.Push(new byte[][] { rot[0], rot[2], rot[1] });
                        break;

                    case Op.Swap:
                        byte[][] swap = Main.Pop(2);
                        Main.Push(new byte[][] { swap[0], swap[1] });
                        break;

                    case Op.Tuck:
                        byte[][] tuck = Main.Pop(2);
                        Main.Push(new byte[][] { tuck[0], tuck[1], tuck[0] });
                        break;

                    case Op.Drop2:
                        Main.Pop(2);
                        break;

                    case Op.Dup2:
                        Main.Push(new byte[][] { Main[1], Main[0] });
                        break;

                    case Op.Dup3:
                        Main.Push(new byte[][] { Main[2], Main[1], Main[0] });
                        break;

                    case Op.Over2:
                        Main.Push(new byte[][] { Main[3], Main[2] });
                        break;

                    case Op.Rot2:
                        byte[][] rot2 = Main.Pop(6);
                        Main.Push(new byte[][] { rot2[1], rot2[0], rot2[5], rot2[4], rot2[3], rot2[2] });
                        break;

                    case Op.Swap2:
                        byte[][] swap2 = Main.Pop(4);
                        Main.Push(new byte[][] { swap2[2], swap2[3], swap2[0], swap2[1] });
                        break;

                    case Op.Size:
                        throw new NotImplementedException();

                    case Op.Equal:
                        Main.Push(Main[0].SequenceEqual(Main[1]));
                        break;

                    case Op.EqualVerify:
                        Main.Push(Main[0] == Main[1]);
                        goto case Op.Verify;

                    case Op.Add1:
                        Main.Push(Main.PopInt() + 1);
                        break;

                    case Op.Sub1:
                        Main.Push(Main.PopInt() - 1);
                        break;

                    case Op.Negate:
                        Main.Push(-Main.PopInt());
                        break;

                    case Op.Abs:
                        Main.Push(Math.Abs(Main.PopInt()));
                        break;

                    case Op.Not:
                        Main.Push(Main.PopInt() == 0 ? 1 : 0);
                        break;

                    case Op.NotEqual0:
                        Main.Push(Main.PopInt() == 0 ? 0 : 1);
                        break;

                    case Op.Add:
                        Main.Push(Main.PopInt() + Main.PopInt());
                        break;

                    case Op.Sub:
                        int b = Main.PopInt();
                        Main.Push(Main.PopInt() - b);
                        break;

                    case Op.BoolAnd:
                        Main.Push(Main.PopBool() && Main.PopBool());
                        break;

                    case Op.BoolOr:
                        Main.Push(Main.PopBool() || Main.PopBool());
                        break;

                    case Op.NumEqual:
                        Main.Push(Main.PopInt() == Main.PopInt());
                        break;

                    case Op.NumEqualVerify:
                        Main.Push(Main.PopInt() == Main.PopInt());
                        goto case Op.Verify;

                    case Op.NumNotEqual:
                        Main.Push(Main.PopInt() != Main.PopInt());
                        break;

                    case Op.LessThan:
                        Main.Push(Main.PopInt() < Main.PopInt());
                        break;

                    case Op.GreaterThan:
                        Main.Push(Main.PopInt() > Main.PopInt());
                        break;

                    case Op.LessThanOrEqual:
                        Main.Push(Main.PopInt() <= Main.PopInt());
                        break;

                    case Op.GreaterThanOrEqual:
                        Main.Push(Main.PopInt() >= Main.PopInt());
                        break;

                    case Op.Min:
                        Main.Push(Math.Min(Main.PopInt(), Main.PopInt()));
                        break;

                    case Op.Max:
                        Main.Push(Math.Max(Main.PopInt(), Main.PopInt()));
                        break;

                    case Op.Within:
                        int max = Main.PopInt();
                        int min = Main.PopInt();
                        int x   = Main.PopInt();
                        Main.Push(min <= x && x < max);
                        break;

                    case Op.RIPEMD160:
                        Main.Push(RIPEMD160.Hash(Main.Pop()));
                        break;

                    case Op.SHA1:
                        Main.Push(SHA1.Hash(Main.Pop()));
                        break;

                    case Op.SHA256:
                        Main.Push(SHA256.Hash(Main.Pop()));
                        break;

                    case Op.Hash160:
                        Main.Push(Digest.Hash <RIPEMD160, SHA256>(Main.Pop()));
                        break;

                    case Op.Hash256:
                        Main.Push(Digest.Hash <SHA256, SHA256>(Main.Pop()));
                        break;

                    case Op.CodeSeparator:
                        lastSeparatorIndex = _start.Count - Execution.Count;
                        break;

                    case Op.CheckSig:
//						Main.Push(Transaction.SigIsValid(Main.Pop(), Main.Pop(), SubScript, InputIndex));
                        throw new NotImplementedException();

                    case Op.CheckSigVerify:
                        throw new NotImplementedException();

                    case Op.CheckMultiSig:
                        throw new NotImplementedException();

                    case Op.CheckMultiSigVerify:
                        throw new NotImplementedException();

                    case Op.Reserved:
                    case Op.Ver:
                    case Op.Reserved1:
                    case Op.Reserved2:
                        throw new Exception(String.Format("Invalid script! (opcode {0} used)", (Op)next));


                    case Op.If:
                    case Op.NotIf:
                    case Op.Else:
                    case Op.EndIf:
                        goto case Op.Nop;

                    case Op.Nop:
                    case Op.Nop1:
                    case Op.Nop2:
                    case Op.Nop3:
                    case Op.Nop4:
                    case Op.Nop5:
                    case Op.Nop6:
                    case Op.Nop7:
                    case Op.Nop8:
                    case Op.Nop9:
                    case Op.Nop10:
                        break;

                    default:
                        throw new Exception(String.Format("{0} is an invalid opcode", next));
                    }
                }
            }

            switch ((Op)next)
            {
            case Op.If:
                RunBranch.Push(branchIsRunning && Main.PopBool());
                break;

            case Op.NotIf:
                RunBranch.Push(branchIsRunning && !Main.PopBool());
                break;

            case Op.Else:
                RunBranch.Push(!RunBranch.Pop() && !branchIsRunning);
                break;

            case Op.EndIf:
                RunBranch.Pop();
                break;

            case Op.VerIf:
            case Op.VerNotIf:
                throw new Exception(String.Format("Invalid script! (opcode {0} included)", (Op)next));
            }
        }