PageRenderTime 18ms CodeModel.GetById 11ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/reactive-pattern-matching/src/edu/vub/at/eval/InvocationStack.java

http://ambienttalk.googlecode.com/
Java | 144 lines | 78 code | 19 blank | 47 comment | 4 complexity | 2987e02d08008595b322efac700129fa 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.ATObject;
 33import edu.vub.at.objects.ATTable;
 34import edu.vub.at.objects.grammar.ATExpression;
 35
 36import java.io.PrintStream;
 37import java.io.PrintWriter;
 38import java.io.Serializable;
 39import java.util.ListIterator;
 40import java.util.Stack;
 41
 42/**
 43 * An InvocationStack instance represents the stack of method invocations and function applications
 44 * that are currently activated in an actor's thread. It is mainly used for debugging purposes
 45 * (e.g. generating stack trace information)
 46 * 
 47 * @author tvc
 48 */
 49public final class InvocationStack implements Cloneable, Serializable {
 50
 51	/**
 52	 * A thread-local variable is used to assign a unique invocation stack to
 53	 * each separate actor. Each actor that invokes the getInvocationStack()
 54	 * method receives its own separate copy of the invocation stack
 55	 */
 56	private static final ThreadLocal _INVOCATION_STACK_ = new ThreadLocal() {
 57	    protected synchronized Object initialValue() {
 58	        return new InvocationStack();
 59	    }
 60	};
 61	
 62	public static final InvocationStack getInvocationStack() {
 63		return (InvocationStack) _INVOCATION_STACK_.get();
 64	}
 65	
 66	public static final InvocationStack captureInvocationStack() {
 67		return (InvocationStack) getInvocationStack().clone();
 68	}
 69	
 70	private static class InvocationFrame implements Serializable {
 71		public final ATExpression invocation;
 72		public final ATObject receiver;
 73		public final ATTable arguments;
 74		
 75		public InvocationFrame(ATExpression inv, ATObject rcvr, ATTable args) {
 76			invocation = inv;
 77			receiver = rcvr;
 78			arguments = args;
 79		}
 80	}
 81	
 82	private final Stack invocationStack_;
 83	
 84	private InvocationStack() {
 85		invocationStack_ = new Stack();
 86	}
 87	
 88	private InvocationStack(Stack initstack) {
 89		invocationStack_ = initstack;
 90	}
 91	
 92	public void methodInvoked(ATExpression methodInvocation, ATObject receiver, ATTable args) throws InterpreterException {
 93		invocationStack_.push(new InvocationFrame(methodInvocation, receiver, args));
 94	}
 95	
 96	public void functionCalled(ATExpression funCall, ATClosure fun, ATTable evaluatedArgs) {
 97		invocationStack_.push(new InvocationFrame(funCall, fun, evaluatedArgs));
 98	}
 99	
100	/**
101	 * @param result if null, the method invocation was aborted via an exception
102	 */
103	public void methodReturned(ATObject result) {
104		invocationStack_.pop();
105	}
106	
107	/**
108	 * @param result if null, the function call was aborted via an exception
109	 */
110	public void funcallReturned(ATObject result) {
111		invocationStack_.pop();
112	}
113	
114	public void printStackTrace(PrintStream s) {
115		if(!invocationStack_.isEmpty()) {
116			s.println("origin:");
117			// iterator loops from bottom to top by default
118			ListIterator i = invocationStack_.listIterator();
119			while (i.hasNext()) { i.next(); } // skip to last element
120			while(i.hasPrevious()) { // traverse stack top to bottom
121				InvocationFrame frame = (InvocationFrame) i.previous();
122				s.println("at "+Evaluator.toString(frame.invocation));
123			}
124		}
125	}
126	
127	public void printStackTrace(PrintWriter s) {
128		if(!invocationStack_.isEmpty()) {
129			s.println("origin:");
130			// iterator loops from bottom to top by default
131			ListIterator i = invocationStack_.listIterator();
132			while (i.hasNext()) { i.next(); } // skip to last element
133			while(i.hasPrevious()) { // traverse stack top to bottom
134				InvocationFrame frame = (InvocationFrame) i.previous();
135				s.println("at "+Evaluator.toString(frame.invocation));
136			}
137		}
138	}
139	
140	public Object clone() {
141		return new InvocationStack((Stack) invocationStack_.clone());
142	}
143	
144}