8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
authorlagergren
Fri, 22 Feb 2013 12:22:16 +0100
changeset 16256 f2d9a0c49914
parent 16255 cb52a2524ca8
child 16257 781330354161
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code Reviewed-by: attila, hannesw
nashorn/src/jdk/nashorn/api/scripting/NashornException.java
nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
nashorn/src/jdk/nashorn/api/scripting/URLReader.java
nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
nashorn/src/jdk/nashorn/internal/objects/Global.java
nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
nashorn/src/jdk/nashorn/internal/objects/NativeError.java
nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
nashorn/src/jdk/nashorn/internal/objects/NativeString.java
nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
nashorn/src/jdk/nashorn/internal/parser/Lexer.java
nashorn/src/jdk/nashorn/internal/runtime/Context.java
nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java
nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java
nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java
nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
nashorn/src/jdk/nashorn/internal/runtime/JSType.java
nashorn/src/jdk/nashorn/internal/runtime/ParserException.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
nashorn/src/jdk/nashorn/internal/runtime/Undefined.java
nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java
nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java
nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java
nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java
nashorn/src/jdk/nashorn/internal/runtime/linker/Lookup.java
nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java	Fri Feb 22 12:22:16 2013 +0100
@@ -25,100 +25,115 @@
 
 package jdk.nashorn.api.scripting;
 
+import jdk.nashorn.internal.runtime.ECMAErrors;
+
 /**
- * This is base exception for all Nashorn exceptions. These originate from user's
- * ECMAScript code. Example: script parse errors, exceptions thrown from scripts.
- * Note that ScriptEngine methods like "eval", "invokeMethod", "invokeFunction"
- * will wrap this as ScriptException and throw it. But, there are cases where user
- * may need to access this exception (or implementation defined subtype of this).
- * For example, if java interface is implemented by a script object or Java access
- * to script object properties via java.util.Map interface. In these cases, user
- * code will get an instance of this or implementation defined subclass.
+ * This is base exception for all Nashorn exceptions. These originate from
+ * user's ECMAScript code. Example: script parse errors, exceptions thrown from
+ * scripts. Note that ScriptEngine methods like "eval", "invokeMethod",
+ * "invokeFunction" will wrap this as ScriptException and throw it. But, there
+ * are cases where user may need to access this exception (or implementation
+ * defined subtype of this). For example, if java interface is implemented by a
+ * script object or Java access to script object properties via java.util.Map
+ * interface. In these cases, user code will get an instance of this or
+ * implementation defined subclass.
  */
 @SuppressWarnings("serial")
-public class NashornException extends RuntimeException {
+public abstract class NashornException extends RuntimeException {
     // script file name
-    private String      fileName;
+    private final String fileName;
     // script line number
-    private int         line;
+    private final int line;
     // script column number
-    private int         column;
+    private final int column;
 
     /** script source name used for "engine.js" */
-    protected static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
+    public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
 
     /**
      * Constructor
      *
-     * @param msg exception message
+     * @param msg       exception message
+     * @param fileName  file name
+     * @param line      line number
+     * @param column    column number
      */
-    protected NashornException(final String msg) {
-        super(msg);
-    }
-
-    /**
-     * Constructor
-     * @param msg   exception message
-     * @param cause exception cause
-     */
-    protected NashornException(final String msg, final Throwable cause) {
-        super(msg, cause);
+    protected NashornException(final String msg, final String fileName, final int line, final int column) {
+        this(msg, null, fileName, line, column);
     }
 
     /**
      * Constructor
      *
-     * @param cause exception cause
+     * @param msg       exception message
+     * @param cause     exception cause
+     * @param fileName  file name
+     * @param line      line number
+     * @param column    column number
      */
-    protected NashornException(final Throwable cause) {
-        super(cause);
+    protected NashornException(final String msg, final Throwable cause, final String fileName, final int line, final int column) {
+        super(msg, cause == null ? null : cause);
+        this.fileName = fileName;
+        this.line = line;
+        this.column = column;
     }
 
-     /**
-      * Get the source file name for this {@code NashornException}
-      * @return the file name
-      */
-     public final String getFileName() {
-         return fileName;
-     }
+    /**
+     * Constructor
+     *
+     * @param msg       exception message
+     * @param cause     exception cause
+     */
+    protected NashornException(final String msg, final Throwable cause) {
+        super(msg, cause == null ? null : cause);
+        // This is not so pretty - but it gets the job done. Note that the stack
+        // trace has been already filled by "fillInStackTrace" call from
+        // Throwable
+        // constructor and so we don't pay additional cost for it.
+
+        // Hard luck - no column number info
+        this.column = -1;
+
+        // Find the first JavaScript frame by walking and set file, line from it
+        // Usually, we should be able to find it in just few frames depth.
+        for (final StackTraceElement ste : getStackTrace()) {
+            if (ECMAErrors.isScriptFrame(ste)) {
+                // Whatever here is compiled from JavaScript code
+                this.fileName = ste.getFileName();
+                this.line = ste.getLineNumber();
+                return;
+            }
+        }
+
+        this.fileName = null;
+        this.line = 0;
+    }
 
     /**
-     * Set the source file name for this {@code NashornException}
-     * @param fileName file name
+     * Get the source file name for this {@code NashornException}
+     *
+     * @return the file name
      */
-    protected final void setFileName(final String fileName) {
-         this.fileName = fileName;
-     }
+    public final String getFileName() {
+        return fileName;
+    }
 
     /**
      * Get the line number for this {@code NashornException}
+     *
      * @return the line number
      */
-     public final int getLineNumber() {
-         return line;
-     }
-
-    /**
-     * Set the line number for this {@code NashornException}
-     * @param line line number
-     */
-    protected final void setLineNumber(final int line) {
-         this.line = line;
-     }
+    public final int getLineNumber() {
+        return line;
+    }
 
     /**
      * Get the column for this {@code NashornException}
+     *
      * @return the column
      */
     public final int getColumnNumber() {
         return column;
     }
 
-   /**
-    * Set the column number for this {@code NashornException}
-    * @param column the column
-    */
-    public final void setColumnNumber(final int column) {
-        this.column = column;
-    }
 }
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Fri Feb 22 12:22:16 2013 +0100
@@ -122,9 +122,8 @@
             if (reader instanceof URLReader) {
                 final URL url = ((URLReader)reader).getURL();
                 return evalImpl(compileImpl(new Source(url.toString(), url), ctxt), ctxt);
-            } else {
-                return evalImpl(Source.readFully(reader), ctxt);
             }
+            return evalImpl(Source.readFully(reader), ctxt);
         } catch (final IOException e) {
             throw new ScriptException(e);
         }
@@ -240,7 +239,7 @@
 
         if (self == UNDEFINED) {
             // scope access and so throw ReferenceError
-            referenceError(ctxtGlobal, "not.defined", name);
+            throw referenceError(ctxtGlobal, "not.defined", name);
         }
 
         return UNDEFINED;
--- a/nashorn/src/jdk/nashorn/api/scripting/URLReader.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java	Fri Feb 22 12:22:16 2013 +0100
@@ -40,6 +40,11 @@
     // lazily initialized underlying reader for URL
     private Reader reader;
 
+    /**
+     * Constructor
+     *
+     * @param url URL for this URLReader
+     */
     public URLReader(final URL url) {
         this.url = url;
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Fri Feb 22 12:22:16 2013 +0100
@@ -157,7 +157,7 @@
             if (getter == UNDEFINED || getter instanceof ScriptFunction) {
                 this.get = getter;
             } else {
-                typeError("not.a.function", ScriptRuntime.safeToString(getter));
+                throw typeError("not.a.function", ScriptRuntime.safeToString(getter));
             }
         } else {
             delete(GET, strict);
@@ -168,7 +168,7 @@
             if (setter == UNDEFINED || setter instanceof ScriptFunction) {
                 this.set = setter;
             } else {
-                typeError("not.a.function", ScriptRuntime.safeToString(setter));
+                throw typeError("not.a.function", ScriptRuntime.safeToString(setter));
             }
         } else {
             delete(SET, strict);
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java	Fri Feb 22 12:22:16 2013 +0100
@@ -485,7 +485,7 @@
                         return value;
                     }
                 }
-                typeError(this, "cannot.get.default.string");
+                throw typeError(this, "cannot.get.default.string");
             }
 
             if (hint == Number.class) {
@@ -505,7 +505,7 @@
                     }
                 }
 
-                typeError(this, "cannot.get.default.number");
+                throw typeError(this, "cannot.get.default.number");
             }
         } catch (final RuntimeException | Error e) {
             throw e;
@@ -1177,7 +1177,7 @@
      */
     public static Object toObject(final Object obj) {
         if (obj == null || obj == UNDEFINED) {
-            typeError("not.an.object", ScriptRuntime.safeToString(obj));
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
         }
 
         if (obj instanceof ScriptObject) {
@@ -1294,7 +1294,7 @@
      */
     public static void checkObject(final Object obj) {
         if (!(obj instanceof ScriptObject)) {
-            typeError("not.an.object", ScriptRuntime.safeToString(obj));
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
         }
     }
 
@@ -1306,7 +1306,7 @@
      */
     public static void checkObjectCoercible(final Object obj) {
         if (obj == null || obj == UNDEFINED) {
-            typeError("not.an.object", ScriptRuntime.safeToString(obj));
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java	Fri Feb 22 12:22:16 2013 +0100
@@ -485,7 +485,7 @@
             final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
             if (!allowed) {
                 if (reject) {
-                    typeError("cant.redefine.property",  key, ScriptRuntime.safeToString(this));
+                    throw typeError("cant.redefine.property",  key, ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Fri Feb 22 12:22:16 2013 +0100
@@ -181,7 +181,7 @@
             // Step 3g
             if (!oldLenDesc.isWritable()) {
                 if (reject) {
-                    typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+                    throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -210,7 +210,7 @@
                     }
                     super.defineOwnProperty("length", newLenDesc, false);
                     if (reject) {
-                        typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+                        throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
                     }
                     return false;
                 }
@@ -235,7 +235,7 @@
             // setting an element beyond current length, but 'length' is not writable
             if (longIndex >= oldLen && !oldLenDesc.isWritable()) {
                 if (reject) {
-                    typeError("property.not.writable", Long.toString(longIndex), ScriptRuntime.safeToString(this));
+                    throw typeError("property.not.writable", Long.toString(longIndex), ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -247,7 +247,7 @@
             // Step 4d
             if (!succeeded) {
                 if (reject) {
-                    typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+                    throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -324,7 +324,7 @@
             }
         }
         if (reject) {
-            rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
+            throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
         }
         return -1;
     }
@@ -380,7 +380,7 @@
                         if (toLocaleString instanceof ScriptFunction) {
                             sb.append((String)TO_LOCALE_STRING.getInvoker().invokeExact(toLocaleString, sobj));
                         } else {
-                            typeError("not.a.function", "toLocaleString");
+                            throw typeError("not.a.function", "toLocaleString");
                         }
                     }
                 } catch (final Error|RuntimeException t) {
@@ -433,7 +433,7 @@
                  */
                 final double numberLength = ((Number) len).doubleValue();
                 if (length != numberLength) {
-                    rangeError("inappropriate.array.length", JSType.toString(numberLength));
+                    throw rangeError("inappropriate.array.length", JSType.toString(numberLength));
                 }
 
                 return new NativeArray(length);
@@ -623,8 +623,7 @@
 
             return element;
         } catch (final ClassCastException | NullPointerException e) {
-            typeError("not.an.object", ScriptRuntime.safeToString(self));
-            return ScriptRuntime.UNDEFINED;
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -659,8 +658,7 @@
 
             return len;
         } catch (final ClassCastException | NullPointerException e) {
-            typeError("not.an.object", ScriptRuntime.safeToString(self));
-            return ScriptRuntime.UNDEFINED;
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -698,8 +696,7 @@
             }
             return sobj;
         } catch (final ClassCastException | NullPointerException e) {
-            typeError("not.an.object", ScriptRuntime.safeToString(self));
-            return ScriptRuntime.UNDEFINED;
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -864,8 +861,7 @@
 
             return sobj;
         } catch (final ClassCastException | NullPointerException e) {
-            typeError("not.an.object", ScriptRuntime.safeToString(self));
-            return ScriptRuntime.UNDEFINED;
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -1079,7 +1075,7 @@
                 }
             }
         } catch (final ClassCastException | NullPointerException e) {
-            typeError("not.an.object", ScriptRuntime.safeToString(self));
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
         }
 
         return -1;
@@ -1201,14 +1197,14 @@
         Object initialValue = initialValuePresent ? args[1] : ScriptRuntime.UNDEFINED;
 
         if (callbackfn == ScriptRuntime.UNDEFINED) {
-            typeError("not.a.function", "undefined");
+            throw typeError("not.a.function", "undefined");
         }
 
         if (!initialValuePresent) {
             if (iter.hasNext()) {
                 initialValue = iter.next();
             } else {
-                typeError("array.reduce.invalid.init");
+                throw typeError("array.reduce.invalid.init");
             }
         }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Fri Feb 22 12:22:16 2013 +0100
@@ -145,8 +145,7 @@
         } else if (self != null && self == Global.instance().getBooleanPrototype()) {
             return false;
         } else {
-            typeError("not.a.boolean", ScriptRuntime.safeToString(self));
-            return false;
+            throw typeError("not.a.boolean", ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Fri Feb 22 12:22:16 2013 +0100
@@ -867,14 +867,12 @@
             if (func instanceof ScriptFunction) {
                 return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
             }
-            typeError("not.a.function", ScriptRuntime.safeToString(func));
+            throw typeError("not.a.function", ScriptRuntime.safeToString(func));
         } catch (final RuntimeException | Error e) {
             throw e;
         } catch (final Throwable t) {
             throw new RuntimeException(t);
         }
-
-        return null;
     }
 
     // -- Internals below this point
@@ -1006,9 +1004,7 @@
             return sb.toString();
         }
 
-        rangeError("invalid.date");
-
-        return INVALID_DATE;
+        throw rangeError("invalid.date");
     }
 
     private static String toISOStringImpl(final Object self) {
@@ -1035,9 +1031,7 @@
             return sb.toString();
         }
 
-        rangeError("invalid.date");
-
-        return INVALID_DATE;
+        throw rangeError("invalid.date");
     }
 
     // ECMA 15.9.1.2 Day (t)
@@ -1268,8 +1262,7 @@
         } else if (self != null && self == Global.instance().getDatePrototype()) {
             return Global.instance().DEFAULT_DATE;
         } else {
-            typeError("not.a.date", ScriptRuntime.safeToString(self));
-            return null;
+            throw typeError("not.a.date", ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Fri Feb 22 12:22:16 2013 +0100
@@ -38,6 +38,7 @@
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ECMAErrors;
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -246,7 +247,7 @@
             final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
             final List<StackTraceElement> filtered = new ArrayList<>();
             for (final StackTraceElement st : frames) {
-                if (ECMAException.isScriptFrame(st)) {
+                if (ECMAErrors.isScriptFrame(st)) {
                     filtered.add(st);
                 }
             }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java	Fri Feb 22 12:22:16 2013 +0100
@@ -60,8 +60,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object toString(final Object self) {
         if (!(self instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(self));
-            return UNDEFINED;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
         return ((ScriptFunction)self).toSource();
     }
@@ -77,8 +76,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object apply(final Object self, final Object thiz, final Object array) {
         if (!(self instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(self));
-            return UNDEFINED;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
 
         Object[] args = null;
@@ -91,12 +89,12 @@
             final Object       len  = sobj.getLength();
 
             if (len == UNDEFINED || len == null) {
-                typeError("function.apply.expects.array");
+                throw typeError("function.apply.expects.array");
             }
 
             final int n = (int)JSType.toUint32(len);
             if (n != JSType.toNumber(len)) {
-                typeError("function.apply.expects.array");
+                throw typeError("function.apply.expects.array");
             }
 
             args = new Object[(int)JSType.toUint32(len)];
@@ -111,7 +109,7 @@
         } else if (array == null || array == UNDEFINED) {
             args = ScriptRuntime.EMPTY_ARRAY;
         } else {
-            typeError("function.apply.expects.array");
+            throw typeError("function.apply.expects.array");
         }
 
         return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
@@ -127,8 +125,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
     public static Object call(final Object self, final Object... args) {
         if (!(self instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(self));
-            return UNDEFINED;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
 
         Object thiz = (args.length == 0) ? UNDEFINED : args[0];
@@ -154,8 +151,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
     public static Object bind(final Object self, final Object... args) {
         if (!(self instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(self));
-            return UNDEFINED;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
 
         final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
@@ -180,8 +176,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object toSource(final Object self) {
         if (!(self instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(self));
-            return UNDEFINED;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
         return ((ScriptFunction)self).toSource();
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Fri Feb 22 12:22:16 2013 +0100
@@ -541,8 +541,7 @@
         Object adaptee;
 
         if (args == null || args.length == 0) {
-            typeError("not.an.object", "null");
-            return null; //won't reach, but fixed warning
+            throw typeError("not.an.object", "null");
         }
 
         switch (args.length) {
@@ -565,7 +564,7 @@
         }
 
         if (!(adaptee instanceof ScriptObject)) {
-            typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
+            throw typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
         }
 
         if (proto != null && !(proto instanceof ScriptObject)) {
@@ -624,8 +623,7 @@
                         func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
                         adaptee.getMap().getProtoGetSwitchPoint(__call__), testJSAdaptor(adaptee, null, null, null));
             }
-            typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
-            break;
+            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
         default:
             break;
         }
@@ -697,8 +695,7 @@
 
         switch (hook) {
         case __call__:
-            typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
-            throw new AssertionError("should not reach here");
+            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
         default:
             final MethodHandle methodHandle = hook.equals(__put__) ?
             MH.asType(Lookup.EMPTY_SETTER, type) :
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java	Fri Feb 22 12:22:16 2013 +0100
@@ -241,7 +241,7 @@
     // Spec: The abstract operation JO(value) serializes an object.
     private static String JO(final ScriptObject value, final StringifyState state) {
         if (state.stack.containsKey(value)) {
-            typeError("JSON.stringify.cyclic");
+            throw typeError("JSON.stringify.cyclic");
         }
 
         state.stack.put(value, value);
@@ -317,7 +317,7 @@
     // Spec: The abstract operation JA(value) serializes an array.
     private static Object JA(final NativeArray value, final StringifyState state) {
         if (state.stack.containsKey(value)) {
-            typeError("JSON.stringify.cyclic");
+            throw typeError("JSON.stringify.cyclic");
         }
 
         state.stack.put(value, value);
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java	Fri Feb 22 12:22:16 2013 +0100
@@ -287,9 +287,7 @@
             return new NativeArray(copyArray((boolean[])objArray));
         }
 
-        typeError("cant.convert.to.javascript.array", objArray.getClass().getName());
-
-        throw new AssertionError();
+        throw typeError("cant.convert.to.javascript.array", objArray.getClass().getName());
     }
 
     private static int[] copyArray(final byte[] in) {
@@ -384,8 +382,7 @@
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static Object extend(final Object self, final Object... types) {
         if(types == null || types.length == 0) {
-            typeError("extend.expects.at.least.one.argument");
-            throw new AssertionError(); //circumvent warning for types == null below
+            throw typeError("extend.expects.at.least.one.argument");
         }
         final Class<?>[] stypes = new Class<?>[types.length];
         try {
@@ -393,7 +390,7 @@
                 stypes[i] = ((StaticClass)types[i]).getRepresentedClass();
             }
         } catch(final ClassCastException e) {
-            typeError("extend.expects.java.types");
+            throw typeError("extend.expects.java.types");
         }
         return JavaAdapterFactory.getAdapterClassFor(stypes);
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Fri Feb 22 12:22:16 2013 +0100
@@ -185,8 +185,7 @@
     public static Object toFixed(final Object self, final Object fractionDigits) {
         final int f = JSType.toInteger(fractionDigits);
         if (f < 0 || f > 20) {
-            rangeError("invalid.fraction.digits", "toFixed");
-            return UNDEFINED;
+            throw rangeError("invalid.fraction.digits", "toFixed");
         }
 
         final double x = getNumberValue(self);
@@ -227,8 +226,7 @@
         }
 
         if (fractionDigits != UNDEFINED && (f < 0 || f > 20)) {
-            rangeError("invalid.fraction.digits", "toExponential");
-            return UNDEFINED;
+            throw rangeError("invalid.fraction.digits", "toExponential");
         }
 
         final String res = String.format(Locale.US, "%1." + f + "e", x);
@@ -258,8 +256,7 @@
         }
 
         if (p < 1 || p > 21) {
-            rangeError("invalid.precision");
-            return UNDEFINED;
+            throw rangeError("invalid.precision");
         }
 
         // workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6469160
@@ -283,7 +280,7 @@
             final int intRadix = JSType.toInteger(radix);
             if (intRadix != 10) {
                 if (intRadix < 2 || intRadix > 36) {
-                    rangeError("invalid.radix");
+                    throw rangeError("invalid.radix");
                 }
                 return JSType.toString(getNumberValue(self), intRadix);
             }
@@ -338,8 +335,7 @@
         } else if (self != null && self == Global.instance().getNumberPrototype()) {
             return 0.0;
         } else {
-            typeError("not.a.number", ScriptRuntime.safeToString(self));
-            return Double.NaN;
+            throw typeError("not.a.number", ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Feb 22 12:22:16 2013 +0100
@@ -331,8 +331,7 @@
                 throw new RuntimeException(t);
             }
 
-            typeError("not.a.function", "toString");
-            throw new AssertionError(); // never reached
+            throw typeError("not.a.function", "toString");
         }
 
         return ScriptRuntime.builtinObjectToString(self);
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Fri Feb 22 12:22:16 2013 +0100
@@ -224,7 +224,7 @@
                 if (!flagsDefined) {
                     return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as
                 }
-                typeError("regex.cant.supply.flags");
+                throw typeError("regex.cant.supply.flags");
             }
             patternString = JSType.toString(regexp);
         }
@@ -880,8 +880,7 @@
         } else if (self != null && self == Global.instance().getRegExpPrototype()) {
             return Global.instance().DEFAULT_REGEXP;
         } else {
-            typeError("not.a.regexp", ScriptRuntime.safeToString(self));
-            return null;
+            throw typeError("not.a.regexp", ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Fri Feb 22 12:22:16 2013 +0100
@@ -342,7 +342,7 @@
     private boolean checkDeleteIndex(final int index, final boolean strict) {
         if (isValid(index)) {
             if (strict) {
-                typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
+                throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
             }
             return true;
         }
@@ -1141,8 +1141,7 @@
         } else if (self != null && self == Global.instance().getStringPrototype()) {
             return "";
         } else {
-            typeError("not.a.string", ScriptRuntime.safeToString(self));
-            return null;
+            throw typeError("not.a.string", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -1156,8 +1155,7 @@
         } else if (self != null && self == Global.instance().getStringPrototype()) {
             return "";
         } else {
-            typeError( "not.a.string", ScriptRuntime.safeToString(self));
-            return null;
+            throw typeError( "not.a.string", ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java	Fri Feb 22 12:22:16 2013 +0100
@@ -214,9 +214,7 @@
         final int lineNum   = source.getLine(position);
         final int columnNum = source.getColumn(position);
         final String formatted = ErrorManager.format(message, source, lineNum, columnNum, errorToken);
-        final ParserException exp = new ParserException(formatted, source, lineNum, columnNum, errorToken);
-        exp.setErrorType(errorType);
-        throw exp;
+        throw new ParserException(errorType, formatted, source, lineNum, columnNum, errorToken);
     }
 
     /**
@@ -239,9 +237,7 @@
         final int position = Token.descPosition(token);
         final int column = position - linePosition;
         final String formatted = ErrorManager.format(message, source, line, column, token);
-        final ParserException exp = new ParserException(formatted, source, line, column, token);
-        exp.setErrorType(errorType);
-        throw exp;
+        throw new ParserException(errorType, formatted, source, line, column, token);
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java	Fri Feb 22 12:22:16 2013 +0100
@@ -45,6 +45,7 @@
 
 import jdk.nashorn.internal.runtime.ECMAErrors;
 import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSErrorType;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.Source;
@@ -1598,7 +1599,7 @@
         final int  lineNum   = source.getLine(pos);
         final int  columnNum = source.getColumn(pos);
         final String formatted = ErrorManager.format(message, source, lineNum, columnNum, token);
-        throw new ParserException(formatted, source, lineNum, columnNum, token);
+        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, lineNum, columnNum, token);
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Fri Feb 22 12:22:16 2013 +0100
@@ -671,9 +671,7 @@
             return evaluateSource(source, scope, scope);
         }
 
-        typeError("cant.load.script", ScriptRuntime.safeToString(from));
-
-        return UNDEFINED;
+        throw typeError("cant.load.script", ScriptRuntime.safeToString(from));
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Fri Feb 22 12:22:16 2013 +0100
@@ -31,6 +31,9 @@
 import java.util.Locale;
 import java.util.ResourceBundle;
 
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.scripts.JS$;
+
 /**
  * Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
  */
@@ -49,36 +52,44 @@
         });
     }
 
+    /** We assume that compiler generates script classes into the known package. */
+    private static final String scriptPackage;
+    static {
+        String name = JS$.class.getName();
+        scriptPackage = name.substring(0, name.lastIndexOf('.'));
+    }
+
     private ECMAErrors() {
     }
 
-    private static void throwError(final Object thrown, final Throwable cause) {
-        throw new ECMAException(thrown, cause);
+    private static ECMAException error(final Object thrown, final Throwable cause) {
+        return new ECMAException(thrown, cause);
     }
 
      /**
      * Error dispatch mechanism.
-     * Throw a {@link ParserException} as the correct JavaScript error
+     * Create a {@link ParserException} as the correct JavaScript error
      *
      * @param e {@code ParserException} for error dispatcher
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void throwAsEcmaException(final ParserException e) {
-        throwAsEcmaException(Context.getGlobalTrusted(), e);
+    public static ECMAException asEcmaException(final ParserException e) {
+        return asEcmaException(Context.getGlobalTrusted(), e);
     }
 
     /**
      * Error dispatch mechanism.
-     * Throw a {@link ParserException} as the correct JavaScript error
+     * Create a {@link ParserException} as the correct JavaScript error
      *
      * @param global global scope object
      * @param e {@code ParserException} for error dispatcher
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void throwAsEcmaException(final ScriptObject global, final ParserException e) {
+    public static ECMAException asEcmaException(final ScriptObject global, final ParserException e) {
         final JSErrorType errorType = e.getErrorType();
-        if (errorType == null) {
-            // no errorType set, throw ParserException object 'as is'
-            throw e;
-        }
+        assert errorType != null : "error type for " + e + " was null";
 
         final GlobalObject globalObj = (GlobalObject)global;
         final String       msg    = e.getMessage();
@@ -86,256 +97,288 @@
         // translate to ECMAScript Error object using error type
         switch (errorType) {
         case ERROR:
-            throwError(globalObj.newError(msg), e);
-            break;
+            return error(globalObj.newError(msg), e);
         case EVAL_ERROR:
-            throwError(globalObj.newEvalError(msg), e);
-            break;
+            return error(globalObj.newEvalError(msg), e);
         case RANGE_ERROR:
-            throwError(globalObj.newRangeError(msg), e);
-            break;
+            return error(globalObj.newRangeError(msg), e);
         case REFERENCE_ERROR:
-            throwError(globalObj.newReferenceError(msg), e);
-            break;
+            return error(globalObj.newReferenceError(msg), e);
         case SYNTAX_ERROR:
-            throwError(globalObj.newSyntaxError(msg), e);
-            break;
+            return error(globalObj.newSyntaxError(msg), e);
         case TYPE_ERROR:
-            throwError(globalObj.newTypeError(msg), e);
-            break;
+            return error(globalObj.newTypeError(msg), e);
         case URI_ERROR:
-            throwError(globalObj.newURIError(msg), e);
-            break;
+            return error(globalObj.newURIError(msg), e);
         default:
-            break;
+            // should not happen - perhaps unknown error type?
+            throw new AssertionError(e.getMessage());
         }
+    }
 
-        // should not happen - perhaps unknown error type?
-        throw e;
-    }
     /**
-     * Throw a syntax error (ECMA 15.11.6.4)
+     * Create a syntax error (ECMA 15.11.6.4)
      *
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void syntaxError(final String msgId, final String... args) {
-        syntaxError(Context.getGlobalTrusted(), msgId, args);
+    public static ECMAException syntaxError(final String msgId, final String... args) {
+        return syntaxError(Context.getGlobalTrusted(), msgId, args);
     }
 
     /**
-     * Throw a syntax error (ECMA 15.11.6.4)
+     * Create a syntax error (ECMA 15.11.6.4)
      *
      * @param global  global scope object
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void syntaxError(final ScriptObject global, final String msgId, final String... args) {
-        syntaxError(global, null, msgId, args);
+    public static ECMAException syntaxError(final ScriptObject global, final String msgId, final String... args) {
+        return syntaxError(global, null, msgId, args);
     }
 
     /**
-     * Throw a syntax error (ECMA 15.11.6.4)
+     * Create a syntax error (ECMA 15.11.6.4)
      *
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void syntaxError(final Throwable cause, final String msgId, final String... args) {
-        syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
+    public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
+        return syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
     }
 
     /**
-     * Throw a syntax error (ECMA 15.11.6.4)
+     * Create a syntax error (ECMA 15.11.6.4)
      *
      * @param global  global scope object
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("syntax.error." + msgId, args);
-        throwError(((GlobalObject)global).newSyntaxError(msg), cause);
+        return error(((GlobalObject)global).newSyntaxError(msg), cause);
     }
 
     /**
-     * Throw a type error (ECMA 15.11.6.5)
+     * Create a type error (ECMA 15.11.6.5)
      *
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void typeError(final String msgId, final String... args) {
-        typeError(Context.getGlobalTrusted(), msgId, args);
+    public static ECMAException typeError(final String msgId, final String... args) {
+        return typeError(Context.getGlobalTrusted(), msgId, args);
     }
 
     /**
-     * Throw a type error (ECMA 15.11.6.5)
+     * Create a type error (ECMA 15.11.6.5)
      *
      * @param global  global scope object
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void typeError(final ScriptObject global, final String msgId, final String... args) {
-        typeError(global, null, msgId, args);
+    public static ECMAException typeError(final ScriptObject global, final String msgId, final String... args) {
+        return typeError(global, null, msgId, args);
     }
 
     /**
-     * Throw a type error (ECMA 15.11.6.5)
+     * Create a type error (ECMA 15.11.6.5)
      *
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void typeError(final Throwable cause, final String msgId, final String... args) {
-        typeError(Context.getGlobalTrusted(), cause, msgId, args);
+    public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
+        return typeError(Context.getGlobalTrusted(), cause, msgId, args);
     }
 
     /**
-     * Throw a type error (ECMA 15.11.6.5)
+     * Create a type error (ECMA 15.11.6.5)
      *
      * @param global  global scope object
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("type.error." + msgId, args);
-        throwError(((GlobalObject)global).newTypeError(msg), cause);
+        return error(((GlobalObject)global).newTypeError(msg), cause);
     }
 
     /**
-     * Throw a range error (ECMA 15.11.6.2)
+     * Create a range error (ECMA 15.11.6.2)
      *
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void rangeError(final String msgId, final String... args) {
-        rangeError(Context.getGlobalTrusted(), msgId, args);
+    public static ECMAException rangeError(final String msgId, final String... args) {
+        return rangeError(Context.getGlobalTrusted(), msgId, args);
     }
 
     /**
-     * Throw a range error (ECMA 15.11.6.2)
+     * Create a range error (ECMA 15.11.6.2)
      *
      * @param global  global scope object
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void rangeError(final ScriptObject global, final String msgId, final String... args) {
-        rangeError(global, null, msgId, args);
+    public static ECMAException rangeError(final ScriptObject global, final String msgId, final String... args) {
+        return rangeError(global, null, msgId, args);
     }
 
     /**
-     * Throw a range error (ECMA 15.11.6.2)
+     * Create a range error (ECMA 15.11.6.2)
      *
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void rangeError(final Throwable cause, final String msgId, final String... args) {
-        rangeError(Context.getGlobalTrusted(), cause, msgId, args);
+    public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
+        return rangeError(Context.getGlobalTrusted(), cause, msgId, args);
     }
 
     /**
-     * Throw a range error (ECMA 15.11.6.2)
+     * Create a range error (ECMA 15.11.6.2)
      *
      * @param global  global scope object
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("range.error." + msgId, args);
-        throwError(((GlobalObject)global).newRangeError(msg), cause);
+        return error(((GlobalObject)global).newRangeError(msg), cause);
     }
 
     /**
-     * Throw a reference error (ECMA 15.11.6.3)
+     * Create a reference error (ECMA 15.11.6.3)
      *
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void referenceError(final String msgId, final String... args) {
-        referenceError(Context.getGlobalTrusted(), msgId, args);
+    public static ECMAException referenceError(final String msgId, final String... args) {
+        return referenceError(Context.getGlobalTrusted(), msgId, args);
     }
 
     /**
-     * Throw a reference error (ECMA 15.11.6.3)
+     * Create a reference error (ECMA 15.11.6.3)
      *
      * @param global  global scope object
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void referenceError(final ScriptObject global, final String msgId, final String... args) {
-        referenceError(global, null, msgId, args);
+    public static ECMAException referenceError(final ScriptObject global, final String msgId, final String... args) {
+        return referenceError(global, null, msgId, args);
     }
 
     /**
-     * Throw a reference error (ECMA 15.11.6.3)
+     * Create a reference error (ECMA 15.11.6.3)
      *
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void referenceError(final Throwable cause, final String msgId, final String... args) {
-        referenceError(Context.getGlobalTrusted(), cause, msgId, args);
+    public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
+        return referenceError(Context.getGlobalTrusted(), cause, msgId, args);
     }
 
     /**
-     * Throw a reference error (ECMA 15.11.6.3)
+     * Create a reference error (ECMA 15.11.6.3)
      *
      * @param global  global scope object
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("reference.error." + msgId, args);
-        throwError(((GlobalObject)global).newReferenceError(msg), cause);
+        return error(((GlobalObject)global).newReferenceError(msg), cause);
     }
 
     /**
-     * Throw a URI error (ECMA 15.11.6.6)
+     * Create a URI error (ECMA 15.11.6.6)
      *
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void uriError(final String msgId, final String... args) {
-        uriError(Context.getGlobalTrusted(), msgId, args);
+    public static ECMAException uriError(final String msgId, final String... args) {
+        return uriError(Context.getGlobalTrusted(), msgId, args);
     }
 
     /**
-     * Throw a URI error (ECMA 15.11.6.6)
+     * Create a URI error (ECMA 15.11.6.6)
      *
      * @param global  global scope object
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void uriError(final ScriptObject global, final String msgId, final String... args) {
-        uriError(global, null, msgId, args);
+    public static ECMAException uriError(final ScriptObject global, final String msgId, final String... args) {
+        return uriError(global, null, msgId, args);
     }
 
     /**
-     * Throw a URI error (ECMA 15.11.6.6)
+     * Create a URI error (ECMA 15.11.6.6)
      *
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void uriError(final Throwable cause, final String msgId, final String... args) {
-        uriError(Context.getGlobalTrusted(), cause, msgId, args);
+    public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
+        return uriError(Context.getGlobalTrusted(), cause, msgId, args);
     }
 
     /**
-     * Throw a URI error (ECMA 15.11.6.6)
+     * Create a URI error (ECMA 15.11.6.6)
      *
      * @param global  global scope object
      * @param cause   native Java {@code Throwable} that is the cause of error
      * @param msgId   resource tag for error message
      * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
      */
-    public static void uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("uri.error." + msgId, args);
-        throwError(((GlobalObject)global).newURIError(msg), cause);
+        return error(((GlobalObject)global).newURIError(msg), cause);
     }
 
     /**
@@ -356,4 +399,27 @@
         }
     }
 
+
+    /**
+     * Check if a stack trace element is in JavaScript
+     *
+     * @param frame frame
+     *
+     * @return true if frame is in the script
+     */
+    public static boolean isScriptFrame(final StackTraceElement frame) {
+        final String className = frame.getClassName();
+
+        // Look for script package in class name (into which compiler puts generated code)
+        if (className.startsWith(scriptPackage)) {
+            final String source = frame.getFileName();
+            /*
+             * Make sure that it is not some Java code that Nashorn has in that package!
+             * also, we don't want to report JavaScript code that lives in script engine implementation
+             * We want to report only user's own scripts and not any of our own scripts like "engine.js"
+             */
+            return source != null && !source.endsWith(".java") && !source.contains(NashornException.ENGINE_SCRIPT_SOURCE_NAME);
+        }
+        return false;
+    }
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java	Fri Feb 22 12:22:16 2013 +0100
@@ -33,7 +33,6 @@
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess;
-import jdk.nashorn.internal.scripts.JS$;
 
 /**
  * Exception used to implement ECMAScript "throw" from scripts. The actual thrown
@@ -54,13 +53,6 @@
 
     private static final String EXCEPTION_PROPERTY = "nashornException";
 
-    /** We assume that compiler generates script classes into the known package. */
-    private static final String scriptPackage;
-    static {
-        String name = JS$.class.getName();
-        scriptPackage = name.substring(0, name.lastIndexOf('.'));
-    }
-
     /** Object thrown. */
     public final Object thrown;
 
@@ -74,10 +66,7 @@
      * @param column    column number of throw
      */
     public ECMAException(final Object thrown, final String fileName, final int line, final int column) {
-        super(ScriptRuntime.safeToString(thrown), asThrowable(thrown));
-        setFileName(fileName);
-        setLineNumber(line);
-        setColumnNumber(column);
+        super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column);
         this.thrown = thrown;
         setExceptionToThrown();
     }
@@ -93,8 +82,6 @@
         super(ScriptRuntime.safeToString(thrown), cause);
         this.thrown = thrown;
         setExceptionToThrown();
-        // location is not directly available, get it from stack trace
-        setLocationFromStack();
     }
 
     /**
@@ -143,29 +130,6 @@
     }
 
     /**
-     * Check if a stack trace element is in JavaScript
-     *
-     * @param frame frame
-     *
-     * @return true if frame is in the script
-     */
-    public static boolean isScriptFrame(final StackTraceElement frame) {
-        final String className = frame.getClassName();
-
-        // Look for script package in class name (into which compiler puts generated code)
-        if (className.startsWith(scriptPackage)) {
-            final String source = frame.getFileName();
-            /*
-             * Make sure that it is not some Java code that Nashorn has in that package!
-             * also, we don't want to report JavaScript code that lives in script engine implementation
-             * We want to report only user's own scripts and not any of our own scripts like "engine.js"
-             */
-            return source != null && !source.endsWith(".java") && !source.contains(ENGINE_SCRIPT_SOURCE_NAME);
-        }
-        return false;
-    }
-
-    /**
      * Print the stack trace for a {@code ScriptObject} representing an error
      *
      * @param errObj the error object
@@ -295,23 +259,4 @@
             }
         }
     }
-
-    private void setLocationFromStack() {
-        // This is not so pretty - but it gets the job done. Note that the stack
-        // trace has been already filled by "fillInStackTrace" call from Throwable
-        // constructor and so we don't pay additional cost for it.
-
-        // Find the first JavaScript frame by walking and set file, line from it
-        // Usually, we should be able to find it in just few frames depth.
-        for (final StackTraceElement ste : getStackTrace()) {
-            if (isScriptFrame(ste)) {
-                // Whatever here is compiled from JavaScript code
-                setFileName(ste.getFileName());
-                setLineNumber(ste.getLineNumber());
-                // Hard luck - no column number info
-                setColumnNumber(-1);
-                break;
-            }
-        }
-    }
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java	Fri Feb 22 12:22:16 2013 +0100
@@ -79,7 +79,7 @@
         }
 
         if (limit != 0 && count > limit) {
-            rangeError("too.many.errors", Integer.toString(limit));
+            throw rangeError("too.many.errors", Integer.toString(limit));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Fri Feb 22 12:22:16 2013 +0100
@@ -79,8 +79,7 @@
         try {
             node = parser.parse();
         } catch (final ParserException e) {
-            ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
-            return ScriptRuntime.UNDEFINED;
+            throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
         }
 
         final ScriptObject global = Context.getGlobalTrusted();
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Fri Feb 22 12:22:16 2013 +0100
@@ -248,7 +248,7 @@
         final Object       result = sobj.getDefaultValue(hint);
 
         if (!isPrimitive(result)) {
-            typeError("bad.default.value", result.toString());
+            throw typeError("bad.default.value", result.toString());
         }
 
         return result;
@@ -823,7 +823,7 @@
      */
     public static Object toScriptObject(final ScriptObject global, final Object obj) {
         if (nullOrUndefined(obj)) {
-            typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
+            throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
         }
 
         if (obj instanceof ScriptObject) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java	Fri Feb 22 12:22:16 2013 +0100
@@ -34,11 +34,11 @@
 @SuppressWarnings("serial")
 public final class ParserException extends NashornException {
     // Source from which this ParserException originated
-    private Source source;
+    private final Source source;
     // token responsible for this exception
-    private long token;
+    private final long token;
     // if this is traslated as ECMA error, which type should be used?
-    private JSErrorType errorType;
+    private final JSErrorType errorType;
 
     /**
      * Constructor
@@ -46,29 +46,25 @@
      * @param msg exception message for this parser error.
      */
     public ParserException(final String msg) {
-        this(msg, null, -1, -1, -1);
+        this(JSErrorType.SYNTAX_ERROR, msg, null, -1, -1, -1);
     }
 
     /**
      * Constructor
      *
-     * @param msg      exception message
-     * @param source   source from which this exception originates
-     * @param line     line number of exception
-     * @param column   column number of exception
-     * @param token    token from which this exception originates
+     * @param errorType error type
+     * @param msg       exception message
+     * @param source    source from which this exception originates
+     * @param line      line number of exception
+     * @param column    column number of exception
+     * @param token     token from which this exception originates
      *
      */
-    public ParserException(final String msg, final Source source, final int line, final int column, final long token) {
-        super(msg);
-        setSource(source);
-        if (source != null) {
-            setFileName(source.getName());
-        }
-        setLineNumber(line);
-        setColumnNumber(column);
-        setToken(token);
-        setErrorType(JSErrorType.SYNTAX_ERROR);
+    public ParserException(final JSErrorType errorType, final String msg, final Source source, final int line, final int column, final long token) {
+        super(msg, source != null ? source.getName() : null, line, column);
+        this.source = source;
+        this.token = token;
+        this.errorType = errorType;
     }
 
     /**
@@ -80,14 +76,6 @@
     }
 
     /**
-     * Set the {@code Source} of this {@code ParserException}
-     * @param source script source
-     */
-    public void setSource(Source source) {
-        this.source = source;
-    }
-
-    /**
      * Get the token responsible for this {@code ParserException}
      * @return token
      */
@@ -96,14 +84,6 @@
     }
 
     /**
-     * Set the errand token of this {@code ParserException}
-     * @param token token responsible for this ParserException
-     */
-    public void setToken(final long token) {
-        this.token = token;
-    }
-
-    /**
      * Get token position within source where the error originated.
      * @return token position if available, else -1
      */
@@ -120,18 +100,10 @@
     }
 
     /**
-     * Set the {@code JSErrorType} of this {@code ParserException}
-     * @param errorType error type
-     */
-    public void setErrorType(final JSErrorType errorType) {
-        this.errorType = errorType;
-    }
-
-    /**
      * Throw this {@code ParserException} as one of the 7 native JavaScript errors
      */
     public void throwAsEcmaException() {
-        ECMAErrors.throwAsEcmaException(this);
+        throw ECMAErrors.asEcmaException(this);
     }
 
     /**
@@ -139,7 +111,7 @@
      * @param global global scope object
      */
     public void throwAsEcmaException(final ScriptObject global) {
-        ECMAErrors.throwAsEcmaException(global, this);
+        throw ECMAErrors.asEcmaException(global, this);
     }
 }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Fri Feb 22 12:22:16 2013 +0100
@@ -135,7 +135,7 @@
     public boolean isInstance(final ScriptObject instance) {
         final Object basePrototype = getTargetFunction().getPrototype();
         if (!(basePrototype instanceof ScriptObject)) {
-            typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype));
+            throw typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype));
         }
 
         for (ScriptObject proto = instance.getProto(); proto != null; proto = proto.getProto()) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Fri Feb 22 12:22:16 2013 +0100
@@ -290,7 +290,7 @@
 
     MethodHandle getBestConstructor(MethodType descType) {
         if (!isConstructor()) {
-            typeError("not.a.constructor", toSource());
+            throw typeError("not.a.constructor", toSource());
         }
         return SpecializedMethodChooser.candidateWithLowestWeight(descType, getConstructor(), getConstructSpecializations());
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Feb 22 12:22:16 2013 +0100
@@ -278,13 +278,13 @@
         final PropertyDescriptor desc;
         if (isDataDescriptor()) {
             if (has(SET) || has(GET)) {
-                typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
             }
 
             desc = global.newDataDescriptor(UNDEFINED, false, false, false);
         } else if (isAccessorDescriptor()) {
             if (has(VALUE) || has(WRITABLE)) {
-                typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
             }
 
             desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
@@ -308,8 +308,7 @@
             return ((ScriptObject)obj).toPropertyDescriptor();
         }
 
-        typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
-        return null;
+        throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
     }
 
     /**
@@ -401,7 +400,7 @@
             }
             // new property added to non-extensible object
             if (reject) {
-                typeError(global, "object.non.extensible", name, ScriptRuntime.safeToString(this));
+                throw typeError(global, "object.non.extensible", name, ScriptRuntime.safeToString(this));
             }
             return false;
         }
@@ -424,7 +423,7 @@
             if (newDesc.has(CONFIGURABLE) && newDesc.isConfigurable()) {
                 // not configurable can not be made configurable
                 if (reject) {
-                    typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -433,7 +432,7 @@
                 currentDesc.isEnumerable() != newDesc.isEnumerable()) {
                 // cannot make non-enumerable as enumerable or vice-versa
                 if (reject) {
-                    typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -448,7 +447,7 @@
                 if (newDesc.has(WRITABLE) && newDesc.isWritable() ||
                     newDesc.has(VALUE) && ! ScriptRuntime.sameValue(currentDesc.getValue(), newDesc.getValue())) {
                     if (reject) {
-                        typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                        throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
                     }
                     return false;
                 }
@@ -477,7 +476,7 @@
                 if (newDesc.has(PropertyDescriptor.GET) && ! ScriptRuntime.sameValue(currentDesc.getGetter(), newDesc.getGetter()) ||
                     newDesc.has(PropertyDescriptor.SET) && ! ScriptRuntime.sameValue(currentDesc.getSetter(), newDesc.getSetter())) {
                     if (reject) {
-                        typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                        throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
                     }
                     return false;
                 }
@@ -492,7 +491,7 @@
             if (! currentDesc.isConfigurable()) {
                 // not configurable can not be made configurable
                 if (reject) {
-                    typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
                 }
                 return false;
             }
@@ -1150,7 +1149,7 @@
             if (newProtoObject instanceof ScriptObject) {
                 setProto((ScriptObject)newProtoObject);
             } else {
-                typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
+                throw typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
             }
         }
     }
@@ -1638,8 +1637,7 @@
     }
 
     private GuardedInvocation notAFunction() {
-        typeError("not.a.function", ScriptRuntime.safeToString(this));
-        return null;
+        throw typeError("not.a.function", ScriptRuntime.safeToString(this));
     }
 
     /**
@@ -1815,7 +1813,7 @@
     private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, String strictErrorMessage, boolean canBeFastScope) {
         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
         if (NashornCallSiteDescriptor.isStrict(desc)) {
-               typeError(strictErrorMessage, name, ScriptRuntime.safeToString((this)));
+               throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString((this)));
            }
            assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
            final PropertyMap myMap = getMap();
@@ -1842,8 +1840,7 @@
     private boolean trySetEmbedOrSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final Object value) {
         final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
         if (!isExtensible() && isStrict) {
-            typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(this));
-            throw new AssertionError(); // never reached
+            throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(this));
         } else if (compareAndSetMap(oldMap, newMap)) {
             return true;
         } else {
@@ -1859,7 +1856,7 @@
 
         if (!obj.isExtensible()) {
             if (isStrict) {
-                typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+                throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
             }
         } else if (obj.compareAndSetMap(oldMap, newMap)) {
             obj.spill = new Object[SPILL_RATE];
@@ -1876,7 +1873,7 @@
 
         if (!obj.isExtensible()) {
             if (isStrict) {
-                typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+                throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
             }
         } else if (obj.compareAndSetMap(oldMap, newMap)) {
             final int oldLength = obj.spill.length;
@@ -1968,7 +1965,7 @@
         }
 
         if (scopeAccess) {
-            referenceError("not.defined", name);
+            throw referenceError("not.defined", name);
         }
 
         return createEmptyGetter(desc, name);
@@ -2569,7 +2566,7 @@
         if (longIndex >= oldLength) {
             if (!isExtensible()) {
                 if (strict) {
-                    typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this));
+                    throw typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this));
                 }
                 return;
             }
@@ -2618,7 +2615,7 @@
         if (f != null) {
             if (!f.getProperty().isWritable()) {
                 if (strict) {
-                    typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
+                    throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
                 }
 
                 return;
@@ -2634,7 +2631,7 @@
             }
         } else if (!isExtensible()) {
             if (strict) {
-                typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
+                throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
             }
         } else {
             spill(key, value);
@@ -3121,7 +3118,7 @@
 
         if (!find.getProperty().isConfigurable()) {
             if (strict) {
-                typeError("cant.delete.property", propName, ScriptRuntime.safeToString(this));
+                throw typeError("cant.delete.property", propName, ScriptRuntime.safeToString(this));
             }
             return false;
         }
@@ -3291,7 +3288,7 @@
                 throw new RuntimeException(t);
             }
         }  else if (name != null) {
-            typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
+            throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Fri Feb 22 12:22:16 2013 +0100
@@ -426,9 +426,9 @@
     public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
         final ScriptObject global = Context.getGlobalTrusted();
         if (expression == UNDEFINED) {
-            typeError(global, "cant.apply.with.to.undefined");
+            throw typeError(global, "cant.apply.with.to.undefined");
         } else if (expression == null) {
-            typeError(global, "cant.apply.with.to.null");
+            throw typeError(global, "cant.apply.with.to.null");
         }
 
         final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression));
@@ -527,7 +527,7 @@
             } else if (object instanceof Undefined) {
                 obj = ((Undefined)obj).get(property);
             } else if (object == null) {
-                typeError("cant.get.property", safeToString(property), "null");
+                throw typeError("cant.get.property", safeToString(property), "null");
             } else if (JSType.isPrimitive(obj)) {
                 obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property);
             } else {
@@ -565,8 +565,7 @@
      * @return undefined
      */
     public static Object REFERENCE_ERROR(final Object lhs, final Object rhs, final Object msg) {
-        referenceError("cant.be.used.as.lhs", Objects.toString(msg));
-        return UNDEFINED;
+        throw referenceError("cant.be.used.as.lhs", Objects.toString(msg));
     }
 
     /**
@@ -588,7 +587,7 @@
         }
 
         if (obj == null) {
-            typeError("cant.delete.property", safeToString(property), "null");
+            throw typeError("cant.delete.property", safeToString(property), "null");
         }
 
         if (JSType.isPrimitive(obj)) {
@@ -612,7 +611,7 @@
      */
     public static boolean FAIL_DELETE(final Object property, final Object strict) {
         if (Boolean.TRUE.equals(strict)) {
-            syntaxError("strict.cant.delete", safeToString(property));
+            throw syntaxError("strict.cant.delete", safeToString(property));
         }
         return false;
     }
@@ -789,9 +788,7 @@
             return false;
         }
 
-        typeError("in.with.non.object", rvalType.toString().toLowerCase());
-
-        return false;
+        throw typeError("in.with.non.object", rvalType.toString().toLowerCase());
     }
 
     /**
@@ -814,9 +811,7 @@
             return ((StaticClass)clazz).getRepresentedClass().isInstance(obj);
         }
 
-        typeError("instanceof.on.non.object");
-
-        return false;
+        throw typeError("instanceof.on.non.object");
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Fri Feb 22 12:22:16 2013 +0100
@@ -109,8 +109,7 @@
         }
 
         if (f == null || !f.isFile()) {
-            typeError("not.a.file", ScriptRuntime.safeToString(file));
-            return UNDEFINED;
+            throw typeError("not.a.file", ScriptRuntime.safeToString(file));
         }
 
         return new String(Source.readFully(f));
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Fri Feb 22 12:22:16 2013 +0100
@@ -139,7 +139,7 @@
         // In strict mode, assignment can not create a new variable.
         // See also ECMA Annex C item 4. ReferenceError is thrown.
         if (NashornCallSiteDescriptor.isScope(desc) && NashornCallSiteDescriptor.isStrict(desc)) {
-            referenceError("not.defined", getName());
+            throw referenceError("not.defined", getName());
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java	Fri Feb 22 12:22:16 2013 +0100
@@ -93,8 +93,7 @@
             try {
                 sb.append(toHexEscape(V));
             } catch (final Exception e) {
-                uriError( e, "bad.uri", string, Integer.toString(k));
-                return null;
+                throw uriError(e, "bad.uri", string, Integer.toString(k));
             }
         }
 
@@ -179,8 +178,7 @@
                 try {
                     V = ucs4Char(bbuf);
                 } catch (final Exception e) {
-                    uriError(e, "bad.uri", string, Integer.toString(k));
-                    return null;
+                    throw uriError(e, "bad.uri", string, Integer.toString(k));
                 }
                 if (V < 0x10000) {
                     C = (char) V;
@@ -269,8 +267,7 @@
     }
 
     private static String error(final String string, final int index) {
-        uriError("bad.uri", string, Integer.toString(index));
-        return null;
+        throw uriError("bad.uri", string, Integer.toString(index));
     }
 
     // 'uriEscaped' except for alphanumeric chars
--- a/nashorn/src/jdk/nashorn/internal/runtime/Undefined.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Undefined.java	Fri Feb 22 12:22:16 2013 +0100
@@ -97,30 +97,26 @@
         switch (operator) {
         case "new":
         case "call":
-            lookupTypeError("cant.call.undefined", desc);
-            break;
+            throw lookupTypeError("cant.call.undefined", desc);
         case "callMethod":
-            lookupTypeError("cant.read.property.of.undefined", desc);
+            throw lookupTypeError("cant.read.property.of.undefined", desc);
         // NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself
         // emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are
         // more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the
         // operation has an associated name or not.
-            break;
         case "getProp":
         case "getElem":
         case "getMethod":
             if (desc.getNameTokenCount() < 3) {
                 return findGetIndexMethod(desc);
             }
-            lookupTypeError("cant.read.property.of.undefined", desc);
-            break;
+            throw lookupTypeError("cant.read.property.of.undefined", desc);
         case "setProp":
         case "setElem":
             if (desc.getNameTokenCount() < 3) {
                 return findSetIndexMethod(desc);
             }
-            lookupTypeError("cant.set.property.of.undefined", desc);
-            break;
+            throw lookupTypeError("cant.set.property.of.undefined", desc);
         default:
             break;
         }
@@ -128,8 +124,8 @@
         return null;
     }
 
-    private static void lookupTypeError(final String msg, final CallSiteDescriptor desc) {
-        typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null);
+    private static ECMAException lookupTypeError(final String msg, final CallSiteDescriptor desc) {
+        return typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null);
     }
 
     /**
@@ -174,19 +170,17 @@
 
     @Override
     public Object get(final Object key) {
-        typeError("cant.read.property.of.undefined", ScriptRuntime.safeToString(key));
-        return ScriptRuntime.UNDEFINED;
+        throw typeError("cant.read.property.of.undefined", ScriptRuntime.safeToString(key));
     }
 
     @Override
     public void set(final Object key, final Object value, final boolean strict) {
-        typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key));
+        throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key));
     }
 
     @Override
     public boolean delete(final Object key, final boolean strict) {
-        typeError("cant.delete.property.of.undefined", ScriptRuntime.safeToString(key));
-        return false;
+        throw typeError("cant.delete.property.of.undefined", ScriptRuntime.safeToString(key));
     }
 
     @Override
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Fri Feb 22 12:22:16 2013 +0100
@@ -46,7 +46,7 @@
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         if (strict) {
-            typeError("cant.set.property", Integer.toString(index), "frozen array");
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
         }
         return this;
     }
@@ -54,7 +54,7 @@
     @Override
     public ArrayData set(final int index, final long value, final boolean strict) {
         if (strict) {
-            typeError("cant.set.property", Integer.toString(index), "frozen array");
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
         }
         return this;
     }
@@ -62,7 +62,7 @@
     @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (strict) {
-            typeError("cant.set.property", Integer.toString(index), "frozen array");
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
         }
         return this;
     }
@@ -70,7 +70,7 @@
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
         if (strict) {
-            typeError("cant.set.property", Integer.toString(index), "frozen array");
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
         }
         return this;
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java	Fri Feb 22 12:22:16 2013 +0100
@@ -97,8 +97,7 @@
      */
     public final T apply() {
         if (!(callbackfn instanceof ScriptFunction)) {
-            typeError("not.a.function", ScriptRuntime.safeToString(callbackfn));
-            return result;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(callbackfn));
         }
         final ScriptFunction func = ((ScriptFunction)callbackfn);
         // for non-strict callback, need to translate undefined thisArg to be global object
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Fri Feb 22 12:22:16 2013 +0100
@@ -46,7 +46,7 @@
     @Override
     public boolean canDelete(final int index, final boolean strict) {
         if (strict) {
-            typeError("cant.delete.property", Integer.toString(index), "sealed array");
+            throw typeError("cant.delete.property", Integer.toString(index), "sealed array");
         }
         return false;
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Fri Feb 22 12:22:16 2013 +0100
@@ -705,8 +705,7 @@
      */
     public static MethodHandle getHandle(final Object obj, final String name, final MethodType type, final boolean varArg) {
         if (! (obj instanceof ScriptObject)) {
-            typeError("not.an.object", ScriptRuntime.safeToString(obj));
-            throw new AssertionError();
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
         }
 
         final ScriptObject sobj = (ScriptObject)obj;
@@ -721,8 +720,7 @@
         } else if(fnObj == null || fnObj instanceof Undefined) {
             return null;
         } else {
-            typeError("not.a.function", name);
-            throw new AssertionError();
+            throw typeError("not.a.function", name);
         }
     }
 
@@ -1093,7 +1091,7 @@
 
         void typeError() {
             assert adaptationOutcome != AdaptationOutcome.SUCCESS;
-            ECMAErrors.typeError("extend." + adaptationOutcome, classList);
+            throw ECMAErrors.typeError("extend." + adaptationOutcome, classList);
         }
     }
 
@@ -1236,8 +1234,7 @@
         while(it.hasNext()) {
             b.append(", ").append(it.next().clazz.getCanonicalName());
         }
-        typeError("extend.ambiguous.defining.class", b.toString());
-        throw new AssertionError(); // never reached
+        throw typeError("extend.ambiguous.defining.class", b.toString());
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Fri Feb 22 12:22:16 2013 +0100
@@ -109,7 +109,7 @@
                 return Character.valueOf((char) ival);
             }
 
-            typeError("cant.convert.number.to.char");
+            throw typeError("cant.convert.number.to.char");
         }
 
         final String s = toString(o);
@@ -118,7 +118,7 @@
         }
 
         if (s.length() != 1) {
-            typeError("cant.convert.string.to.char");
+            throw typeError("cant.convert.string.to.char");
         }
 
         return s.charAt(0);
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Lookup.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Lookup.java	Fri Feb 22 12:22:16 2013 +0100
@@ -111,8 +111,7 @@
      * @return undefined (but throws error before return point)
      */
     public static Object typeErrorThrowerGetter(final Object self) {
-        typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
-        return UNDEFINED;
+        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
     }
 
     /**
@@ -122,7 +121,7 @@
      * @param value (ignored)
      */
     public static void typeErrorThrowerSetter(final Object self, final Object value) {
-        typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
+        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Fri Feb 22 12:22:16 2013 +0100
@@ -80,22 +80,17 @@
         switch (operator) {
         case "new":
             if(BeansLinker.isDynamicMethod(self)) {
-                typeError("method.not.constructor", ScriptRuntime.safeToString(self));
-            } else {
-                typeError("not.a.function", ScriptRuntime.safeToString(self));
+                throw typeError("method.not.constructor", ScriptRuntime.safeToString(self));
             }
-            break;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         case "call":
             if(BeansLinker.isDynamicMethod(self)) {
-                typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
-            } else {
-                typeError("not.a.function", ScriptRuntime.safeToString(self));
+                throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
             }
-            break;
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         case "callMethod":
         case "getMethod":
-            typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
-            break;
+            throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
         case "getProp":
         case "getElem":
             if (desc.getOperand() != null) {
@@ -130,20 +125,16 @@
         switch (operator) {
         case "new":
         case "call":
-            typeError("not.a.function", "null");
-            break;
+            throw typeError("not.a.function", "null");
         case "callMethod":
         case "getMethod":
-            typeError("no.such.function", getArgument(linkRequest), "null");
-            break;
+            throw typeError("no.such.function", getArgument(linkRequest), "null");
         case "getProp":
         case "getElem":
-            typeError("cant.get.property", getArgument(linkRequest), "null");
-            break;
+            throw typeError("cant.get.property", getArgument(linkRequest), "null");
         case "setProp":
         case "setElem":
-            typeError("cant.set.property", getArgument(linkRequest), "null");
-            break;
+            throw typeError("cant.set.property", getArgument(linkRequest), "null");
         default:
             break;
         }
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Fri Feb 22 11:27:40 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Fri Feb 22 12:22:16 2013 +0100
@@ -93,7 +93,7 @@
 
     private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class<?> receiverClass) {
         if(ctorInvocation == null) {
-            ECMAErrors.typeError("no.constructor.matches.args", receiverClass.getName());
+            throw ECMAErrors.typeError("no.constructor.matches.args", receiverClass.getName());
         }
         return ctorInvocation;
     }