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 public Object getThrown() {
92 return thrown;
93 }
94
95 @Override
96 public String toString() {
97 final StringBuilder sb = new StringBuilder();
98 final String fileName = getFileName();
99 final int line = getLineNumber();
100 final int column = getColumnNumber();
101
102 if (fileName != null) {
103 sb.append(fileName);
104 if (line >= 0) {
105 sb.append(':');
106 sb.append(line);
107 }
108 if (column >= 0) {
109 sb.append(':');
110 sb.append(column);
239
240 return name + ": " + msg;
241 }
242
243 private static Throwable asThrowable(final Object obj) {
244 return (obj instanceof Throwable)? (Throwable)obj : null;
245 }
246
247 private void setExceptionToThrown() {
248 /*
249 * Nashorn extension: errorObject.nashornException
250 * Expose this exception via "nashornException" property of on the
251 * thrown object. This exception object can be used to print stack
252 * trace and fileName, line number etc. from script code.
253 */
254
255 if (thrown instanceof ScriptObject) {
256 final ScriptObject sobj = (ScriptObject)thrown;
257 if (!sobj.has(EXCEPTION_PROPERTY)) {
258 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
259 }
260 }
261 }
262 }
|
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
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#create(Object, String, int, int)},
48 */
49 public static final Call CREATE = staticCallNoLookup(ECMAException.class, "create", 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. Called from the factory method 'create'.
61 *
62 * @param thrown object to be thrown
63 * @param fileName script file name
64 * @param line line number of throw
65 * @param column column number of throw
66 */
67 private ECMAException(final Object thrown, final String fileName, final int line, final int column) {
68 super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column);
69 this.thrown = thrown;
70 setExceptionToThrown();
71 }
72
73 /**
74 * Constructor. This is called from the runtime code.
75 *
76 * @param thrown object to be thrown
77 * @param cause Java exception that triggered this throw
78 */
79 public ECMAException(final Object thrown, final Throwable cause) {
80 super(ScriptRuntime.safeToString(thrown), cause);
81 this.thrown = thrown;
82 setExceptionToThrown();
83 }
84
85 /**
86 * Factory method to retrieve the underlying exception or create an exception.
87 * This method is called from the generated code.
88 *
89 * @param thrown object to be thrown
90 * @param fileName script file name
91 * @param line line number of throw
92 * @param column column number of throw
93 * @return ECMAException object
94 */
95 public static ECMAException create(final Object thrown, final String fileName, final int line, final int column) {
96 // If thrown object is an Error or sub-object like TypeError, then
97 // an ECMAException object has been already initialized at constructor.
98 if (thrown instanceof ScriptObject) {
99 ScriptObject sobj = (ScriptObject)thrown;
100 Object exception = getException(sobj);
101 if (exception instanceof ECMAException) {
102 // copy over file name, line number and column number.
103 final ECMAException ee = (ECMAException)exception;
104 ee.setFileName(fileName);
105 ee.setLineNumber(line);
106 ee.setColumnNumber(column);
107 return ee;
108 }
109 }
110
111 return new ECMAException(thrown, fileName, line, column);
112 }
113
114 /**
115 * Get the thrown object
116 * @return thrown object
117 */
118 @Override
119 public Object getThrown() {
120 return thrown;
121 }
122
123 @Override
124 public String toString() {
125 final StringBuilder sb = new StringBuilder();
126 final String fileName = getFileName();
127 final int line = getLineNumber();
128 final int column = getColumnNumber();
129
130 if (fileName != null) {
131 sb.append(fileName);
132 if (line >= 0) {
133 sb.append(':');
134 sb.append(line);
135 }
136 if (column >= 0) {
137 sb.append(':');
138 sb.append(column);
267
268 return name + ": " + msg;
269 }
270
271 private static Throwable asThrowable(final Object obj) {
272 return (obj instanceof Throwable)? (Throwable)obj : null;
273 }
274
275 private void setExceptionToThrown() {
276 /*
277 * Nashorn extension: errorObject.nashornException
278 * Expose this exception via "nashornException" property of on the
279 * thrown object. This exception object can be used to print stack
280 * trace and fileName, line number etc. from script code.
281 */
282
283 if (thrown instanceof ScriptObject) {
284 final ScriptObject sobj = (ScriptObject)thrown;
285 if (!sobj.has(EXCEPTION_PROPERTY)) {
286 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
287 } else {
288 sobj.set(EXCEPTION_PROPERTY, this, false);
289 }
290 }
291 }
292 }
|