8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime; 27 28 import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; 29 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualField; 30 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 31 32 import javax.script.ScriptException; 33 import jdk.nashorn.api.scripting.NashornException; 34 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 35 import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess; 36 37 /** 38 * Exception used to implement ECMAScript "throw" from scripts. The actual thrown 39 * object from script need not be a Java exception and so it is wrapped as an 40 * instance field called "thrown" here. This exception class is also used to 41 * represent ECMA errors thrown from runtime code (for example, TypeError, 42 * ReferenceError thrown from Nashorn engine runtime). 43 */ 44 @SuppressWarnings("serial") 45 public final class ECMAException extends NashornException { 46 /** 47 * Method handle pointing to the constructor {@link ECMAException#ECMAException(Object, String, int, int)}, 48 */ 49 public static final Call THROW_INIT = constructorNoLookup(ECMAException.class, Object.class, String.class, int.class, int.class); 50 51 /** Field handle to the{@link ECMAException#thrown} field, so that it can be accessed from generated code */ 52 public static final FieldAccess THROWN = virtualField(ECMAException.class, "thrown", Object.class); 53 54 private static final String EXCEPTION_PROPERTY = "nashornException"; 55 56 /** Object thrown. */ 57 public final Object thrown; 58 59 /** 60 * Constructor. This is called from generated code to implement the {@code throw} 61 * instruction from generated script code 62 * 63 * @param thrown object to be thrown 64 * @param fileName script file name 65 * @param line line number of throw 66 * @param column column number of throw 67 */ 68 public ECMAException(final Object thrown, final String fileName, final int line, final int column) { 69 super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column); 70 this.thrown = thrown; 71 setExceptionToThrown(); 72 } 73 74 /** 75 * Constructor. This is called from runtime code in Nashorn to throw things like 76 * type errors. 77 * 78 * @param thrown object to be thrown 79 * @param cause Java exception that triggered this throw 80 */ 81 public ECMAException(final Object thrown, final Throwable cause) { 82 super(ScriptRuntime.safeToString(thrown), cause); 83 this.thrown = thrown; 84 setExceptionToThrown(); 85 } 86 87 /** 88 * Get the thrown object 89 * @return thrown object 90 */ 91 @Override 92 public Object getThrown() { 93 return thrown; 94 } 95 96 @Override 97 public String toString() { 98 final StringBuilder sb = new StringBuilder(); 99 final String fileName = getFileName(); 100 final int line = getLineNumber(); 101 final int column = getColumnNumber(); 102 103 if (fileName != null) { 104 sb.append(fileName); 105 if (line >= 0) { 106 sb.append(':'); 107 sb.append(line); 240 241 return name + ": " + msg; 242 } 243 244 private static Throwable asThrowable(final Object obj) { 245 return (obj instanceof Throwable)? (Throwable)obj : null; 246 } 247 248 private void setExceptionToThrown() { 249 /* 250 * Nashorn extension: errorObject.nashornException 251 * Expose this exception via "nashornException" property of on the 252 * thrown object. This exception object can be used to print stack 253 * trace and fileName, line number etc. from script code. 254 */ 255 256 if (thrown instanceof ScriptObject) { 257 final ScriptObject sobj = (ScriptObject)thrown; 258 if (!sobj.has(EXCEPTION_PROPERTY)) { 259 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this); 260 } 261 } 262 } 263 } | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime; 27 28 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; 29 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualField; 30 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 31 32 import javax.script.ScriptException; 33 import jdk.nashorn.api.scripting.NashornException; 34 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 35 import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess; 36 import jdk.nashorn.internal.objects.NativeError; 37 38 /** 39 * Exception used to implement ECMAScript "throw" from scripts. The actual thrown 40 * object from script need not be a Java exception and so it is wrapped as an 41 * instance field called "thrown" here. This exception class is also used to 42 * represent ECMA errors thrown from runtime code (for example, TypeError, 43 * ReferenceError thrown from Nashorn engine runtime). 44 */ 45 @SuppressWarnings("serial") 46 public final class ECMAException extends NashornException { 47 /** 48 * Method handle pointing to the constructor {@link ECMAException#create(Object, String, int, int)}, 49 */ 50 public static final Call CREATE = staticCallNoLookup(ECMAException.class, "create", ECMAException.class, Object.class, String.class, int.class, int.class); 51 52 /** Field handle to the{@link ECMAException#thrown} field, so that it can be accessed from generated code */ 53 public static final FieldAccess THROWN = virtualField(ECMAException.class, "thrown", Object.class); 54 55 private static final String EXCEPTION_PROPERTY = "nashornException"; 56 57 /** Object thrown. */ 58 public final Object thrown; 59 60 /** 61 * Constructor. Called from the factory method 'create'. 62 * 63 * @param thrown object to be thrown 64 * @param fileName script file name 65 * @param line line number of throw 66 * @param column column number of throw 67 */ 68 private ECMAException(final Object thrown, final String fileName, final int line, final int column) { 69 super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column); 70 this.thrown = thrown; 71 setExceptionToThrown(); 72 } 73 74 /** 75 * Constructor. This is called from the runtime code. 76 * 77 * @param thrown object to be thrown 78 * @param cause Java exception that triggered this throw 79 */ 80 public ECMAException(final Object thrown, final Throwable cause) { 81 super(ScriptRuntime.safeToString(thrown), cause); 82 this.thrown = thrown; 83 setExceptionToThrown(); 84 } 85 86 /** 87 * Factory method to retrieve the underlying exception or create an exception. 88 * This method is called from the generated code. 89 * 90 * @param thrown object to be thrown 91 * @param fileName script file name 92 * @param line line number of throw 93 * @param column column number of throw 94 * @return ECMAException object 95 */ 96 public static ECMAException create(final Object thrown, final String fileName, final int line, final int column) { 97 // If thrown object is an Error or sub-object like TypeError, then 98 // an ECMAException object has been already initialized at constructor. 99 if (thrown instanceof ScriptObject) { 100 ScriptObject sobj = (ScriptObject)thrown; 101 Object exception = getException(sobj); 102 if (exception instanceof ECMAException) { 103 // copy over file name, line number and column number. 104 final ECMAException ee = (ECMAException)exception; 105 ee.setFileName(fileName); 106 ee.setLineNumber(line); 107 ee.setColumnNumber(column); 108 return ee; 109 } 110 } 111 112 return new ECMAException(thrown, fileName, line, column); 113 } 114 115 /** 116 * Get the thrown object 117 * @return thrown object 118 */ 119 @Override 120 public Object getThrown() { 121 return thrown; 122 } 123 124 @Override 125 public String toString() { 126 final StringBuilder sb = new StringBuilder(); 127 final String fileName = getFileName(); 128 final int line = getLineNumber(); 129 final int column = getColumnNumber(); 130 131 if (fileName != null) { 132 sb.append(fileName); 133 if (line >= 0) { 134 sb.append(':'); 135 sb.append(line); 268 269 return name + ": " + msg; 270 } 271 272 private static Throwable asThrowable(final Object obj) { 273 return (obj instanceof Throwable)? (Throwable)obj : null; 274 } 275 276 private void setExceptionToThrown() { 277 /* 278 * Nashorn extension: errorObject.nashornException 279 * Expose this exception via "nashornException" property of on the 280 * thrown object. This exception object can be used to print stack 281 * trace and fileName, line number etc. from script code. 282 */ 283 284 if (thrown instanceof ScriptObject) { 285 final ScriptObject sobj = (ScriptObject)thrown; 286 if (!sobj.has(EXCEPTION_PROPERTY)) { 287 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this); 288 } else { 289 sobj.set(EXCEPTION_PROPERTY, this, false); 290 } 291 } 292 } 293 } |