1/* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 */ 20 21#include "config.h" 22#include "ErrorPrototype.h" 23 24#include "Error.h" 25#include "JSFunction.h" 26#include "JSString.h" 27#include "JSStringBuilder.h" 28#include "ObjectPrototype.h" 29#include "Operations.h" 30#include "StringRecursionChecker.h" 31 32namespace JSC { 33 34ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorPrototype); 35 36static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*); 37 38} 39 40#include "ErrorPrototype.lut.h" 41 42namespace JSC { 43 44const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, 0, ExecState::errorPrototypeTable, CREATE_METHOD_TABLE(ErrorPrototype) }; 45 46/* Source for ErrorPrototype.lut.h 47@begin errorPrototypeTable 48 toString errorProtoFuncToString DontEnum|Function 0 49@end 50*/ 51 52ErrorPrototype::ErrorPrototype(ExecState* exec, Structure* structure) 53 : ErrorInstance(exec->vm(), structure) 54{ 55} 56 57void ErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject*) 58{ 59 Base::finishCreation(exec->vm(), ""); 60 ASSERT(inherits(&s_info)); 61 putDirect(exec->vm(), exec->propertyNames().name, jsNontrivialString(exec, String(ASCIILiteral("Error"))), DontEnum); 62} 63 64bool ErrorPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot) 65{ 66 return getStaticFunctionSlot<ErrorInstance>(exec, ExecState::errorPrototypeTable(exec), jsCast<ErrorPrototype*>(cell), propertyName, slot); 67} 68 69bool ErrorPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) 70{ 71 return getStaticFunctionDescriptor<ErrorInstance>(exec, ExecState::errorPrototypeTable(exec), jsCast<ErrorPrototype*>(object), propertyName, descriptor); 72} 73 74// ------------------------------ Functions --------------------------- 75 76// ECMA-262 5.1, 15.11.4.4 77EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec) 78{ 79 // 1. Let O be the this value. 80 JSValue thisValue = exec->hostThisValue(); 81 82 // 2. If Type(O) is not Object, throw a TypeError exception. 83 if (!thisValue.isObject()) 84 return throwVMTypeError(exec); 85 JSObject* thisObj = asObject(thisValue); 86 87 // Guard against recursion! 88 StringRecursionChecker checker(exec, thisObj); 89 if (JSValue earlyReturnValue = checker.earlyReturnValue()) 90 return JSValue::encode(earlyReturnValue); 91 92 // 3. Let name be the result of calling the [[Get]] internal method of O with argument "name". 93 JSValue name = thisObj->get(exec, exec->propertyNames().name); 94 if (exec->hadException()) 95 return JSValue::encode(jsUndefined()); 96 97 // 4. If name is undefined, then let name be "Error"; else let name be ToString(name). 98 String nameString; 99 if (name.isUndefined()) 100 nameString = ASCIILiteral("Error"); 101 else { 102 nameString = name.toString(exec)->value(exec); 103 if (exec->hadException()) 104 return JSValue::encode(jsUndefined()); 105 } 106 107 // 5. Let msg be the result of calling the [[Get]] internal method of O with argument "message". 108 JSValue message = thisObj->get(exec, exec->propertyNames().message); 109 if (exec->hadException()) 110 return JSValue::encode(jsUndefined()); 111 112 // (sic) 113 // 6. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). 114 // 7. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). 115 String messageString; 116 if (message.isUndefined()) 117 messageString = String(); 118 else { 119 messageString = message.toString(exec)->value(exec); 120 if (exec->hadException()) 121 return JSValue::encode(jsUndefined()); 122 } 123 124 // 8. If name is the empty String, return msg. 125 if (!nameString.length()) 126 return JSValue::encode(message.isString() ? message : jsString(exec, messageString)); 127 128 // 9. If msg is the empty String, return name. 129 if (!messageString.length()) 130 return JSValue::encode(name.isString() ? name : jsNontrivialString(exec, nameString)); 131 132 // 10. Return the result of concatenating name, ":", a single space character, and msg. 133 return JSValue::encode(jsMakeNontrivialString(exec, nameString, ": ", messageString)); 134} 135 136} // namespace JSC 137