src/jdk/nashorn/internal/objects/NativeError.java

Print this page

        

@@ -142,10 +142,38 @@
         Global.checkObject(self);
         return ECMAException.printStackTrace((ScriptObject)self);
     }
 
     /**
+     * Nashorn extension: Error.prototype.getStackTrace()
+     * "stack" property is an array typed value containing {@link StackTraceElement}
+     * objects of JavaScript stack frames.
+     *
+     * @param self  self reference
+     *
+     * @return      stack trace as a script array.
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getStackTrace(final Object self) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        if (sobj.has(STACK)) {
+            return sobj.get(STACK);
+        }
+
+        final Object exception = ECMAException.getException(sobj);
+        Object[] res;
+        if (exception instanceof Throwable) {
+            res = getScriptFrames((Throwable)exception);
+        } else {
+            res = ScriptRuntime.EMPTY_ARRAY;
+        }
+
+        return new NativeArray(res);
+    }
+
+    /**
      * Nashorn extension: Error.prototype.lineNumber
      *
      * @param self self reference
      *
      * @return line number from which error was thrown

@@ -227,12 +255,12 @@
         return value;
     }
 
     /**
      * Nashorn extension: Error.prototype.stack
-     * "stack" property is an array typed value containing {@link StackTraceElement}
-     * objects of JavaScript stack frames.
+     * "stack" property is a string typed value containing JavaScript stack frames.
+     * Each frame information is separated bv "\n" character.
      *
      * @param self  self reference
      *
      * @return      value of "stack" property
      */

@@ -242,31 +270,32 @@
         if (sobj.has(STACK)) {
             return sobj.get(STACK);
         }
 
         final Object exception = ECMAException.getException(sobj);
-        Object[] res;
+        final StringBuilder buf = new StringBuilder();
         if (exception instanceof Throwable) {
-            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()));
+            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);
                 }
-            }
-            res = filtered.toArray();
+            return buf.toString();
         } else {
-            res = ScriptRuntime.EMPTY_ARRAY;
+            return "";
         }
-
-        return new NativeArray(res);
     }
 
     /**
      * Nashorn extension
      * Accessed from {@link Global} while setting up the Error.prototype

@@ -333,6 +362,23 @@
             return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types));
         } catch (final NoSuchMethodException | IllegalAccessException e) {
             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();
+    }
 }