127 Thread.dumpStack(); 128 return UNDEFINED; 129 } 130 131 /** 132 * Nashorn extension: Error.prototype.printStackTrace 133 * prints stack trace associated with the exception (if available). 134 * to the standard error stream. 135 * 136 * @param self self reference 137 * 138 * @return result of {@link ECMAException#printStackTrace(ScriptObject)}, which is typically undefined 139 */ 140 @Function(attributes = Attribute.NOT_ENUMERABLE) 141 public static Object printStackTrace(final Object self) { 142 Global.checkObject(self); 143 return ECMAException.printStackTrace((ScriptObject)self); 144 } 145 146 /** 147 * Nashorn extension: Error.prototype.lineNumber 148 * 149 * @param self self reference 150 * 151 * @return line number from which error was thrown 152 */ 153 public static Object getLineNumber(final Object self) { 154 Global.checkObject(self); 155 final ScriptObject sobj = (ScriptObject)self; 156 return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj); 157 } 158 159 /** 160 * Nashorn extension: Error.prototype.lineNumber 161 * 162 * @param self self reference 163 * @param value value of line number 164 * 165 * @return value that was set 166 */ 212 return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject)self); 213 } 214 215 /** 216 * Nashorn extension: Error.prototype.fileName 217 * 218 * @param self self reference 219 * @param value value of file name 220 * 221 * @return value that was set 222 */ 223 public static Object setFileName(final Object self, final Object value) { 224 Global.checkObject(self); 225 final ScriptObject sobj = (ScriptObject)self; 226 sobj.set(FILENAME, value, false); 227 return value; 228 } 229 230 /** 231 * Nashorn extension: Error.prototype.stack 232 * "stack" property is an array typed value containing {@link StackTraceElement} 233 * objects of JavaScript stack frames. 234 * 235 * @param self self reference 236 * 237 * @return value of "stack" property 238 */ 239 public static Object getStack(final Object self) { 240 Global.checkObject(self); 241 final ScriptObject sobj = (ScriptObject)self; 242 if (sobj.has(STACK)) { 243 return sobj.get(STACK); 244 } 245 246 final Object exception = ECMAException.getException(sobj); 247 Object[] res; 248 if (exception instanceof Throwable) { 249 final StackTraceElement[] frames = ((Throwable)exception).getStackTrace(); 250 final List<StackTraceElement> filtered = new ArrayList<>(); 251 for (final StackTraceElement st : frames) { 252 if (ECMAErrors.isScriptFrame(st)) { 253 final String className = "<" + st.getFileName() + ">"; 254 String methodName = st.getMethodName(); 255 if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { 256 methodName = "<program>"; 257 } 258 filtered.add(new StackTraceElement(className, methodName, 259 st.getFileName(), st.getLineNumber())); 260 } 261 } 262 res = filtered.toArray(); 263 } else { 264 res = ScriptRuntime.EMPTY_ARRAY; 265 } 266 267 return new NativeArray(res); 268 } 269 270 /** 271 * Nashorn extension 272 * Accessed from {@link Global} while setting up the Error.prototype 273 * 274 * @param self self reference 275 * @param value value to set "stack" property to, must be {@code ScriptObject} 276 * 277 * @return value that was set 278 */ 279 public static Object setStack(final Object self, final Object value) { 280 Global.checkObject(self); 281 final ScriptObject sobj = (ScriptObject)self; 282 sobj.set(STACK, value, false); 283 return value; 284 } 285 286 /** 287 * ECMA 15.11.4.4 Error.prototype.toString ( ) 317 318 // Step 8 : if name is empty, return msg 319 if (((String)name).isEmpty()) { 320 return msg; 321 } 322 323 // Step 9 : if message is empty, return name 324 if (((String)msg).isEmpty()) { 325 return name; 326 } 327 // Step 10 : return name + ": " + msg 328 return name + ": " + msg; 329 } 330 331 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { 332 try { 333 return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types)); 334 } catch (final NoSuchMethodException | IllegalAccessException e) { 335 throw new MethodHandleFactory.LookupException(e); 336 } 337 } 338 } | 127 Thread.dumpStack(); 128 return UNDEFINED; 129 } 130 131 /** 132 * Nashorn extension: Error.prototype.printStackTrace 133 * prints stack trace associated with the exception (if available). 134 * to the standard error stream. 135 * 136 * @param self self reference 137 * 138 * @return result of {@link ECMAException#printStackTrace(ScriptObject)}, which is typically undefined 139 */ 140 @Function(attributes = Attribute.NOT_ENUMERABLE) 141 public static Object printStackTrace(final Object self) { 142 Global.checkObject(self); 143 return ECMAException.printStackTrace((ScriptObject)self); 144 } 145 146 /** 147 * Nashorn extension: Error.prototype.getStackTrace() 148 * "stack" property is an array typed value containing {@link StackTraceElement} 149 * objects of JavaScript stack frames. 150 * 151 * @param self self reference 152 * 153 * @return stack trace as a script array. 154 */ 155 @Function(attributes = Attribute.NOT_ENUMERABLE) 156 public static Object getStackTrace(final Object self) { 157 Global.checkObject(self); 158 final ScriptObject sobj = (ScriptObject)self; 159 if (sobj.has(STACK)) { 160 return sobj.get(STACK); 161 } 162 163 final Object exception = ECMAException.getException(sobj); 164 Object[] res; 165 if (exception instanceof Throwable) { 166 res = getScriptFrames((Throwable)exception); 167 } else { 168 res = ScriptRuntime.EMPTY_ARRAY; 169 } 170 171 return new NativeArray(res); 172 } 173 174 /** 175 * Nashorn extension: Error.prototype.lineNumber 176 * 177 * @param self self reference 178 * 179 * @return line number from which error was thrown 180 */ 181 public static Object getLineNumber(final Object self) { 182 Global.checkObject(self); 183 final ScriptObject sobj = (ScriptObject)self; 184 return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj); 185 } 186 187 /** 188 * Nashorn extension: Error.prototype.lineNumber 189 * 190 * @param self self reference 191 * @param value value of line number 192 * 193 * @return value that was set 194 */ 240 return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject)self); 241 } 242 243 /** 244 * Nashorn extension: Error.prototype.fileName 245 * 246 * @param self self reference 247 * @param value value of file name 248 * 249 * @return value that was set 250 */ 251 public static Object setFileName(final Object self, final Object value) { 252 Global.checkObject(self); 253 final ScriptObject sobj = (ScriptObject)self; 254 sobj.set(FILENAME, value, false); 255 return value; 256 } 257 258 /** 259 * Nashorn extension: Error.prototype.stack 260 * "stack" property is a string typed value containing JavaScript stack frames. 261 * Each frame information is separated bv "\n" character. 262 * 263 * @param self self reference 264 * 265 * @return value of "stack" property 266 */ 267 public static Object getStack(final Object self) { 268 Global.checkObject(self); 269 final ScriptObject sobj = (ScriptObject)self; 270 if (sobj.has(STACK)) { 271 return sobj.get(STACK); 272 } 273 274 final Object exception = ECMAException.getException(sobj); 275 final StringBuilder buf = new StringBuilder(); 276 if (exception instanceof Throwable) { 277 final Object[] frames = getScriptFrames((Throwable)exception); 278 for (final Object fr : frames) { 279 final StackTraceElement st = (StackTraceElement)fr; 280 buf.append(st.getMethodName()); 281 buf.append(" @ "); 282 buf.append(st.getFileName()); 283 buf.append(':'); 284 buf.append(st.getLineNumber()); 285 buf.append('\n'); 286 } 287 final int len = buf.length(); 288 // remove trailing '\n' 289 if (len > 0) { 290 assert buf.charAt(len - 1) == '\n'; 291 buf.deleteCharAt(len - 1); 292 } 293 return buf.toString(); 294 } else { 295 return ""; 296 } 297 } 298 299 /** 300 * Nashorn extension 301 * Accessed from {@link Global} while setting up the Error.prototype 302 * 303 * @param self self reference 304 * @param value value to set "stack" property to, must be {@code ScriptObject} 305 * 306 * @return value that was set 307 */ 308 public static Object setStack(final Object self, final Object value) { 309 Global.checkObject(self); 310 final ScriptObject sobj = (ScriptObject)self; 311 sobj.set(STACK, value, false); 312 return value; 313 } 314 315 /** 316 * ECMA 15.11.4.4 Error.prototype.toString ( ) 346 347 // Step 8 : if name is empty, return msg 348 if (((String)name).isEmpty()) { 349 return msg; 350 } 351 352 // Step 9 : if message is empty, return name 353 if (((String)msg).isEmpty()) { 354 return name; 355 } 356 // Step 10 : return name + ": " + msg 357 return name + ": " + msg; 358 } 359 360 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { 361 try { 362 return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types)); 363 } catch (final NoSuchMethodException | IllegalAccessException e) { 364 throw new MethodHandleFactory.LookupException(e); 365 } 366 } 367 368 private static Object[] getScriptFrames(final Throwable exception) { 369 final StackTraceElement[] frames = ((Throwable)exception).getStackTrace(); 370 final List<StackTraceElement> filtered = new ArrayList<>(); 371 for (final StackTraceElement st : frames) { 372 if (ECMAErrors.isScriptFrame(st)) { 373 final String className = "<" + st.getFileName() + ">"; 374 String methodName = st.getMethodName(); 375 if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { 376 methodName = "<program>"; 377 } 378 filtered.add(new StackTraceElement(className, methodName, 379 st.getFileName(), st.getLineNumber())); 380 } 381 } 382 return filtered.toArray(); 383 } 384 } |