PageRenderTime 40ms CodeModel.GetById 30ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2-build270707/src/edu/vub/at/eval/InvocationStack.java

http://ambienttalk.googlecode.com/
Java | 145 lines | 79 code | 19 blank | 47 comment | 4 complexity | 9f6ea1af94bca03aa140c8a82f061aba MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * InvocationStack.java created on 10-okt-2006 at 14:15:49
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.eval;
 29
 30import edu.vub.at.exceptions.InterpreterException;
 31import edu.vub.at.objects.ATClosure;
 32import edu.vub.at.objects.ATMessage;
 33import edu.vub.at.objects.ATObject;
 34import edu.vub.at.objects.ATTable;
 35import edu.vub.at.objects.grammar.ATExpression;
 36
 37import java.io.PrintStream;
 38import java.io.PrintWriter;
 39import java.io.Serializable;
 40import java.util.ListIterator;
 41import java.util.Stack;
 42
 43/**
 44 * An InvocationStack instance represents the stack of method invocations and function applications
 45 * that are currently activated in an actor's thread. It is mainly used for debugging purposes
 46 * (e.g. generating stack trace information)
 47 * 
 48 * @author tvc
 49 */
 50public final class InvocationStack implements Cloneable, Serializable {
 51
 52	/**
 53	 * A thread-local variable is used to assign a unique invocation stack to
 54	 * each separate actor. Each actor that invokes the getInvocationStack()
 55	 * method receives its own separate copy of the invocation stack
 56	 */
 57	private static final ThreadLocal _INVOCATION_STACK_ = new ThreadLocal() {
 58	    protected synchronized Object initialValue() {
 59	        return new InvocationStack();
 60	    }
 61	};
 62	
 63	public static final InvocationStack getInvocationStack() {
 64		return (InvocationStack) _INVOCATION_STACK_.get();
 65	}
 66	
 67	public static final InvocationStack captureInvocationStack() {
 68		return (InvocationStack) getInvocationStack().clone();
 69	}
 70	
 71	private static class InvocationFrame implements Serializable {
 72		public final ATExpression invocation;
 73		public final ATObject receiver;
 74		public final ATTable arguments;
 75		
 76		public InvocationFrame(ATExpression inv, ATObject rcvr, ATTable args) {
 77			invocation = inv;
 78			receiver = rcvr;
 79			arguments = args;
 80		}
 81	}
 82	
 83	private final Stack invocationStack_;
 84	
 85	private InvocationStack() {
 86		invocationStack_ = new Stack();
 87	}
 88	
 89	private InvocationStack(Stack initstack) {
 90		invocationStack_ = initstack;
 91	}
 92	
 93	public void methodInvoked(ATExpression methodInvocation, ATObject receiver, ATTable args) throws InterpreterException {
 94		invocationStack_.push(new InvocationFrame(methodInvocation, receiver, args));
 95	}
 96	
 97	public void functionCalled(ATExpression funCall, ATClosure fun, ATTable evaluatedArgs) {
 98		invocationStack_.push(new InvocationFrame(funCall, fun, evaluatedArgs));
 99	}
100	
101	/**
102	 * @param result if null, the method invocation was aborted via an exception
103	 */
104	public void methodReturned(ATObject result) {
105		invocationStack_.pop();
106	}
107	
108	/**
109	 * @param result if null, the function call was aborted via an exception
110	 */
111	public void funcallReturned(ATObject result) {
112		invocationStack_.pop();
113	}
114	
115	public void printStackTrace(PrintStream s) {
116		if(!invocationStack_.isEmpty()) {
117			s.println("origin:");
118			// iterator loops from bottom to top by default
119			ListIterator i = invocationStack_.listIterator();
120			while (i.hasNext()) { i.next(); } // skip to last element
121			while(i.hasPrevious()) { // traverse stack top to bottom
122				InvocationFrame frame = (InvocationFrame) i.previous();
123				s.println("at "+Evaluator.toString(frame.invocation));
124			}
125		}
126	}
127	
128	public void printStackTrace(PrintWriter s) {
129		if(!invocationStack_.isEmpty()) {
130			s.println("origin:");
131			// iterator loops from bottom to top by default
132			ListIterator i = invocationStack_.listIterator();
133			while (i.hasNext()) { i.next(); } // skip to last element
134			while(i.hasPrevious()) { // traverse stack top to bottom
135				InvocationFrame frame = (InvocationFrame) i.previous();
136				s.println("at "+Evaluator.toString(frame.invocation));
137			}
138		}
139	}
140	
141	public Object clone() {
142		return new InvocationStack((Stack) invocationStack_.clone());
143	}
144	
145}