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); }
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++; }
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); }
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); }
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); }
/// <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); }
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"); }
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); }
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); }
/// <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; }
/// <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 < 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" }); }
private void Test_Notify2(object sender, NotifyEventArgs e) { item = null; }
public void Clear() { top = null; count = 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; }
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); }
/// <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" }); }
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; } } }
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()); }
/// <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 < 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 }); }
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)); }
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); }
/// <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(); }
public static BigInteger? ToBigInteger(this StackItem value) => value == null || value is Null ? (BigInteger?)null : value.GetInteger();
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); }
/// <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)); }
public static bool NotVmByteArray(this StackItem item) { return !(item is ByteString); }
void IEnumerator.Reset() { cur = first; }
public static bool NotVmNull(this StackItem item) { return !(item.IsNull); }
public void Push(T item) { top = new StackItem(top, item); count++; }
/// <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(); }
public override bool Equals(StackItem other) => true;
public Worker(StackItem stackItem) { this._stackItem = stackItem; }
private void Test_Notify1(object sender, NotifyEventArgs e) { item = e.State; }
private void EmitBranchToCondition(StackItem item) { EmitBranch(item.ConditionLabel, item.ExceptionBlockNestingLevel); }
public virtual void FromStackItem(StackItem stackItem) { Balance = ((Struct)stackItem)[0].GetInteger(); }
void IInteroperable.FromStackItem(StackItem stackItem) { throw new NotSupportedException(); }
/// <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; }
public NotifyEventArgs(IVerifiable container, UInt160 script_hash, StackItem state) { this.ScriptContainer = container; this.ScriptHash = script_hash; this.State = state; }
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); }
public static bool IsVmNullOrByteArray(this StackItem item) { return item.IsNull || item is ByteString; }
private void EmitBranchToExit(StackItem item) { EmitBranch(item.ExitLabel, item.ExceptionBlockNestingLevel); }
/// <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; }
public static bool NotVmInt(this StackItem item) { return !(item is Integer); }