package nl.tudelft.simulation.dsol.interpreter; import java.util.ArrayList; import java.util.Arrays; /** * Each frame (par 2.6) contains a * last-in-first-out (LIFO) stack known as its operand stack. The maximum depth of the operand stack of a frame is determined at * compile time and is supplied along with the code for the method associated with the frame * (par. 4.7.3). Where it is clear by * context, we will sometimes refer to the operand stack of the current frame as simply the operand stack. *
* The operand stack is empty when the frame that contains it is created. The Java virtual machine supplies instructions to load * constants or values from local variables or fields onto the operand stack. Other Java virtual machine instructions take * operands from the operand stack, operate on them, and push the result back onto the operand stack. The operand stack is also * used to prepare parameters to be passed to methods and to receive method results. *
** For example, the IADD instruction adds two int values together. It requires that the int values to be added be the top two * values of the operand stack, pushed there by previous instructions. Both of the int values are popped from the operand stack. * They are added, and their sum is pushed back onto the operand stack. Subcomputations may be nested on the operand stack, * resulting in values that can be used by the encompassing computation. *
** Copyright (c) 2002-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See * for project information https://simulation.tudelft.nl. The DSOL * project is distributed under a three-clause BSD-style license, which can be found at * * https://simulation.tudelft.nl/dsol/3.0/license.html. *
* @author Peter Jacobs * @author Alexander Verbraeck * @since 1.5 */ public class OperandStack implements Cloneable { /** the actual pointer. */ private int pointer = 0; /** the stackContent. */ private Object[] stack = null; /** * constructs a new OperandStack. * @param initialSize int; the stackSize */ public OperandStack(final int initialSize) { super(); this.stack = new Object[initialSize]; } /** * clears the operand stack. */ public void clear() { this.pointer = 0; } /** * is the OperandStack empty. * @return whether the operandStack is empty */ public boolean isEmpty() { return this.pointer == 0; } /** * pops the first object from the operandstack. * @return the top object from the stack */ public Object pop() { synchronized (this.stack) { return this.stack[--this.pointer]; } } /** * peeks the first object from the stack. This is a pop without remove. * @return Object the first object */ public Object peek() { synchronized (this.stack) { return this.stack[this.pointer - 1]; } } /** * peeks the depth-object from the stack. * @param depth int; the depth-object * @return the depth object. */ public Object peek(final int depth) { synchronized (this.stack) { return this.stack[this.pointer - (depth + 1)]; } } /** * pushes object on the stack. * @param object Object; the object to be pushed to the stack */ public void push(final Object object) { synchronized (this.stack) { try { this.stack[this.pointer++] = object; } catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) { ArrayList