All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dragome.callbackevictor.enhancers.Stack Maven / Gradle / Ivy

There is a newer version: 0.96-beta4
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.dragome.callbackevictor.enhancers;

import java.io.Serializable;

import com.dragome.commons.ProxyRelatedInvocationHandler;

/**
 * Stack to store the frame information along the invocation trace.
 */
public class Stack implements Serializable
{

	private static final long serialVersionUID= 2L;

	private int[] istack;
	private float[] fstack;
	private double[] dstack;
	private long[] lstack;
	private Object[] ostack;
	private Object[] rstack;
	private int iTop, fTop, dTop, lTop, oTop, rTop;
	protected Runnable runnable;

	public Stack(Runnable pRunnable)
	{
		istack= new int[10];
		lstack= new long[5];
		dstack= new double[5];
		fstack= new float[5];
		ostack= new Object[10];
		rstack= new Object[5];
		runnable= pRunnable;
	}

	public Stack(final Stack pParent)
	{
		istack= new int[pParent.istack.length];
		lstack= new long[pParent.lstack.length];
		dstack= new double[pParent.dstack.length];
		fstack= new float[pParent.fstack.length];
		ostack= new Object[pParent.ostack.length];
		rstack= new Object[pParent.rstack.length];
		iTop= pParent.iTop;
		fTop= pParent.fTop;
		dTop= pParent.dTop;
		lTop= pParent.lTop;
		oTop= pParent.oTop;
		rTop= pParent.rTop;
		System.arraycopy(pParent.istack, 0, istack, 0, iTop);
		System.arraycopy(pParent.fstack, 0, fstack, 0, fTop);
		System.arraycopy(pParent.dstack, 0, dstack, 0, dTop);
		System.arraycopy(pParent.lstack, 0, lstack, 0, lTop);
		System.arraycopy(pParent.ostack, 0, ostack, 0, oTop);
		System.arraycopy(pParent.rstack, 0, rstack, 0, rTop);
		runnable= pParent.runnable;
	}

	public boolean hasDouble()
	{
		return dTop > 0;
	}

	public double popDouble()
	{
		if (dTop == 0)
		{
			throw new EmptyStackException("pop double");
		}

		final double d= dstack[--dTop];
		return d;
	}

	public boolean hasFloat()
	{
		return fTop > 0;
	}

	public float popFloat()
	{
		if (fTop == 0)
		{
			throw new EmptyStackException("pop float");
		}

		final float f= fstack[--fTop];
		return f;
	}

	public boolean hasInt()
	{
		return iTop > 0;
	}

	public int popInt()
	{
		if (iTop == 0)
		{
			throw new EmptyStackException("pop int");
		}

		final int i= istack[--iTop];
		return i;
	}

	public boolean hasLong()
	{
		return lTop > 0;
	}

	public long popLong()
	{
		if (lTop == 0)
		{
			throw new EmptyStackException("pop long");
		}

		final long l= lstack[--lTop];
		return l;
	}

	public boolean hasObject()
	{
		return oTop > 0;
	}

	public Object popObject()
	{
		if (oTop == 0)
		{
			throw new EmptyStackException("pop object");
		}

		final Object o= ostack[--oTop];
		ostack[oTop]= null; // avoid unnecessary reference to object

		return o;
	}

	public boolean hasReference()
	{
		return rTop > 0;
	}

	public Object popReference()
	{
		if (rTop == 0)
		{
			throw new EmptyStackException("pop reference");
		}

		Object o= rstack[--rTop];
		rstack[rTop]= null; // avoid unnecessary reference to object

		//TODO arreglar este parche feo
		if (o instanceof ProxyRelatedInvocationHandler)
		{
			ProxyRelatedInvocationHandler proxyRelatedInvocationHandler= (ProxyRelatedInvocationHandler) o;

			if (!proxyRelatedInvocationHandler.isInvoked())
				o= proxyRelatedInvocationHandler.getProxy();
			
			proxyRelatedInvocationHandler.setInvoked(existsIn(rstack, proxyRelatedInvocationHandler));
		}

		return o;
	}

	private boolean existsIn(Object[] stack, Object o)
	{
		for (Object object : stack)
			if (object == o)
				return true;

		return false;
	}

	public void pushDouble(double d)
	{

		if (dTop == dstack.length)
		{
			double[] hlp= new double[Math.max(8, dstack.length * 2)];
			System.arraycopy(dstack, 0, hlp, 0, dstack.length);
			dstack= hlp;
		}
		dstack[dTop++]= d;
	}

	public void pushFloat(float f)
	{

		if (fTop == fstack.length)
		{
			float[] hlp= new float[Math.max(8, fstack.length * 2)];
			System.arraycopy(fstack, 0, hlp, 0, fstack.length);
			fstack= hlp;
		}
		fstack[fTop++]= f;
	}

	public void pushInt(int i)
	{

		if (iTop == istack.length)
		{
			int[] hlp= new int[Math.max(8, istack.length * 2)];
			System.arraycopy(istack, 0, hlp, 0, istack.length);
			istack= hlp;
		}
		istack[iTop++]= i;
	}

	public void pushLong(long l)
	{

		if (lTop == lstack.length)
		{
			long[] hlp= new long[Math.max(8, lstack.length * 2)];
			System.arraycopy(lstack, 0, hlp, 0, lstack.length);
			lstack= hlp;
		}
		lstack[lTop++]= l;
	}

	public void pushObject(Object o)
	{
		//		if (o instanceof ProxyRelatedInvocationHandler)
		//		{
		//			ProxyRelatedInvocationHandler proxyRelatedInvocationHandler= (ProxyRelatedInvocationHandler) o;
		//			o= proxyRelatedInvocationHandler.getProxy();
		//		}

		if (oTop == ostack.length)
		{
			Object[] hlp= new Object[Math.max(8, ostack.length * 2)];
			System.arraycopy(ostack, 0, hlp, 0, ostack.length);
			ostack= hlp;
		}
		ostack[oTop++]= o;
	}

	public void replaceReference(Object o)
	{
		popReference();
		pushReference(o);
	}

	public void pushReference(Object o)
	{
		//		if (o instanceof ProxyRelatedInvocationHandler)
		//		{
		//			ProxyRelatedInvocationHandler proxyRelatedInvocationHandler= (ProxyRelatedInvocationHandler) o;
		//			o= proxyRelatedInvocationHandler.getProxy();
		//		}

		if (rTop == rstack.length)
		{
			Object[] hlp= new Object[Math.max(8, rstack.length * 2)];
			System.arraycopy(rstack, 0, hlp, 0, rstack.length);
			rstack= hlp;
		}
		rstack[rTop++]= o;
	}

	public boolean isSerializable()
	{
		for (int i= 0; i < rTop; i++)
		{
			final Object r= rstack[i];
			if (!(r instanceof Serializable))
			{
				return false;
			}
		}
		for (int i= 0; i < oTop; i++)
		{
			final Object o= ostack[i];
			if (!(o instanceof Serializable))
			{
				return false;
			}
		}
		return true;
	}

	public boolean isEmpty()
	{
		return iTop == 0 && lTop == 0 && dTop == 0 && fTop == 0 && oTop == 0 && rTop == 0;
	}

	private String getStats()
	{
		final StringBuffer sb= new StringBuffer();
		sb.append("i[").append(iTop).append("],");
		sb.append("l[").append(lTop).append("],");
		sb.append("d[").append(dTop).append("],");
		sb.append("f[").append(fTop).append("],");
		sb.append("o[").append(oTop).append("],");
		sb.append("r[").append(rTop).append("]");
		return sb.toString();
	}

	//    private String getContent() {
	//        final StringBuffer sb = new StringBuffer();
	//        sb.append("i[").append(iTop).append("]\n");
	//        sb.append("l[").append(lTop).append("]\n");
	//        sb.append("d[").append(dTop).append("]\n");
	//        sb.append("f[").append(fTop).append("]\n");
	//        sb.append("o[").append(oTop).append("]\n");
	//        for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy