/** * ECMA 15.11.4.4 Error.prototype.toString ( ) * * @param self self reference * @return this NativeError as a string */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object toString(final Object self) { // Step 1 and 2 : check if 'self' is object it not throw TypeError final ScriptObject sobj = Global.checkObject(self); // Step 3 & 4 : get "name" and convert to String. // But if message is undefined make it "Error". Object name = sobj.get("name"); if (name == UNDEFINED) { name = "Error"; } else { name = JSType.toString(name); } // Steps 5, 6, & 7 : get "message" and convert to String. // if 'message' is undefined make it "" (empty String). Object msg = sobj.get("message"); if (msg == UNDEFINED) { msg = ""; } else { msg = JSType.toString(msg); } // Step 8 : if name is empty, return msg if (((String) name).isEmpty()) { return msg; } // Step 9 : if message is empty, return name if (((String) msg).isEmpty()) { return name; } // Step 10 : return name + ": " + msg return name + ": " + msg; }
/** * Nashorn extension: Error.prototype.columnNumber * * @param self self reference * @param value value of column number * @return value that was set */ public static Object setColumnNumber(final Object self, final Object value) { final ScriptObject sobj = Global.checkObject(self); if (sobj.hasOwnProperty(COLUMNNUMBER)) { sobj.put(COLUMNNUMBER, value, false); } else { sobj.addOwnProperty(COLUMNNUMBER, Attribute.NOT_ENUMERABLE, value); } return value; }
/** * Nashorn extension Accessed from {@link Global} while setting up the Error.prototype * * @param self self reference * @param value value to set "stack" property to, must be {@code ScriptObject} * @return value that was set */ public static Object setStack(final Object self, final Object value) { final ScriptObject sobj = Global.checkObject(self); if (sobj.hasOwnProperty(STACK)) { sobj.put(STACK, value, false); } else { sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value); } return value; }
/** * Nashorn extension: Error.prototype.fileName * * @param self self reference * @param value value of file name * @return value that was set */ public static Object setFileName(final Object self, final Object value) { final ScriptObject sobj = Global.checkObject(self); if (sobj.hasOwnProperty(FILENAME)) { sobj.put(FILENAME, value, false); } else { sobj.addOwnProperty(FILENAME, Attribute.NOT_ENUMERABLE, value); } return value; }
/** * 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 */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object captureStackTrace(final Object self, final Object errorObj) { final ScriptObject sobj = Global.checkObject(errorObj); 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; }
/** * Declares a symbol name as belonging to a non-scoped local variable during an on-demand * compilation of a single function. This method will add an explicit Undefined binding for the * local into the runtime scope if it's otherwise implicitly undefined so that when an expression * is evaluated for the name, it won't accidentally find an unrelated value higher up the scope * chain. It is only required to call this method when doing an optimistic on-demand compilation. * * @param symbolName the name of the symbol that is to be declared as being a non-scoped local * variable. */ void declareLocalSymbol(final String symbolName) { assert compiler.useOptimisticTypes() && compiler.isOnDemandCompilation() && runtimeScope != null : "useOptimistic=" + compiler.useOptimisticTypes() + " isOnDemand=" + compiler.isOnDemandCompilation() + " scope=" + runtimeScope; if (runtimeScope.findProperty(symbolName, false) == null) { runtimeScope.addOwnProperty( symbolName, NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE, ScriptRuntime.UNDEFINED); } }
private static Object evaluatePropertySafely(final ScriptObject sobj, final String name) { final FindProperty find = sobj.findProperty(name, true); if (find == null) { return null; } final Property property = find.getProperty(); final ScriptObject owner = find.getOwner(); if (property.hasGetterFunction(owner)) { // Possible side effects; can't evaluate safely return null; } return property.getObjectValue(owner, owner); }
private static Type getPropertyType(final ScriptObject sobj, final String name) { final FindProperty find = sobj.findProperty(name, true); if (find == null) { return null; } final Property property = find.getProperty(); final Class<?> propertyClass = property.getType(); if (propertyClass == null) { // propertyClass == null means its value is Undefined. It is probably not initialized yet, so // we won't make // a type assumption yet. return null; } else if (propertyClass.isPrimitive()) { return Type.typeFor(propertyClass); } final ScriptObject owner = find.getOwner(); if (property.hasGetterFunction(owner)) { // Can have side effects, so we can't safely evaluate it; since !propertyClass.isPrimitive(), // it's Object. return Type.OBJECT; } // Safely evaluate the property, and return the narrowest type for the actual value (e.g. // Type.INT for a boxed // integer). final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner); if (value == ScriptRuntime.UNDEFINED) { return null; } return Type.typeFor(JSType.unboxedFieldType(value)); }
/** * Nashorn extension: Error.prototype.stack "stack" property is a string typed value containing * JavaScript stack frames. Each frame information is separated bv "\n" character. * * @param self self reference * @return value of "stack" property */ public static Object getStack(final Object self) { final ScriptObject sobj = Global.checkObject(self); if (sobj.has(STACK)) { return sobj.get(STACK); } final Object exception = ECMAException.getException(sobj); if (exception instanceof Throwable) { final Object value = getScriptStackString(sobj, (Throwable) exception); if (sobj.hasOwnProperty(STACK)) { sobj.put(STACK, value, false); } else { sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value); } return value; } return UNDEFINED; }
/** * Nashorn extension: Error.prototype.fileName * * @param self self reference * @return file name from which error was thrown */ public static Object getFileName(final Object self) { final ScriptObject sobj = Global.checkObject(self); return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject) self); }
/** * Nashorn extension: Error.prototype.columnNumber * * @param self self reference * @return column number from which error was thrown */ public static Object getColumnNumber(final Object self) { final ScriptObject sobj = Global.checkObject(self); return sobj.has(COLUMNNUMBER) ? sobj.get(COLUMNNUMBER) : ECMAException.getColumnNumber((ScriptObject) self); }
/** * Nashorn extension: Error.prototype.lineNumber * * @param self self reference * @return line number from which error was thrown */ public static Object getLineNumber(final Object self) { final ScriptObject sobj = Global.checkObject(self); return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj); }