--- a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java Wed Jun 26 15:40:52 2013 +0200
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java Wed Jun 26 19:42:17 2013 +0530
@@ -25,6 +25,9 @@
package jdk.nashorn.api.scripting;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.runtime.ECMAErrors;
/**
@@ -136,4 +139,52 @@
return column;
}
+ /**
+ * Returns array javascript stack frames from the given exception object.
+ *
+ * @param exception exception from which stack frames are retrieved and filtered
+ * @return array of javascript stack frames
+ */
+ public static StackTraceElement[] getScriptFrames(final Throwable exception) {
+ final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
+ final List<StackTraceElement> filtered = new ArrayList<>();
+ for (final StackTraceElement st : frames) {
+ if (ECMAErrors.isScriptFrame(st)) {
+ final String className = "<" + st.getFileName() + ">";
+ String methodName = st.getMethodName();
+ if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
+ methodName = "<program>";
+ }
+ filtered.add(new StackTraceElement(className, methodName,
+ st.getFileName(), st.getLineNumber()));
+ }
+ }
+ return filtered.toArray(new StackTraceElement[filtered.size()]);
+ }
+
+ /**
+ * Return a formatted script stack trace string with frames information separated by '\n'
+ *
+ * @param exception exception for which script stack string is returned
+ * @return formatted stack trace string
+ */
+ public static String getScriptStackString(final Throwable exception) {
+ final StringBuilder buf = new StringBuilder();
+ final StackTraceElement[] frames = getScriptFrames((Throwable)exception);
+ for (final StackTraceElement st : frames) {
+ buf.append(st.getMethodName());
+ buf.append(" @ ");
+ buf.append(st.getFileName());
+ buf.append(':');
+ buf.append(st.getLineNumber());
+ buf.append('\n');
+ }
+ final int len = buf.length();
+ // remove trailing '\n'
+ if (len > 0) {
+ assert buf.charAt(len - 1) == '\n';
+ buf.deleteCharAt(len - 1);
+ }
+ return buf.toString();
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java Wed Jun 26 15:40:52 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java Wed Jun 26 19:42:17 2013 +0530
@@ -32,6 +32,7 @@
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
+import jdk.nashorn.api.scripting.NashornException;
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -119,6 +120,20 @@
}
/**
+ * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
+ *
+ * @param self self reference
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object captureStackTrace(final Object self, final Object errorObj) {
+ Global.checkObject(errorObj);
+ final ScriptObject sobj = (ScriptObject)errorObj;
+ final ECMAException exp = new ECMAException(sobj, null);
+ sobj.set("stack", NashornException.getScriptStackString(exp), false);
+ return UNDEFINED;
+ }
+
+ /**
* Nashorn extension: Error.dumpStack
* dumps the stack of the current thread.
*
@@ -163,7 +178,7 @@
final Object exception = ECMAException.getException(sobj);
Object[] res;
if (exception instanceof Throwable) {
- res = getScriptFrames((Throwable)exception);
+ res = NashornException.getScriptFrames((Throwable)exception);
} else {
res = ScriptRuntime.EMPTY_ARRAY;
}
@@ -272,25 +287,8 @@
}
final Object exception = ECMAException.getException(sobj);
- final StringBuilder buf = new StringBuilder();
if (exception instanceof Throwable) {
- final Object[] frames = getScriptFrames((Throwable)exception);
- for (final Object fr : frames) {
- final StackTraceElement st = (StackTraceElement)fr;
- buf.append(st.getMethodName());
- buf.append(" @ ");
- buf.append(st.getFileName());
- buf.append(':');
- buf.append(st.getLineNumber());
- buf.append('\n');
- }
- final int len = buf.length();
- // remove trailing '\n'
- if (len > 0) {
- assert buf.charAt(len - 1) == '\n';
- buf.deleteCharAt(len - 1);
- }
- return buf.toString();
+ return NashornException.getScriptStackString((Throwable)exception);
} else {
return "";
}
@@ -364,21 +362,4 @@
throw new MethodHandleFactory.LookupException(e);
}
}
-
- private static Object[] getScriptFrames(final Throwable exception) {
- final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
- final List<StackTraceElement> filtered = new ArrayList<>();
- for (final StackTraceElement st : frames) {
- if (ECMAErrors.isScriptFrame(st)) {
- final String className = "<" + st.getFileName() + ">";
- String methodName = st.getMethodName();
- if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
- methodName = "<program>";
- }
- filtered.add(new StackTraceElement(className, methodName,
- st.getFileName(), st.getLineNumber()));
- }
- }
- return filtered.toArray();
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8014781.js Wed Jun 26 19:42:17 2013 +0530
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8014781: support Error.captureStackTrace
+ *
+ * @test
+ * @run
+ */
+
+function MyError() {
+ Error.captureStackTrace(this);
+}
+
+function func() {
+ return new MyError();
+}
+
+var e = func();
+print(e.stack.replace(/\\/g, '/'));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8014781.js.EXPECTED Wed Jun 26 19:42:17 2013 +0530
@@ -0,0 +1,3 @@
+MyError @ test/script/basic/JDK-8014781.js:32
+func @ test/script/basic/JDK-8014781.js:36
+<program> @ test/script/basic/JDK-8014781.js:39