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

Print this page

        

@@ -36,11 +36,10 @@
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
 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.objects.ScriptFunctionImpl;
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptFunction;

@@ -91,17 +90,19 @@
 
     static PropertyMap getInitialMap() {
         return $nasgenmap$;
     }
 
+    @SuppressWarnings("LeakingThisInConstructor")
     private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        initException(this);
     }
 
     NativeError(final Object msg, final Global global) {
         this(msg, global.getErrorPrototype(), global.getErrorMap());
     }

@@ -127,27 +128,36 @@
     @Constructor
     public static Object constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeError(msg);
     }
 
+    // This is called NativeError, NativeTypeError etc. to
+    // associate a ECMAException with the ECMA Error object.
+    @SuppressWarnings("unused")
+    static void initException(final ScriptObject self) {
+        // ECMAException constructor has side effects
+        new ECMAException(self, null);
+    }
+
     /**
      * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
      *
      * @param self self reference
      * @param errorObj the error object
      * @return undefined
      */
-    @SuppressWarnings("unused")
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static Object captureStackTrace(final Object self, final Object errorObj) {
         Global.checkObject(errorObj);
         final ScriptObject sobj = (ScriptObject)errorObj;
-        new ECMAException(sobj, null); //constructor has side effects
-        sobj.delete("stack", false);
+        initException(sobj);
+        sobj.delete(STACK, false);
+        if (! sobj.has("stack")) {
         final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
         final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
         sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
+        }
         return UNDEFINED;
     }
 
     /**
      * Nashorn extension: Error.dumpStack

@@ -224,11 +234,15 @@
      * @return value that was set
      */
     public static Object setLineNumber(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(LINENUMBER, value, false);
+        if (sobj.hasOwnProperty(LINENUMBER)) {
+            sobj.put(LINENUMBER, value, false);
+        } else {
+            sobj.addOwnProperty(LINENUMBER, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
     /**
      * Nashorn extension: Error.prototype.columnNumber

@@ -252,11 +266,15 @@
      * @return value that was set
      */
     public static Object setColumnNumber(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(COLUMNNUMBER, value, false);
+        if (sobj.hasOwnProperty(COLUMNNUMBER)) {
+            sobj.put(COLUMNNUMBER, value, false);
+        } else {
+            sobj.addOwnProperty(COLUMNNUMBER, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
     /**
      * Nashorn extension: Error.prototype.fileName

@@ -280,11 +298,15 @@
      * @return value that was set
      */
     public static Object setFileName(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(FILENAME, value, false);
+        if (sobj.hasOwnProperty(FILENAME)) {
+            sobj.put(FILENAME, value, false);
+        } else {
+            sobj.addOwnProperty(FILENAME, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
     /**
      * Nashorn extension: Error.prototype.stack

@@ -302,14 +324,16 @@
             return sobj.get(STACK);
         }
 
         final Object exception = ECMAException.getException(sobj);
         if (exception instanceof Throwable) {
-            return getScriptStackString(sobj, (Throwable)exception);
+            Object value = getScriptStackString(sobj, (Throwable)exception);
+            sobj.put(STACK, value, false);
+            return value;
         }
 
-        return "";
+        return UNDEFINED;
     }
 
     /**
      * Nashorn extension
      * Accessed from {@link Global} while setting up the Error.prototype