--- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ECMAException.java 2020-04-15 18:49:47.000000000 +0530 +++ /dev/null 2020-04-15 18:49:47.000000000 +0530 @@ -1,298 +0,0 @@ -/* - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.nashorn.internal.runtime; - -import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; -import static jdk.nashorn.internal.codegen.CompilerConstants.virtualField; -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - -import javax.script.ScriptException; -import jdk.nashorn.api.scripting.NashornException; -import jdk.nashorn.internal.codegen.CompilerConstants.Call; -import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess; - -/** - * Exception used to implement ECMAScript "throw" from scripts. The actual thrown - * object from script need not be a Java exception and so it is wrapped as an - * instance field called "thrown" here. This exception class is also used to - * represent ECMA errors thrown from runtime code (for example, TypeError, - * ReferenceError thrown from Nashorn engine runtime). - */ -@SuppressWarnings("serial") -public final class ECMAException extends NashornException { - /** - * Method handle pointing to the constructor {@link ECMAException#create(Object, String, int, int)}, - */ - public static final Call CREATE = staticCallNoLookup(ECMAException.class, "create", ECMAException.class, Object.class, String.class, int.class, int.class); - - /** Field handle to the{@link ECMAException#thrown} field, so that it can be accessed from generated code */ - public static final FieldAccess THROWN = virtualField(ECMAException.class, "thrown", Object.class); - - private static final String EXCEPTION_PROPERTY = "nashornException"; - - /** Object thrown. */ - public final Object thrown; - - /** - * Constructor. Called from the factory method 'create'. - * - * @param thrown object to be thrown - * @param fileName script file name - * @param line line number of throw - * @param column column number of throw - */ - private ECMAException(final Object thrown, final String fileName, final int line, final int column) { - super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column); - this.thrown = thrown; - setExceptionToThrown(); - } - - /** - * Constructor. This is called from the runtime code. - * - * @param thrown object to be thrown - * @param cause Java exception that triggered this throw - */ - public ECMAException(final Object thrown, final Throwable cause) { - super(ScriptRuntime.safeToString(thrown), cause); - this.thrown = thrown; - setExceptionToThrown(); - } - - /** - * Factory method to retrieve the underlying exception or create an exception. - * This method is called from the generated code. - * - * @param thrown object to be thrown - * @param fileName script file name - * @param line line number of throw - * @param column column number of throw - * @return ECMAException object - */ - public static ECMAException create(final Object thrown, final String fileName, final int line, final int column) { - // If thrown object is an Error or sub-object like TypeError, then - // an ECMAException object has been already initialized at constructor. - if (thrown instanceof ScriptObject) { - final Object exception = getException((ScriptObject)thrown); - if (exception instanceof ECMAException) { - final ECMAException ee = (ECMAException)exception; - // Make sure exception has correct thrown reference because that's what will end up getting caught. - if (ee.getThrown() == thrown) { - // copy over file name, line number and column number. - ee.setFileName(fileName); - ee.setLineNumber(line); - ee.setColumnNumber(column); - return ee; - } - } - } - - return new ECMAException(thrown, fileName, line, column); - } - - /** - * Get the thrown object - * @return thrown object - */ - @Override - public Object getThrown() { - return thrown; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - final String fileName = getFileName(); - final int line = getLineNumber(); - final int column = getColumnNumber(); - - if (fileName != null) { - sb.append(fileName); - if (line >= 0) { - sb.append(':'); - sb.append(line); - } - if (column >= 0) { - sb.append(':'); - sb.append(column); - } - sb.append(' '); - } else { - sb.append("ECMAScript Exception: "); - } - - sb.append(getMessage()); - return sb.toString(); - } - - /** - * Get the {@link ECMAException}, i.e. the underlying Java object for the - * JavaScript error object from a {@link ScriptObject} representing an error - * - * @param errObj the error object - * @return a {@link ECMAException} - */ - public static Object getException(final ScriptObject errObj) { - // Exclude inherited properties that may belong to errors in the prototype chain. - if (errObj.hasOwnProperty(ECMAException.EXCEPTION_PROPERTY)) { - return errObj.get(ECMAException.EXCEPTION_PROPERTY); - } - return null; - } - - /** - * Print the stack trace for a {@code ScriptObject} representing an error - * - * @param errObj the error object - * @return undefined - */ - public static Object printStackTrace(final ScriptObject errObj) { - final Object exception = getException(errObj); - if (exception instanceof Throwable) { - ((Throwable)exception).printStackTrace(Context.getCurrentErr()); - } else { - Context.err(""); - } - return UNDEFINED; - } - - /** - * Get the line number for a {@code ScriptObject} representing an error - * - * @param errObj the error object - * @return the line number, or undefined if wrapped exception is not a ParserException - */ - public static Object getLineNumber(final ScriptObject errObj) { - final Object e = getException(errObj); - if (e instanceof NashornException) { - return ((NashornException)e).getLineNumber(); - } else if (e instanceof ScriptException) { - return ((ScriptException)e).getLineNumber(); - } - - return UNDEFINED; - } - - /** - * Get the column number for a {@code ScriptObject} representing an error - * - * @param errObj the error object - * @return the column number, or undefined if wrapped exception is not a ParserException - */ - public static Object getColumnNumber(final ScriptObject errObj) { - final Object e = getException(errObj); - if (e instanceof NashornException) { - return ((NashornException)e).getColumnNumber(); - } else if (e instanceof ScriptException) { - return ((ScriptException)e).getColumnNumber(); - } - - return UNDEFINED; - } - - /** - * Get the file name for a {@code ScriptObject} representing an error - * - * @param errObj the error object - * @return the file name, or undefined if wrapped exception is not a ParserException - */ - public static Object getFileName(final ScriptObject errObj) { - final Object e = getException(errObj); - if (e instanceof NashornException) { - return ((NashornException)e).getFileName(); - } else if (e instanceof ScriptException) { - return ((ScriptException)e).getFileName(); - } - - return UNDEFINED; - } - - /** - * Stateless string conversion for an error object - * - * @param errObj the error object - * @return string representation of {@code errObj} - */ - public static String safeToString(final ScriptObject errObj) { - Object name = UNDEFINED; - try { - name = errObj.get("name"); - } catch (final Exception e) { - //ignored - } - - if (name == UNDEFINED) { - name = "Error"; - } else { - name = ScriptRuntime.safeToString(name); - } - - Object msg = UNDEFINED; - try { - msg = errObj.get("message"); - } catch (final Exception e) { - //ignored - } - - if (msg == UNDEFINED) { - msg = ""; - } else { - msg = ScriptRuntime.safeToString(msg); - } - - if (((String)name).isEmpty()) { - return (String)msg; - } - - if (((String)msg).isEmpty()) { - return (String)name; - } - - return name + ": " + msg; - } - - private static Throwable asThrowable(final Object obj) { - return (obj instanceof Throwable)? (Throwable)obj : null; - } - - private void setExceptionToThrown() { - /* - * Nashorn extension: errorObject.nashornException - * Expose this exception via "nashornException" property of on the - * thrown object. This exception object can be used to print stack - * trace and fileName, line number etc. from script code. - */ - - if (thrown instanceof ScriptObject) { - final ScriptObject sobj = (ScriptObject)thrown; - if (!sobj.has(EXCEPTION_PROPERTY)) { - sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this); - } else { - sobj.set(EXCEPTION_PROPERTY, this, 0); - } - } - } -}