summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-05-21 12:07:06 +0000
committerpaltherr <paltherr@epfl.ch>2003-05-21 12:07:06 +0000
commita766b31106fb883025d966e9dbe725c385ed22ad (patch)
tree67f59d8bcf35eae7d493d2052fec62e803d7dbf0
parent7eda0b9cfc5be94fc96272e8a72c31b5feb67c9f (diff)
downloadscala-a766b31106fb883025d966e9dbe725c385ed22ad.tar.gz
scala-a766b31106fb883025d966e9dbe725c385ed22ad.tar.bz2
scala-a766b31106fb883025d966e9dbe725c385ed22ad.zip
- Fixed computation of scala stack trace
-rw-r--r--sources/scala/tools/scalai/Evaluator.java15
-rw-r--r--sources/scala/tools/scalai/EvaluatorException.java76
2 files changed, 45 insertions, 46 deletions
diff --git a/sources/scala/tools/scalai/Evaluator.java b/sources/scala/tools/scalai/Evaluator.java
index 1d19637116..76645a6347 100644
--- a/sources/scala/tools/scalai/Evaluator.java
+++ b/sources/scala/tools/scalai/Evaluator.java
@@ -27,13 +27,13 @@ public class Evaluator {
// Private Classes
// !!! remove ?
+ // !!! is it correct to extend EvaluatorException?
private static class LabelException extends EvaluatorException {
public final Symbol symbol;
public final Object[] args;
public LabelException(Symbol symbol, Object[] args) {
- super(null);
this.symbol = symbol;
this.args = args;
}
@@ -62,15 +62,15 @@ public class Evaluator {
//########################################################################
// Private Fields
+ private final EvaluatorException trace;
private EvaluationStack stack;
- private EvaluatorException trace;
//########################################################################
// Public Constructors
public Evaluator() {
+ this.trace = new EvaluatorException();
this.stack = null;
- this.trace = null;
}
//########################################################################
@@ -154,7 +154,7 @@ public class Evaluator {
try {
return invoke(object, function, args);
} catch (EvaluatorException exception) {
- if (stack.symbol != null) exception.addScalaCall(stack.symbol, pos); // !!! remove test
+ exception.addScalaCall(stack.symbol, pos);
throw exception;
}
@@ -285,6 +285,8 @@ public class Evaluator {
private Object invoke(Object object, Constructor constructor,Object[]args){
try {
return constructor.newInstance(args);
+ } catch (StackOverflowError exception) {
+ return throw_(exception);
} catch (ExceptionInInitializerError exception) {
return throw_(exception);
} catch (InvocationTargetException exception) {
@@ -310,6 +312,8 @@ public class Evaluator {
private Object invoke(Object object, Method method, Object[] args) {
try {
return method.invoke(object, args);
+ } catch (StackOverflowError exception) {
+ return throw_(exception);
} catch (NullPointerException exception) {
return throw_(exception);
} catch (ExceptionInInitializerError exception) {
@@ -437,8 +441,7 @@ public class Evaluator {
exception instanceof ExceptionInInitializerError ||
exception instanceof InvocationTargetException))
exception = exception.getCause();
- if (trace == null || trace.getCause() != exception)
- trace = new EvaluatorException(exception);
+ if (trace.getCause() != exception) trace.reset(exception);
trace.addScalaLeavePoint();
throw trace;
}
diff --git a/sources/scala/tools/scalai/EvaluatorException.java b/sources/scala/tools/scalai/EvaluatorException.java
index b262eac367..e6049deff5 100644
--- a/sources/scala/tools/scalai/EvaluatorException.java
+++ b/sources/scala/tools/scalai/EvaluatorException.java
@@ -21,24 +21,33 @@ public class EvaluatorException extends RuntimeException {
//########################################################################
// Private Fields
- private final StackTraceElement[] trace;
private final List stack;
- private int stop;
+ private Throwable cause;
+ private StackTraceElement[] trace;
+ private int entry;
//########################################################################
// Public Constructors
- public EvaluatorException(Throwable cause) {
- super(cause);
- this.trace = getTraceOf(cause);
+ public EvaluatorException() {
this.stack = new ArrayList();
- this.stop = trace.length;
}
//########################################################################
// Public Methods
+ public void reset(Throwable cause) {
+ this.stack.clear();
+ this.cause = cause;
+ this.trace = cause.getStackTrace();
+ this.entry = 0;
+ }
+
+ public Throwable getCause() {
+ return cause;
+ }
+
public void addScalaCall(Symbol method, int pos) {
StringBuffer buffer = new StringBuffer();
buffer.append(method.owner().fullNameString());
@@ -49,37 +58,34 @@ public class EvaluatorException extends RuntimeException {
buffer.append(':');
buffer.append(Position.line(pos));
buffer.append(")");
- stack.add(buffer.toString());
+ stack.add(buffer);
}
public void addScalaEntryPoint() {
- StackTraceElement[] current = getCurrentTrace();
- // find entry point
- int length = Math.min(trace.length, current.length);
- int entry = 0;
- while (entry < length && trace[entry].equals(current[entry])) entry++;
- assert entry <= stop : "entry = " + entry + " > " + stop + " = stop";
+ // save new stack trace elements
+ this.trace = getCurrentTrace();
+ // skip calls through interpreter
+ while (traceAtStartsWith(entry, "scalai.")) entry++;
// skip calls through proxy class
- while (entry > 0 && traceAtStartsWith(entry - 1, "$Proxy")) entry--;
- // save new trace end
- stop = entry;
+ while (traceAtStartsWith(entry, "$Proxy")) entry++;
}
public void addScalaLeavePoint() {
- StackTraceElement[] current = getCurrentTrace();
// find leave point
- int length = Math.min(trace.length, current.length);
- int leave = 0;
- while (leave < length && trace[leave].equals(current[leave])) leave++;
- // skip calls through interpreter & reflection
- int start = leave;
- while (traceAtStartsWith(start, "scalai.")) start++;
- while (traceAtStartsWith(start, "java.lang.reflect.")) start++;
- while (traceAtStartsWith(start, "sun.reflect.")) start++;
+ int leave = entry;
+ while (leave < trace.length && !traceAtStartsWith(leave, "scalai."))
+ leave++;
+ if (leave < trace.length) {
+ // skip calls through reflection
+ while (traceAtStartsWith(leave - 1, "java.lang.reflect.")) leave--;
+ while (traceAtStartsWith(leave - 1, "sun.reflect.")) leave--;
+ }
// complete stack with java trace
- for (int i = stop - 1; start <= i; i--) stack.add(trace[i]);
- // save new trace end
- stop = leave;
+ for (int i = entry; i < leave; i++) stack.add(trace[i]);
+ if (leave == trace.length) stack.add("...");
+ // free memory
+ this.trace = null;
+ this.entry = 0;
}
public Object[] getScalaStackTrace() {
@@ -100,22 +106,12 @@ public class EvaluatorException extends RuntimeException {
// Private Methods
private boolean traceAtStartsWith(int index, String prefix) {
- if (trace.length <= index) return false;
+ if (index < 0 || trace.length <= index) return false;
return trace[index].getClassName().startsWith(prefix);
}
private StackTraceElement[] getCurrentTrace() {
- return getTraceOf(new Error());
- }
-
- private StackTraceElement[] getTraceOf(Throwable exception) {
- StackTraceElement[] trace = exception.getStackTrace();
- for (int i = 0; i < trace.length / 2; i++) {
- StackTraceElement element = trace[i];
- trace[i] = trace[trace.length - i - 1];
- trace[trace.length - i - 1] = element;
- }
- return trace;
+ return new RuntimeException().getStackTrace();
}
//########################################################################