Exemplo n.º 1
0
        public void PushAndPopItems()
        {
            Stack s = new Stack();

            StackItem si = new StackItem(typeof(Int32), 22);
            StackItem si2 = new StackItem(typeof(String), "vrezvr");

            s.Push(si.Type, si.Value);
            s.Push(si2.Type, si2.Value);

            Assert.That(s.Count == 2, "2 item has been push in stack but there is actually {0} item in stack",s.Count);

            StackItem sip = s.Pop();

            Assert.That(sip.Type, Is.EqualTo(typeof(string)), "Bad initialisation of the type or Pop method");

            Assert.That(sip.Value, Is.EqualTo("vrezvr"), "Bad initialisation of the value or Pop method");

            Assert.That(s.Count == 1, "2 item has been push in stack and one has been pop but there is actually {0} item in stack", s.Count);

            sip = s.FirstElement();

            Assert.That(sip.Type, Is.EqualTo(typeof(Int32)), "Bad initialisation of the type or CurrentStack method");

            Assert.That(sip.Value, Is.EqualTo(22), "Bad initialisation of the value or CurrentStack method");

            sip = s.Pop();

            Assert.That(s.Count == 0, "The stack has to be empty but there is still {0} items in", s.Count);
        }
Exemplo n.º 2
0
 public override void Push(string value)
 {
     var item = new StackItem(value.Substring(0, value.Length < 10 ? value.Length : 10));
     item.Next = Head;
     Head = item;
     Count++;
 }
Exemplo n.º 3
0
 public void append(BackgroundWorkerItem item, Object[] parameters, TimeSpan timeout, ApartmentState apartmentState, ThreadPriority priority)
 {
     StackItem sItem = new StackItem();
     sItem.bWItem = item;
     sItem.parameters = parameters;
     sItem.timeout = timeout;
     sItem.apartmentState = apartmentState;
     sItem.priority = priority;
     //
     this._methodStack.Add(sItem);
 }
Exemplo n.º 4
0
        public HtmlClassIdExtractor(ITagOutput output, string path)
        {
            this.output = output;

            HtmlData.FileName = Path.GetFileName(path);
            HtmlData.FragmentName = Name.ToCamelCase(Path.GetFileNameWithoutExtension(path));

            var s = new StackItem(null);
            s.Selectors.Add(HtmlData);
            stack.Add(s);
        }
Exemplo n.º 5
0
 public void append(Delegate method, Object[] parameters, TimeSpan timeout, ApartmentState apartmentState, ThreadPriority priority)
 {
     StackItem sItem = new StackItem();
     sItem.method = method;
     sItem.parameters = parameters;
     sItem.timeout = timeout;
     sItem.apartmentState = apartmentState;
     sItem.priority = priority;
     //
     this._methodStack.Add(sItem);
 }
Exemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="XIncludeReader"/> class.
        /// </summary>
        /// <param name="underlyingReader">The underlying reader.</param>
        public XIncludeReader(XmlReader underlyingReader)
            : base(underlyingReader)
        {
            // Create the stack we use for handling XInclude elements.
            stack = new List<StackItem>();

            // Wrap the first reader in the stack.
            var item = new StackItem
            {
                Reader = underlyingReader
            };

            stack.Add(item);
        }
Exemplo n.º 7
0
        public void FirstStackCreated()
        {
            Stack s = new Stack();

            Assert.That(s.Count == 0, "The stack is not empty : bad initialisation");

            StackItem si = new StackItem(typeof(Int32), 22);

               s.Push(si.Type, si.Value);

               StackItem si2 = new StackItem(typeof(Int32), 54);

            si2 = s.FirstElement();

            Assert.That(s.Count != 0, "The stack is empty but si has been push on");

            Assert.That(si2.Type, Is.EqualTo(typeof(Int32)), "Bad initialisation of the type");

            Assert.That(si2.Value, Is.EqualTo(22), "Bad initialisation of the value");
        }
Exemplo n.º 8
0
        public void ParsedOpeningTag(Tag tag)
        {
            //Get them before they get obfuscated
            string id = tag.Attribute("id");
            string cs = tag.Attribute("class");

            //Ofuscation being done here
            output.ParsedOpeningTag(tag);

            string[] classes = cs == null ? new string[0] : cs.Split(' ');

            if (id == null && classes.Length == 0)
                return;

            var s = new StackItem(tag);

            foreach (var data in stack[stack.Count - 1].Selectors)
            {
                //Extract local ID
                if (id != null)
                    s.Selectors.Add(data.CreateID(id, tag.Name));

                //Extract local classes
                foreach (string c in classes)
                {
                    if (c == "")
                        continue;

                    s.Selectors.Add(data.CreateClass(c, tag.Name));
                }
            }

            if (tag.SelfClosed)
                return;

            //Add to stack
            if(s.Selectors.Count > 0)
                stack.Add(s);
        }
Exemplo n.º 9
0
        public string Fold(Method input)
        {
            var newItem = new StackItem
            {
                Level = input.MethodStats.StackLevel,
            };
            string prefix = null;

            while (_stack.Count > 0)
            {
                var current = _stack.Peek();

                if (current.Level < newItem.Level)
                {
                    prefix = string.Format("{0};", current.Value);
                    break;
                }
                _stack.Pop();
            }
            newItem.Value = string.Format("{0}{1}", prefix, input.Name);

            _stack.Push(newItem);
            return string.Format("{0} {1}", newItem.Value, input.MethodStats.ElapsedExclusive/10);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Navigates to a panel. If a panel already exist with the same panelId instead or creating a new
        /// panel the old panel will be shown and passed the new arguments.
        /// </summary>
        /// <param name="panelType">The type of panel to be created</param>
        /// <param name="panelId">A unique identifier for the panel, the id should be able to differeincae between two panels of the same type</param>
        /// <param name="arguments">Arguments to be sent to the panel</param>
        /// <returns></returns>
        public bool Navigate(Type panelType, string panelId, Dictionary<string, object> arguments = null)
        {
            if (panelType == null)
            {
                throw new Exception("Panel type can't be null!");
            }

            // Make sure we send args along.
            if (arguments == null)
            {
                arguments = new Dictionary<string, object>();
            }

            // Clear this value
            m_finalNavigateHasShownMenu = false;

            // Report to telemetry
            //App.TelemetryClient.TrackPageView(panelType.Name);

            bool isExitingPanel = false;
            StackItem navigateFromPanel = null;
            lock (m_panelStack)
            {
                // For now we can only do one animation at a time. So if we are doing something we
                // must ignore this
                if (m_state != State.Idle)
                {
                    return false;
                }

                // The panel we will navigate to
                StackItem navigateToPanel = null;

                // First, check to see if we already have the panel
                foreach (StackItem item in m_panelStack)
                {
                    if(item.Panel.GetType() == panelType && item.Id == panelId)
                    {
                        // We found it.
                        isExitingPanel = true;
                        navigateToPanel = item;
                        break;
                    }
                }

                // If we didn't find it make a new panel.
                if(navigateToPanel == null)
                {
                    navigateToPanel = new StackItem();
                    navigateToPanel.Panel = (IPanel)Activator.CreateInstance(panelType);
                    navigateToPanel.Id = panelId;
                }

                // Check the type
                PanelType newPanelType = GetPanelType(navigateToPanel.Panel);

                // Second, Figure out what panel will be leaving.
                if (m_screenMode == ScreenMode.Single)
                {
                    // If we are in single mode it will be the panel from the top of the stack
                    if (m_panelStack.Count > 0)
                    {
                        navigateFromPanel = m_panelStack.Last();
                    }
                }
                else
                {
                    // If we are in split mode it will be the panel we will replace.
                    // So go through the list backwards and find it.
                    foreach (StackItem item in m_panelStack.Reverse<StackItem>())
                    {
                        // If the are both subreddit panels or both not, we found the panel.
                        if (GetPanelType(item.Panel) == newPanelType)
                        {
                            navigateFromPanel = item;
                            break;
                        }
                    }
                }

                // We need to type of the leaving panel. If the panel is null this
                // is the first navigation of a type, so we will just call it the content panel.
                PanelType navigateFromPanelType = PanelType.ContentPanel;
                if (navigateFromPanel != null)
                {
                    navigateFromPanelType = GetPanelType(navigateFromPanel.Panel);
                }

                // Third, Setup the panel. If it already exits call activate instead of setup.
                if (isExitingPanel)
                {
                    navigateToPanel.Panel.OnPanelPulledToTop(arguments);
                }
                else
                {
                    navigateToPanel.Panel.PanelSetup(this, arguments);
                }

                // Special case! If the UI is already shown then we should just return here.
                if(navigateFromPanel != null && navigateFromPanel.Panel.GetType() == navigateToPanel.Panel.GetType() && navigateFromPanel.Id == navigateToPanel.Id)
                {
                    return true;
                }

                // Forth, if the panel exist remove it from the stack
                if(isExitingPanel)
                {
                    m_panelStack.Remove(navigateToPanel);
                }

                // Last, add the panel to the bottom of the list.
                m_panelStack.Add(navigateToPanel);

                // Report the view
                App.BaconMan.TelemetryMan.ReportPageView(navigateToPanel.Panel.GetType().Name);

                // Animate the current panel out
                PlayFadeAnimation(newPanelType, navigateFromPanelType, State.FadingOut);
            }

            // If we have a panel tell it we are leaving no under lock.
            if (navigateFromPanel != null)
            {
                FireOnNavigateFrom(navigateFromPanel.Panel);
            }

            return true;
        }
Exemplo n.º 11
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if compare operands are floating point numbers or if either value is &lt; 4 bytes in length or
        /// operands are not of the same size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop in reverse order to push
            StackItem itemB = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            bool unsignedComparison = (OpCodes)theOp.opCode.Value == OpCodes.Cgt_Un;
            int  currOpPosition     = conversionState.PositionOf(theOp);

            if (itemB.isFloat || itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Add floats is unsupported!");
            }
            else if (itemA.sizeOnStackInBytes == 4 && itemB.sizeOnStackInBytes == 4)
            {
                //Pop item B
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });
                //Pop item A
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });
                //If A <= B, jump to Else (not-true case)
                conversionState.Append(new ASMOps.Branch()
                {
                    Src1 = "$t0", Src2 = "$t1", BranchType = ASMOps.BranchOp.BranchLessThanEqual, DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison
                });
                //Otherwise, A > B, so push true (true=1)
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t4", Src = "1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t4"
                });
                //And then jump to the end of this IL op.
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });
                //Insert the Else label.
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "Else"
                });
                //Else case - Push false (false=0)
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$zero"
                });

                //Push the result onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = true
                });
            }
            else if (itemA.sizeOnStackInBytes == 8 && itemB.sizeOnStackInBytes == 8)
            {
                //Pop item B
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t2"
                });
                //Pop item A
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t3"
                });
                //If A high bytes > B high bytes : True
                //If A high bytes = B high bytes : Check, if A low bytes > B low bytes : True
                //Else : False

                //A high bytes > B high bytes? Branch to true case.
                conversionState.Append(new ASMOps.Branch()
                {
                    Src1 = "$t3", Src2 = "$t2", BranchType = ASMOps.BranchOp.BranchGreaterThan, DestILPosition = currOpPosition, Extension = "True", UnsignedTest = unsignedComparison
                });
                //A high bytes < B high bytes? Branch to else case.
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchLessThan, DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison
                });
                //Otherwise, A high bytes = B high bytes
                //A low bytes <= B low bytes? Branch to else case.
                conversionState.Append(new ASMOps.Branch()
                {
                    Src1 = "$t0", Src2 = "$t1", BranchType = ASMOps.BranchOp.BranchLessThanEqual, DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison
                });

                //Otherwise A > B.

                //Insert True case label
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "True"
                });
                //True case - Push true (true=1)
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t4", Src = "1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t4"
                });
                //And then jump to the end of this IL op.
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });
                //Insert Else case label
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "Else"
                });
                //Else case - Push false (false=0)
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$zero"
                });

                //Push the result onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat = false,
                    // Yes, this is supposed to be 4 - the value that just got pushed was a
                    // true / false integer
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = true
                });
            }
            else
            {
                throw new NotSupportedException("Unsupported number of bytes for compare greater than!");
            }

            //Always append the end label
            conversionState.Append(new ASMOps.Label()
            {
                ILPosition = currOpPosition, Extension = "End"
            });
        }
Exemplo n.º 12
0
 private void Test_Notify2(object sender, NotifyEventArgs e)
 {
     item = null;
 }
 public void Clear()
 {
     top   = null;
     count = 0;
 }
Exemplo n.º 14
0
        protected virtual bool Transaction_GetUnspentCoins(ExecutionEngine engine)
        {
            Transaction tx = engine.EvaluationStack.Pop().GetInterface <Transaction>();

            if (tx == null)
            {
                return(false);
            }
            engine.EvaluationStack.Push(Blockchain.Default.GetUnspent(tx.Hash).Select(p => StackItem.FromInterface(p)).ToArray());
            return(true);
        }
 public StackItem(StackItem parent, T item)
 {
     Parent = parent;
     Item   = item;
 }
 void IDisposable.Dispose()
 {
     cur = first = null;
 }
Exemplo n.º 17
0
 protected bool Block_GetTransactions(ExecutionEngine engine)
 {
     if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)
     {
         Block block = _interface.GetInterface <Block>();
         if (block == null)
         {
             return(false);
         }
         if (block.Transactions.Length > ApplicationEngine.MaxArraySize)
         {
             return(false);
         }
         engine.CurrentContext.EvaluationStack.Push(block.Transactions.Select(p => StackItem.FromInterface(p)).ToArray());
         return(true);
     }
     return(false);
 }
Exemplo n.º 18
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point.
        /// </exception>
        /// <exception cref="System.NotImplementedException">
        /// Thrown if the op is 'StIndRef'.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop value
            //Pop address
            //Mov [address], value

            StackItem valueItem    = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem addressItem  = conversionState.CurrentStackFrame.Stack.Pop();
            int       bytesToStore = 0;
            bool      isFloat      = false;

            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Stind_I:
                bytesToStore = 4;
                break;

            case OpCodes.Stind_I1:
                bytesToStore = 1;
                break;

            case OpCodes.Stind_I2:
                bytesToStore = 2;
                break;

            case OpCodes.Stind_I4:
                bytesToStore = 4;
                break;

            case OpCodes.Stind_I8:
                bytesToStore = 8;
                break;

            case OpCodes.Stind_R4:
                bytesToStore = 4;
                isFloat      = true;
                break;

            case OpCodes.Stind_R8:
                bytesToStore = 8;
                isFloat      = true;
                break;

            case OpCodes.Stind_Ref:
                bytesToStore = 4;
                break;
            }

            if (isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Floats not supported yet!");
            }

            int currOpPosition = conversionState.PositionOf(theOp);

            if (bytesToStore == 8)
            {
                //Pop value low bits
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });
                //Pop value high bits
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t3"
                });

                //Pop address
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });

                // Alignment tests
                conversionState.Append(new ASMOps.And()
                {
                    Src1 = "$t1", Src2 = "3", Dest = "$t5"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "1", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "2", DestILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "3", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "WordAligned"
                });

                //Mov [address], value
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "1($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "2($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "3($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });

                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t3", Dest = "4($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t3", Dest = "$t3", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t3", Dest = "5($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t3", Dest = "$t3", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t3", Dest = "6($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t3", Dest = "$t3", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t3", Dest = "7($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });


                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 16
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t0", Dest = "2($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });

                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t3", Dest = "4($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t3", Dest = "$t3", Bits = 16
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t3", Dest = "6($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });


                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "WordAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t3", Dest = "4($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
            }
            else if (bytesToStore == 4)
            {
                //Pop value
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });

                //Pop address
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });

                // Alignment tests
                conversionState.Append(new ASMOps.And()
                {
                    Src1 = "$t1", Src2 = "3", Dest = "$t5"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "1", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "2", DestILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "3", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "WordAligned"
                });

                //Mov [address], value
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "1($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "2($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "3($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });


                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 16
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t0", Dest = "2($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });


                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "WordAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
            }
            else if (bytesToStore == 2)
            {
                //Pop value
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });

                //Pop address
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });

                // Alignment tests
                conversionState.Append(new ASMOps.And()
                {
                    Src1 = "$t1", Src2 = "3", Dest = "$t5"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "1", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "2", DestILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src1 = "$t5", Src2 = "3", DestILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "WordAligned"
                });

                //Mov [address], value
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "ByteAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Srl()
                {
                    Src = "$t0", Dest = "$t0", Bits = 8
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "1($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });

                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "HalfwordAligned"
                });
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "WordAligned"
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Halfword, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End"
                });
            }
            else if (bytesToStore == 1)
            {
                //Pop value
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t0"
                });

                //Pop address
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Word, Dest = "$t1"
                });

                //Mov [address], value
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = "0($t1)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
            }

            conversionState.Append(new ASMOps.Label()
            {
                ILPosition = currOpPosition, Extension = "End"
            });
        }
Exemplo n.º 19
0
        private void SerializeStackItem(StackItem item, BinaryWriter writer)
        {
            List <StackItem>  serialized   = new List <StackItem>();
            Stack <StackItem> unserialized = new Stack <StackItem>();

            unserialized.Push(item);
            while (unserialized.Count > 0)
            {
                item = unserialized.Pop();
                switch (item)
                {
                case ByteArray _:
                    writer.Write((byte)StackItemType.ByteArray);
                    writer.WriteVarBytes(item.GetByteArray());
                    break;

                case VMBoolean _:
                    writer.Write((byte)StackItemType.Boolean);
                    writer.Write(item.GetBoolean());
                    break;

                case Integer _:
                    writer.Write((byte)StackItemType.Integer);
                    writer.WriteVarBytes(item.GetByteArray());
                    break;

                case InteropInterface _:
                    throw new NotSupportedException();

                case VMArray array:
                    if (serialized.Any(p => ReferenceEquals(p, array)))
                    {
                        throw new NotSupportedException();
                    }
                    serialized.Add(array);
                    if (array is Struct)
                    {
                        writer.Write((byte)StackItemType.Struct);
                    }
                    else
                    {
                        writer.Write((byte)StackItemType.Array);
                    }
                    writer.WriteVarInt(array.Count);
                    for (int i = array.Count - 1; i >= 0; i--)
                    {
                        unserialized.Push(array[i]);
                    }
                    break;

                case Map map:
                    if (serialized.Any(p => ReferenceEquals(p, map)))
                    {
                        throw new NotSupportedException();
                    }
                    serialized.Add(map);
                    writer.Write((byte)StackItemType.Map);
                    writer.WriteVarInt(map.Count);
                    foreach (var pair in map.Reverse())
                    {
                        unserialized.Push(pair.Value);
                        unserialized.Push(pair.Key);
                    }
                    break;
                }
            }
        }
Exemplo n.º 20
0
        private StackItem DeserializeStackItem(BinaryReader reader)
        {
            Stack <StackItem> deserialized = new Stack <StackItem>();
            int undeserialized             = 1;

            while (undeserialized-- > 0)
            {
                StackItemType type = (StackItemType)reader.ReadByte();
                switch (type)
                {
                case StackItemType.ByteArray:
                    deserialized.Push(new ByteArray(reader.ReadVarBytes()));
                    break;

                case StackItemType.Boolean:
                    deserialized.Push(new VMBoolean(reader.ReadBoolean()));
                    break;

                case StackItemType.Integer:
                    deserialized.Push(new Integer(new BigInteger(reader.ReadVarBytes())));
                    break;

                case StackItemType.Array:
                case StackItemType.Struct:
                {
                    int count = (int)reader.ReadVarInt(ApplicationEngine.MaxArraySize);
                    deserialized.Push(new ContainerPlaceholder
                        {
                            Type         = type,
                            ElementCount = count
                        });
                    undeserialized += count;
                }
                break;

                case StackItemType.Map:
                {
                    int count = (int)reader.ReadVarInt(ApplicationEngine.MaxArraySize);
                    deserialized.Push(new ContainerPlaceholder
                        {
                            Type         = type,
                            ElementCount = count
                        });
                    undeserialized += count * 2;
                }
                break;

                default:
                    throw new FormatException();
                }
            }
            Stack <StackItem> stack_temp = new Stack <StackItem>();

            while (deserialized.Count > 0)
            {
                StackItem item = deserialized.Pop();
                if (item is ContainerPlaceholder placeholder)
                {
                    switch (placeholder.Type)
                    {
                    case StackItemType.Array:
                        VMArray array = new VMArray();
                        for (int i = 0; i < placeholder.ElementCount; i++)
                        {
                            array.Add(stack_temp.Pop());
                        }
                        item = array;
                        break;

                    case StackItemType.Struct:
                        Struct @struct = new Struct();
                        for (int i = 0; i < placeholder.ElementCount; i++)
                        {
                            @struct.Add(stack_temp.Pop());
                        }
                        item = @struct;
                        break;

                    case StackItemType.Map:
                        Map map = new Map();
                        for (int i = 0; i < placeholder.ElementCount; i++)
                        {
                            StackItem key   = stack_temp.Pop();
                            StackItem value = stack_temp.Pop();
                            map.Add(key, value);
                        }
                        item = map;
                        break;
                    }
                }
                stack_temp.Push(item);
            }
            return(stack_temp.Peek());
        }
Exemplo n.º 21
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// If either value is &lt; 4 bytes in length or
        /// operands are not of the same size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop item to duplicate
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            if (itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Duplicate float vals not suppported yet!");
            }

            if (itemA.sizeOnStackInBytes == 4)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
            }
            else if (itemA.sizeOnStackInBytes == 8)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EDX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EDX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EDX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
            }
            else
            {
                throw new NotSupportedException("Stack item size not supported by duplicate op!");
            }

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = itemA.isFloat,
                sizeOnStackInBytes = itemA.sizeOnStackInBytes,
                isGCManaged        = itemA.isGCManaged
            });
            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = itemA.isFloat,
                sizeOnStackInBytes = itemA.sizeOnStackInBytes,
                isGCManaged        = itemA.isGCManaged
            });
        }
Exemplo n.º 22
0
        private bool Contract_Migrate(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            ContractParameterType[] parameter_list = engine.CurrentContext.EvaluationStack.Pop().GetByteArray().Select(p => (ContractParameterType)p).ToArray();
            if (parameter_list.Length > 252)
            {
                return(false);
            }
            ContractParameterType return_type         = (ContractParameterType)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();
            ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string name = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string version = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string author = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string email = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 65536)
            {
                return(false);
            }
            string        description = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            UInt160       hash        = script.ToScriptHash();
            ContractState contract    = Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                contract = new ContractState
                {
                    Script             = script,
                    ParameterList      = parameter_list,
                    ReturnType         = return_type,
                    ContractProperties = contract_properties,
                    Name        = name,
                    CodeVersion = version,
                    Author      = author,
                    Email       = email,
                    Description = description
                };
                Snapshot.Contracts.Add(hash, contract);
                ContractsCreated.Add(hash, new UInt160(engine.CurrentContext.ScriptHash));
                if (contract.HasStorage)
                {
                    foreach (var pair in Snapshot.Storages.Find(engine.CurrentContext.ScriptHash).ToArray())
                    {
                        Snapshot.Storages.Add(new StorageKey
                        {
                            ScriptHash = hash,
                            Key        = pair.Key.Key
                        }, new StorageItem
                        {
                            Value      = pair.Value.Value,
                            IsConstant = false
                        });
                    }
                }
            }
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(Contract_Destroy(engine));
        }
Exemplo n.º 23
0
        private bool Asset_Create(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            InvocationTransaction tx         = (InvocationTransaction)engine.ScriptContainer;
            AssetType             asset_type = (AssetType)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

            if (!Enum.IsDefined(typeof(AssetType), asset_type) || asset_type == AssetType.CreditFlag || asset_type == AssetType.DutyFlag || asset_type == AssetType.GoverningToken || asset_type == AssetType.UtilityToken)
            {
                return(false);
            }
            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 1024)
            {
                return(false);
            }
            string name   = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            Fixed8 amount = new Fixed8((long)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger());

            if (amount == Fixed8.Zero || amount < -Fixed8.Satoshi)
            {
                return(false);
            }
            if (asset_type == AssetType.Invoice && amount != -Fixed8.Satoshi)
            {
                return(false);
            }
            byte precision = (byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

            if (precision > 8)
            {
                return(false);
            }
            if (asset_type == AssetType.Share && precision != 0)
            {
                return(false);
            }
            if (amount != -Fixed8.Satoshi && amount.GetData() % (long)Math.Pow(10, 8 - precision) != 0)
            {
                return(false);
            }
            ECPoint owner = ECPoint.DecodePoint(engine.CurrentContext.EvaluationStack.Pop().GetByteArray(), ECCurve.Secp256r1);

            if (owner.IsInfinity)
            {
                return(false);
            }
            if (!CheckWitness(engine, owner))
            {
                return(false);
            }
            UInt160    admin  = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            UInt160    issuer = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            AssetState asset  = Snapshot.Assets.GetOrAdd(tx.Hash, () => new AssetState
            {
                AssetId    = tx.Hash,
                AssetType  = asset_type,
                Name       = name,
                Amount     = amount,
                Available  = Fixed8.Zero,
                Precision  = precision,
                Fee        = Fixed8.Zero,
                FeeAddress = new UInt160(),
                Owner      = owner,
                Admin      = admin,
                Issuer     = issuer,
                Expiration = Snapshot.Height + 1 + 2000000,
                IsFrozen   = false
            });

            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(asset));
            return(true);
        }
Exemplo n.º 24
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="anILOpInfo">See base class documentation.</param>
        /// <param name="aScannerState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if any argument or the return value is a floating point number.
        /// </exception>
        public override string Convert(ILOpInfo anILOpInfo, ILScannerState aScannerState)
        {
            StringBuilder result = new StringBuilder();

            MethodBase methodToCall = anILOpInfo.MethodToCall;
            //The method to call is a method base
            //A method base can be either a method info i.e. a normal method
            //or a constructor method. The two types are treated separately.
            if(methodToCall is MethodInfo)
            {
                //Allocate space on the stack for the return value as necessary
                Type retType = ((MethodInfo)methodToCall).ReturnType;
                StackItem returnItem = new StackItem()
                {
                    isFloat = Utils.IsFloat(retType),
                    sizeOnStackInBytes = Utils.GetNumBytesForType(retType),
                    isGCManaged = Utils.IsGCManaged(retType)
                };
                //We do not push the return value onto the stack unless it has size > 0
                //We do not push the return value onto our stack at this point - it is pushed after the call is done

                if (returnItem.sizeOnStackInBytes != 0)
                {
                    if (returnItem.isFloat)
                    {
                        //SUPPORT - floats
                        throw new NotSupportedException("Cannot handle float return values!");
                    }
                    else if (returnItem.sizeOnStackInBytes == 4)
                    {
                        result.AppendLine("push dword 0");
                    }
                    else if (returnItem.sizeOnStackInBytes == 8)
                    {
                        result.AppendLine("push dword 0");
                        result.AppendLine("push dword 0");
                    }
                    else
                    {
                        throw new NotSupportedException("Invalid return stack operand size!");
                    }
                }

                //Get the ID of method to call as it will be labelled in the output ASM.
                string methodID = aScannerState.GetMethodID(methodToCall);
                //Append the actual call
                result.AppendLine(string.Format("call {0}", methodID));

                //After a call, we need to remove the return value and parameters from the stack
                //This is most easily done by just adding the total number of bytes for params and
                //return value to the stack pointer (ESP register).
                
                //Stores the number of bytes to add
                int bytesToAdd = 0;
                //All the parameters for the method that was called
                List<Type> allParams = ((MethodInfo)methodToCall).GetParameters().Select(x => x.ParameterType).ToList();
                //Go through each one
                if (!methodToCall.IsStatic)
                {
                    allParams.Insert(0, methodToCall.DeclaringType);
                }
                foreach (Type aParam in allParams)
                {
                    //Pop the paramter off our stack 
                    //(Note: Return value was never pushed onto our stack. See above)
                    aScannerState.CurrentStackFrame.Stack.Pop();
                    //Add the size of the paramter to the total number of bytes to pop
                    bytesToAdd += Utils.GetNumBytesForType(aParam);
                }
                //If the number of bytes to add to skip over params is > 0
                if (bytesToAdd > 0)
                {
                    //If there is a return value on the stack
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //We need to store the return value then pop all the params

                        //We now push the return value onto our stack as,
                        //after all is said and done below, it will be the 
                        //top item on the stack
                        aScannerState.CurrentStackFrame.Stack.Push(returnItem);

                        //SUPPORT - floats (with above)

                        //Pop the return value into the eax register
                        //We will push it back on after params are skipped over.
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("pop dword eax");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("pop dword eax");
                            result.AppendLine("pop dword edx");
                        }
                    }   
                    //Skip over the params
                    result.AppendLine(string.Format("add esp, {0}", bytesToAdd));
                    //If necessary, push the return value onto the stack.
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //SUPPORT - floats (with above)

                        //The return value was stored in eax
                        //So push it back onto the stack
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("push dword eax");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("push dword edx");
                            result.AppendLine("push dword eax");
                        }
                    }
                }
                //No params to skip over but we might still need to store return value
                else if (returnItem.sizeOnStackInBytes != 0)
                {
                    //The return value will be the top item on the stack.
                    //So all we need to do is push the return item onto our stack.
                    aScannerState.CurrentStackFrame.Stack.Push(returnItem);
                }
            }
            else if(methodToCall is ConstructorInfo)
            {
                ConstructorInfo aConstructor = (ConstructorInfo)methodToCall;
                if (aConstructor.IsStatic)
                {
                    //Static constructors do not have parameters or return values

                    //Get the ID of method to call as it will be labelled in the output ASM.
                    string methodID = aScannerState.GetMethodID(methodToCall);
                    //Append the actual call
                    result.AppendLine(string.Format("call {0}", methodID));
                }
                else
                {
                    //Get the ID of method to call as it will be labelled in the output ASM.
                    string methodID = aScannerState.GetMethodID(methodToCall);
                    //Append the actual call
                    result.AppendLine(string.Format("call {0}", methodID));

                    //After a call, we need to remove the parameters from the stack
                    //This is most easily done by just adding the total number of bytes for params
                    //to the stack pointer (ESP register).

                    //Stores the number of bytes to add
                    int bytesToAdd = 0;
                    //All the parameters for the method that was called
                    ParameterInfo[] allParams = methodToCall.GetParameters();
                    //Go through each one
                    foreach (ParameterInfo aParam in allParams)
                    {
                        //Pop the paramter off our stack 
                        //(Note: Return value was never pushed onto our stack. See above)
                        aScannerState.CurrentStackFrame.Stack.Pop();
                        //Add the size of the paramter to the total number of bytes to pop
                        bytesToAdd += Utils.GetNumBytesForType(aParam.ParameterType);
                    }
                    //Add 4 bytes for the instance ref
                    bytesToAdd += 4;
                    //If the number of bytes to add to skip over params is > 0
                    if (bytesToAdd > 0)
                    {
                        //Skip over the params
                        result.AppendLine(string.Format("add esp, {0}", bytesToAdd));
                    }
                }
            }
            
            return result.ToString().Trim();
        }
Exemplo n.º 25
0
 public static BigInteger? ToBigInteger(this StackItem value) => value == null || value is Null ? (BigInteger?)null : value.GetInteger();
Exemplo n.º 26
0
        private void PostTransfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data, bool callOnPayment)
        {
            // Send notification

            engine.SendNotification(Hash, "Transfer",
                                    new Array {
                from?.ToArray() ?? StackItem.Null, to?.ToArray() ?? StackItem.Null, amount
            });

            // Check if it's a wallet or smart contract

            if (!callOnPayment || to is null || ContractManagement.GetContract(engine.Snapshot, to) is null)
            {
                return;
            }

            // Call onNEP17Payment method

            engine.CallFromNativeContract(Hash, to, "onNEP17Payment", from?.ToArray() ?? StackItem.Null, amount, data);
        }
Exemplo n.º 27
0
 /// <summary>
 /// Converts the <see cref="StackItem"/> to a <see cref="ContractParameter"/>.
 /// </summary>
 /// <param name="item">The <see cref="StackItem"/> to convert.</param>
 /// <returns>The converted <see cref="ContractParameter"/>.</returns>
 public static ContractParameter ToContractParameter(this StackItem item, List<(StackItem, ContractParameter)> context = null)
 public StackItemEnumerator(StackItem cur)
 {
     this.cur = first = new StackItem(cur, default(T));
 }
Exemplo n.º 29
0
 public static bool NotVmByteArray(this StackItem item)
 {
     return !(item is ByteString);
 }
 void IEnumerator.Reset()
 {
     cur = first;
 }
Exemplo n.º 31
0
 public static bool NotVmNull(this StackItem item)
 {
     return !(item.IsNull);
 }
 public void Push(T item)
 {
     top = new StackItem(top, item);
     count++;
 }
Exemplo n.º 33
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="anILOpInfo">See base class documentation.</param>
        /// <param name="aScannerState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if any argument or the return value is a floating point number.
        /// </exception>
        public override string Convert(ILOpInfo anILOpInfo, ILScannerState aScannerState)
        {
            StringBuilder result = new StringBuilder();

            MethodBase methodToCall = anILOpInfo.MethodToCall;
            //The method to call is a method base
            //A method base can be either a method info i.e. a normal method
            //or a constructor method. The two types are treated separately.
            if(methodToCall is MethodInfo)
            {
                //Need to do callvirt related stuff to load address of method to call
                // - Check for invoke of a delegate - if so, treat rather differently from normal callvirt


                string call_Label = string.Format("{0}.IL_{1}_Call",
                                                aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                                                anILOpInfo.Position);

                if (typeof(Delegate).IsAssignableFrom(((MethodInfo)methodToCall).DeclaringType))
                {
                    //Callvirt to delegate method
                    // - We only support calls to Invoke at the moment
                    if (methodToCall.Name != "Invoke")
                    {
                        throw new NotSupportedException("Callvirt to Delegate method not supported! Method name: " + methodToCall.Name);
                    }
                    int bytesForAllParams = ((MethodInfo)methodToCall).GetParameters().Select(x => Utils.GetNumBytesForType(x.ParameterType)).Sum();
                    
                    // - Move into eax address of function to call from stack - delegate reference is function pointer

                    //All the parameters for the method that was called
                    List<Type> allParams = ((MethodInfo)methodToCall).GetParameters().Select(x => x.ParameterType).ToList();

                    int bytesForParams = allParams.Select(x => Utils.GetNumBytesForType(x)).Sum();
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "esp", bytesForParams, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine(string.Format("mov dword eax, [esp+{0}]", bytesForParams));


                    //Allocate space on the stack for the return value as necessary
                    Type retType = ((MethodInfo)methodToCall).ReturnType;
                    StackItem returnItem = new StackItem()
                    {
                        isFloat = Utils.IsFloat(retType),
                        sizeOnStackInBytes = Utils.GetNumBytesForType(retType),
                        isGCManaged = Utils.IsGCManaged(retType)
                    };
                    //We do not push the return value onto the stack unless it has size > 0
                    //We do not push the return value onto our stack at this point - it is pushed after the call is done

                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        if (returnItem.isFloat)
                        {
                            //SUPPORT - floats
                            throw new NotSupportedException("Cannot handle float return values!");
                        }
                        else if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("push dword 0");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("push dword 0");
                            result.AppendLine("push dword 0");
                        }
                        else
                        {
                            throw new NotSupportedException("Invalid return stack operand size!");
                        }
                    }
                    


                    //Append the actual call
                    result.AppendLine("call eax");
                    


                    //After a call, we need to remove the return value and parameters from the stack
                    //This is most easily done by just adding the total number of bytes for params and
                    //return value to the stack pointer (ESP register).

                    //Stores the number of bytes to add
                    // - Initially at least 4 for the delegate (method) ref/pointer
                    int bytesToAdd = 4;
                    //Go through all params that must be removed
                    foreach (Type aParam in allParams)
                    {
                        //Pop the paramter off our stack 
                        //(Note: Return value was never pushed onto our stack. See above)
                        aScannerState.CurrentStackFrame.Stack.Pop();
                        //Add the size of the paramter to the total number of bytes to pop
                        bytesToAdd += Utils.GetNumBytesForType(aParam);
                    }
                        
                    //If there is a return value on the stack
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //We need to store the return value then pop all the params

                        //We now push the return value onto our stack as,
                        //after all is said and done below, it will be the 
                        //top item on the stack
                        aScannerState.CurrentStackFrame.Stack.Push(returnItem);

                        //SUPPORT - floats (with above)

                        //Pop the return value into the eax register
                        //We will push it back on after params are skipped over.
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("pop dword eax");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("pop dword eax");
                            result.AppendLine("pop dword edx");
                        }
                    }
                    //Skip over the params
                    result.AppendLine(string.Format("add esp, {0}", bytesToAdd));
                    //If necessary, push the return value onto the stack.
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //SUPPORT - floats (with above)

                        //The return value was stored in eax
                        //So push it back onto the stack
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("push dword eax");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("push dword edx");
                            result.AppendLine("push dword eax");
                        }
                    }
                }
                else
                {
                    //Normal callvirt
                    // - Get object ref from loaded args
                    // - Check object ref not null
                    // - Get type table entry from object ref
                    // - Get method table from type table entry
                    // - Scan method table for the method we want
                    //      - If found, load method address
                    // - Else, check for parent type method table
                    //      - If no parent type method table, throw exception
                    // - Else, scan parent type method table

                    string methodIDValueWanted = aScannerState.GetMethodIDValue((MethodInfo)methodToCall);
                    string loopTableEntries_Label = string.Format("{0}.IL_{1}_LoopMethodTable",
                                                    aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                                                    anILOpInfo.Position);
                    string notEqual_Label = string.Format("{0}.IL_{1}_NotEqual",
                                                    aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                                                    anILOpInfo.Position);
                    string endOfTable_Label = string.Format("{0}.IL_{1}_EndOfTable",
                                                    aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                                                    anILOpInfo.Position);
                    string notFound_Label = string.Format("{0}.IL_{1}_NotFound",
                                                    aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                                                    anILOpInfo.Position);
                    string notNull_Label = string.Format("{0}.IL_{1}_NotNullMem",
                    aScannerState.GetMethodID(aScannerState.CurrentILChunk.Method),
                    anILOpInfo.Position);

                    
                    DB_Type declaringDBType = DebugDatabase.GetType(aScannerState.GetTypeID(methodToCall.DeclaringType));

                    //Get object ref
                    int bytesForAllParams = ((MethodInfo)methodToCall).GetParameters().Select(x => Utils.GetNumBytesForType(x.ParameterType)).Sum();
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "esp", bytesForAllParams, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine(string.Format("mov dword eax, [esp+{0}]", bytesForAllParams));

                    //Check object ref
                    result.AppendLine("cmp eax, 0");
                    result.AppendLine(string.Format("jnz {0}", notNull_Label));
                    result.AppendLine("call GetEIP");
                    result.AppendLine(string.Format("call {0}", aScannerState.GetMethodID(aScannerState.HaltMethod)));
                    result.AppendLine(notNull_Label + ":");

                    //Get type ref
                    int typeOffset = aScannerState.GetFieldOffset(declaringDBType, "_Type");
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "eax", typeOffset, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine(string.Format("mov eax, [eax+{0}]", typeOffset));

                    //Get method table ref
                    int methodTablePtrOffset = aScannerState.GetTypeFieldOffset("MethodTablePtr");
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "eax", methodTablePtrOffset, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine(string.Format("mov eax, [eax+{0}]", methodTablePtrOffset));

                    //Loop through entries
                    result.AppendLine(loopTableEntries_Label + ":");
                    //Load ID Val for current entry
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "eax", 0, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine("mov ebx, [eax]");
                    //Compare to wanted ID value
                    result.AppendLine("cmp ebx, " + methodIDValueWanted);
                    //If equal, load method address into eax
                    result.AppendLine("jne " + notEqual_Label);
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "eax", 4, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine("mov eax, [eax+4]");
                    result.AppendLine("jmp " + call_Label);
                    result.AppendLine(notEqual_Label + ":");
                    //Else, compare to 0 to check for end of table
                    result.AppendLine("cmp ebx, 0");
                    result.AppendLine("jz " + endOfTable_Label);
                    //Not 0? Move to next entry then loop again
                    result.AppendLine("add eax, 8");
                    result.AppendLine("jmp " + loopTableEntries_Label);
                    result.AppendLine(endOfTable_Label + ":");
                    //Compare address value to 0
                    //If not zero, there is a parent method table to check
                    GlobalMethods.InsertPageFaultDetection(result, aScannerState, "eax", 4, (OpCodes)anILOpInfo.opCode.Value);
                    result.AppendLine("mov ebx, [eax+4]");
                    result.AppendLine("cmp ebx, 0");
                    result.AppendLine("jz " + notFound_Label);
                    //Load parent method table and loop 
                    result.AppendLine("mov eax, ebx");
                    result.AppendLine("jmp " + loopTableEntries_Label);
                    result.AppendLine(notFound_Label + ":");
                    //Throw exception!
                    result.AppendLine(string.Format("call {0}", aScannerState.GetMethodID(aScannerState.ThrowNullReferenceExceptionMethod)));

                    result.AppendLine(call_Label + ":");

                    //Allocate space on the stack for the return value as necessary
                    Type retType = ((MethodInfo)methodToCall).ReturnType;
                    StackItem returnItem = new StackItem()
                    {
                        isFloat = Utils.IsFloat(retType),
                        sizeOnStackInBytes = Utils.GetNumBytesForType(retType),
                        isGCManaged = Utils.IsGCManaged(retType)
                    };
                    //We do not push the return value onto the stack unless it has size > 0
                    //We do not push the return value onto our stack at this point - it is pushed after the call is done

                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        if (returnItem.isFloat)
                        {
                            //SUPPORT - floats
                            throw new NotSupportedException("Cannot handle float return values!");
                        }
                        else if (returnItem.sizeOnStackInBytes == 4)
                        {
                            result.AppendLine("push dword 0");
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            result.AppendLine("push dword 0");
                            result.AppendLine("push dword 0");
                        }
                        else
                        {
                            throw new NotSupportedException("Invalid return stack operand size!");
                        }
                    }


                    //Append the actual call
                    result.AppendLine("call eax");



                    //After a call, we need to remove the return value and parameters from the stack
                    //This is most easily done by just adding the total number of bytes for params and
                    //return value to the stack pointer (ESP register).

                    //Stores the number of bytes to add
                    int bytesToAdd = 0;
                    //All the parameters for the method that was called
                    List<Type> allParams = ((MethodInfo)methodToCall).GetParameters().Select(x => x.ParameterType).ToList();
                    //Go through each one
                    if (!methodToCall.IsStatic)
                    {
                        allParams.Insert(0, methodToCall.DeclaringType);
                    }
                    foreach (Type aParam in allParams)
                    {
                        //Pop the paramter off our stack 
                        //(Note: Return value was never pushed onto our stack. See above)
                        aScannerState.CurrentStackFrame.Stack.Pop();
                        //Add the size of the paramter to the total number of bytes to pop
                        bytesToAdd += Utils.GetNumBytesForType(aParam);
                    }
                    //If the number of bytes to add to skip over params is > 0
                    if (bytesToAdd > 0)
                    {
                        //If there is a return value on the stack
                        if (returnItem.sizeOnStackInBytes != 0)
                        {
                            //We need to store the return value then pop all the params

                            //We now push the return value onto our stack as,
                            //after all is said and done below, it will be the 
                            //top item on the stack
                            aScannerState.CurrentStackFrame.Stack.Push(returnItem);

                            //SUPPORT - floats (with above)

                            //Pop the return value into the eax register
                            //We will push it back on after params are skipped over.
                            if (returnItem.sizeOnStackInBytes == 4)
                            {
                                result.AppendLine("pop dword eax");
                            }
                            else if (returnItem.sizeOnStackInBytes == 8)
                            {
                                result.AppendLine("pop dword eax");
                                result.AppendLine("pop dword edx");
                            }
                        }
                        //Skip over the params
                        result.AppendLine(string.Format("add esp, {0}", bytesToAdd));
                        //If necessary, push the return value onto the stack.
                        if (returnItem.sizeOnStackInBytes != 0)
                        {
                            //SUPPORT - floats (with above)

                            //The return value was stored in eax
                            //So push it back onto the stack
                            if (returnItem.sizeOnStackInBytes == 4)
                            {
                                result.AppendLine("push dword eax");
                            }
                            else if (returnItem.sizeOnStackInBytes == 8)
                            {
                                result.AppendLine("push dword edx");
                                result.AppendLine("push dword eax");
                            }
                        }
                    }
                    //No params to skip over but we might still need to store return value
                    else if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //The return value will be the top item on the stack.
                        //So all we need to do is push the return item onto our stack.
                        aScannerState.CurrentStackFrame.Stack.Push(returnItem);
                    }
                }
            }
            else if(methodToCall is ConstructorInfo)
            {
                throw new NotSupportedException("How the hell are we getting callvirts to constructor methods?!");
            }
            
            return result.ToString().Trim();
        }
Exemplo n.º 34
0
 public override bool Equals(StackItem other) => true;
Exemplo n.º 35
0
 public Worker(StackItem stackItem)
 {
     this._stackItem = stackItem;
 }
Exemplo n.º 36
0
 private void Test_Notify1(object sender, NotifyEventArgs e)
 {
     item = e.State;
 }
Exemplo n.º 37
0
		private void EmitBranchToCondition(StackItem item)
		{
			EmitBranch(item.ConditionLabel, item.ExceptionBlockNestingLevel);
		}
Exemplo n.º 38
0
 public virtual void FromStackItem(StackItem stackItem)
 {
     Balance = ((Struct)stackItem)[0].GetInteger();
 }
Exemplo n.º 39
0
 void IInteroperable.FromStackItem(StackItem stackItem)
 {
     throw new NotSupportedException();
 }
Exemplo n.º 40
0
			/// <summary>
			/// Compiles in a seperate appdomain utilitizing one of the compilers on the stack.
			/// </summary>
			public static void Compile(ErrorSink/*!*/ errorSink, CompilationParameters/*!*/ ps)
			{
				// obtain a compiler
				StackItem item = new StackItem();
				lock (stack)
				{
					if (stack.Count > 0) item = stack.Pop();
				}
				if (item.Compiler == null) item.Compiler = ApplicationCompiler.CreateRemoteCompiler();

				// compile
				item.Compiler.RemoteCompile(ref errorSink, ps);

				// check whether the separate appdomain is not too weedy
				if (++item.CompileCounter == 1 || item.CompileCounter == compileCounterTreshold)
				{
					item.CompileCounter = 1;

					CallBackDisplay display = new CallBackDisplay();

					// avoid passing the array of assemblies across appdomain boundary
					item.Compiler.Domain.DoCallBack(display.Handler);

					if (item.RemoteAssemblyCount == 0) item.RemoteAssemblyCount = display.AssemblyCount;
					else
					{
						if (display.AssemblyCount > (2 * item.RemoteAssemblyCount))
						{
							AppDomain.Unload(item.Compiler.Domain);
							return;
						}
					}
				}

				// recycle the compiler
				lock (stack) stack.Push(item);
			}
 void ICollection <T> .Clear()
 {
     top   = null;
     count = 0;
 }
Exemplo n.º 42
0
 public NotifyEventArgs(IVerifiable container, UInt160 script_hash, StackItem state)
 {
     this.ScriptContainer = container;
     this.ScriptHash      = script_hash;
     this.State           = state;
 }
Exemplo n.º 43
0
        protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data)
        {
            if (amount.Sign < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount));
            }
            if (!from.Equals(engine.CallingScriptHash) && !engine.CheckWitnessInternal(from))
            {
                return(false);
            }
            StorageKey  key_from     = CreateStorageKey(Prefix_Account).Add(from);
            StorageItem storage_from = engine.Snapshot.GetAndChange(key_from);

            if (amount.IsZero)
            {
                if (storage_from != null)
                {
                    TState state_from = storage_from.GetInteroperable <TState>();
                    OnBalanceChanging(engine, from, state_from, amount);
                }
            }
            else
            {
                if (storage_from is null)
                {
                    return(false);
                }
                TState state_from = storage_from.GetInteroperable <TState>();
                if (state_from.Balance < amount)
                {
                    return(false);
                }
                if (from.Equals(to))
                {
                    OnBalanceChanging(engine, from, state_from, BigInteger.Zero);
                }
                else
                {
                    OnBalanceChanging(engine, from, state_from, -amount);
                    if (state_from.Balance == amount)
                    {
                        engine.Snapshot.Delete(key_from);
                    }
                    else
                    {
                        state_from.Balance -= amount;
                    }
                    StorageKey  key_to     = CreateStorageKey(Prefix_Account).Add(to);
                    StorageItem storage_to = engine.Snapshot.GetAndChange(key_to, () => new StorageItem(new TState()));
                    TState      state_to   = storage_to.GetInteroperable <TState>();
                    OnBalanceChanging(engine, to, state_to, amount);
                    state_to.Balance += amount;
                }
            }
            PostTransfer(engine, from, to, amount, data, true);
            return(true);
        }
Exemplo n.º 44
0
 public static bool IsVmNullOrByteArray(this StackItem item)
 {
     return item.IsNull || item is ByteString;
 }
Exemplo n.º 45
0
		private void EmitBranchToExit(StackItem item)
		{
			EmitBranch(item.ExitLabel, item.ExceptionBlockNestingLevel);
		}
Exemplo n.º 46
0
        /// <summary>
        /// Navigates to a panel. If a panel already exist with the same panelId instead or creating a new
        /// panel the old panel will be shown and passed the new arguments.
        /// </summary>
        /// <param name="panelType">The type of panel to be created</param>
        /// <param name="panelId">A unique identifier for the panel, the id should be able to differeincae between two panels of the same type</param>
        /// <param name="arguments">Arguments to be sent to the panel</param>
        /// <returns></returns>
        public bool Navigate(Type panelType, string panelId, Dictionary<string, object> arguments = null)
        {
            if (panelType == null)
            {
                throw new Exception("Panel type can't be null!");
            }

            // Make sure we send args along.
            if (arguments == null)
            {
                arguments = new Dictionary<string, object>();
            }

            // Clear this value
            m_finalNavigateHasShownMenu = false;

            bool isExitingPanel = false;
            StackItem navigateFromPanel = null;
            StackItem panelToReduceMemory = null;
            lock (m_panelStack)
            {
                // For now we can only do one animation at a time. So if we are doing something we
                // must ignore this
                if (m_state != State.Idle)
                {
                    return false;
                }

                // The panel we will navigate to
                StackItem navigateToPanel = null;

                // First, check to see if we already have the panel
                foreach (StackItem item in m_panelStack)
                {
                    if(item.Panel.GetType() == panelType && item.Id == panelId)
                    {
                        // We found it.
                        isExitingPanel = true;
                        navigateToPanel = item;
                        break;
                    }
                }

                // If we didn't find it make a new panel.
                if(navigateToPanel == null)
                {
                    navigateToPanel = new StackItem();
                    navigateToPanel.Panel = (IPanel)Activator.CreateInstance(panelType);
                    navigateToPanel.Id = panelId;
                }

                // Check the type
                PanelType newPanelType = GetPanelType(navigateToPanel.Panel);

                // Second, Figure out what panel will be leaving.
                if (m_screenMode == ScreenMode.Single)
                {
                    // If we are in single mode it will be the panel from the top of the stack
                    if (m_panelStack.Count > 0)
                    {
                        navigateFromPanel = m_panelStack.Last();
                    }
                }
                else
                {
                    // If we are in split mode it will be the panel we will replace.
                    // So go through the list backwards and find it.
                    foreach (StackItem item in m_panelStack.Reverse<StackItem>())
                    {
                        // If the are both subreddit panels or both not, we found the panel.
                        if (GetPanelType(item.Panel) == newPanelType)
                        {
                            navigateFromPanel = item;
                            break;
                        }
                    }
                }

                // We need to type of the leaving panel. If the panel is null this
                // is the first navigation of a type, so we will just call it the content panel.
                PanelType navigateFromPanelType = PanelType.ContentPanel;
                if (navigateFromPanel != null)
                {
                    navigateFromPanelType = GetPanelType(navigateFromPanel.Panel);
                }

                // Third, Setup the panel. If it already exits call activate instead of setup.
                if (isExitingPanel)
                {
                    navigateToPanel.Panel.OnPanelPulledToTop(arguments);
                }
                else
                {
                    navigateToPanel.Panel.PanelSetup(this, arguments);
                }

                // Special case! If the UI is already shown then we should just return here.
                if(navigateFromPanel != null && navigateFromPanel.Panel.GetType() == navigateToPanel.Panel.GetType() && navigateFromPanel.Id == navigateToPanel.Id)
                {
                    return true;
                }

                // Last, add the panel to the bottom of the list.
                // Note if this existing the panel will be in the list twice!
                m_panelStack.Add(navigateToPanel);

                // Report the view
                App.BaconMan.TelemetryMan.ReportPageView(navigateToPanel.Panel.GetType().Name);

                // Check if there is someone we should ask to reduce memory
                if(m_panelStack.Count > (c_numberOfHistoryPagesBeforeMemoryReduce + 1))
                {
                    panelToReduceMemory = m_panelStack[m_panelStack.Count - (c_numberOfHistoryPagesBeforeMemoryReduce +1)];

                    // This can only happen in split mode.
                    if(m_screenMode == ScreenMode.Split)
                    {
                        // We need to make sure this panel isn't visible
                        PanelType reducePanelType = GetPanelType(panelToReduceMemory.Panel);
                        for (int count = m_panelStack.Count - 1; count >= 0; count--)
                        {
                            // Find the first panel of this type and make sure it isn't this panel
                            StackItem item = m_panelStack[count];
                            if (GetPanelType(item.Panel) == reducePanelType)
                            {
                                if (item.Id.Equals(panelToReduceMemory.Id) && item.Panel.GetType() == panelToReduceMemory.Panel.GetType())
                                {
                                    // This is the panel thus it is visible. Just null out the var
                                    // and leave it alone.
                                    // #todo! There is a bug here, any panel that is cleared here will never be
                                    // asked to reduce its memory. This isn't a huge deal, but something we might
                                    // want to fix later. This isn't a huge problem because on mobile this will never happen
                                    // and the memory manager will start killing pages if memory gets too high.
                                    panelToReduceMemory = null;
                                }

                                // If the first panel we found wasn't it then this panel
                                // isn't visible.
                                break;
                            }
                        }
                    }
                }

                // Animate the current panel out
                PlayFadeAnimation(newPanelType, navigateFromPanelType, State.FadingOut);
            }

            // If we have a panel tell it we are leaving no under lock.
            if (navigateFromPanel != null)
            {
                FireOnNavigateFrom(navigateFromPanel.Panel);
            }

            // If we have a panel to reduce memory, ask it to.
            if (panelToReduceMemory != null)
            {
                FireOnReduceMemory(panelToReduceMemory.Panel);
            }

            return true;
        }
Exemplo n.º 47
0
 public static bool NotVmInt(this StackItem item)
 {
     return !(item is Integer);
 }