File indexing completed on 2024-05-12 15:43:19

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2003 Apple Computer, Inc.
0005  *
0006  *  This library is free software; you can redistribute it and/or
0007  *  modify it under the terms of the GNU Lesser General Public
0008  *  License as published by the Free Software Foundation; either
0009  *  version 2 of the License, or (at your option) any later version.
0010  *
0011  *  This library is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  *  Lesser General Public License for more details.
0015  *
0016  *  You should have received a copy of the GNU Lesser General Public
0017  *  License along with this library; if not, write to the Free Software
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0019  *
0020  */
0021 
0022 #include "error_object.h"
0023 
0024 #include "value.h"
0025 #include "object.h"
0026 #include "types.h"
0027 #include "interpreter.h"
0028 #include "operations.h"
0029 //#include "debugger.h"
0030 
0031 using namespace KJS;
0032 
0033 // ------------------------------ ErrorInstance ----------------------------
0034 
0035 const ClassInfo ErrorInstance::info = {"Error", nullptr, nullptr, nullptr};
0036 
0037 ErrorInstance::ErrorInstance(JSObject *proto)
0038     : JSObject(proto)
0039 {
0040 }
0041 
0042 // ------------------------------ ErrorPrototype ----------------------------
0043 
0044 // ECMA 15.9.4
0045 ErrorPrototype::ErrorPrototype(ExecState *exec,
0046                                ObjectPrototype *objectProto,
0047                                FunctionPrototype *funcProto)
0048     : ErrorInstance(objectProto)
0049 {
0050     // Interpreter::initGlobalObject sets the constructor property
0051     // on the prototypes for this and the native error types
0052 
0053     put(exec, exec->propertyNames().name,     jsString("Error"), DontEnum);
0054     // ECMA Edition 5.1r6 - 15.11.4.3
0055     // The initial value of Error.prototype.message is the empty String.
0056     put(exec, exec->propertyNames().message,  jsString(""), DontEnum);
0057     putDirectFunction(new ErrorProtoFunc(exec, funcProto, exec->propertyNames().toString), DontEnum);
0058 }
0059 
0060 // ------------------------------ ErrorProtoFunc ----------------------------
0061 
0062 ErrorProtoFunc::ErrorProtoFunc(ExecState *exec, FunctionPrototype *funcProto, const Identifier &name)
0063     : InternalFunctionImp(funcProto, name)
0064 {
0065     putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
0066 }
0067 
0068 JSValue *ErrorProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &/*args*/)
0069 {
0070     // toString()
0071     UString name;
0072     JSValue *v = thisObj->get(exec, exec->propertyNames().name);
0073     if (!JSValue::isUndefined(v)) {
0074         name = JSValue::toString(v, exec);
0075     } else {
0076         name = "Error";
0077     }
0078 
0079     UString message;
0080     v = thisObj->get(exec, exec->propertyNames().message);
0081     if (!JSValue::isUndefined(v)) {
0082         message = JSValue::toString(v, exec);
0083     }
0084 
0085     if (name.isEmpty()) {
0086         return jsString(message);
0087     }
0088     if (message.isEmpty()) {
0089         return jsString(name);
0090     }
0091 
0092     return jsString(name + ": " + message);
0093 }
0094 
0095 // ------------------------------ ErrorObjectImp -------------------------------
0096 
0097 ErrorObjectImp::ErrorObjectImp(ExecState *exec, FunctionPrototype *funcProto, ErrorPrototype *errorProto)
0098     : InternalFunctionImp(funcProto)
0099 {
0100     // ECMA 15.11.3.1 Error.prototype
0101     putDirect(exec->propertyNames().prototype, errorProto, DontEnum | DontDelete | ReadOnly);
0102     putDirect(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
0103     //putDirect(namePropertyName, jsString(n));
0104 }
0105 
0106 bool ErrorObjectImp::implementsConstruct() const
0107 {
0108     return true;
0109 }
0110 
0111 // ECMA 15.9.3
0112 JSObject *ErrorObjectImp::construct(ExecState *exec, const List &args)
0113 {
0114     JSObject *proto = static_cast<JSObject *>(exec->lexicalInterpreter()->builtinErrorPrototype());
0115     JSObject *imp = new ErrorInstance(proto);
0116     JSObject *obj(imp);
0117 
0118     if (!JSValue::isUndefined(args[0])) {
0119         imp->putDirect(exec->propertyNames().message, jsString(JSValue::toString(args[0], exec)));
0120     }
0121 
0122     return obj;
0123 }
0124 
0125 // ECMA 15.9.2
0126 JSValue *ErrorObjectImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args)
0127 {
0128     // "Error()" gives the sames result as "new Error()"
0129     return construct(exec, args);
0130 }
0131 
0132 // ------------------------------ NativeErrorPrototype ----------------------
0133 
0134 NativeErrorPrototype::NativeErrorPrototype(ExecState *exec, ErrorPrototype *errorProto, ErrorType et, UString name, UString message)
0135     : JSObject(errorProto)
0136 {
0137     errType = et;
0138     putDirect(exec->propertyNames().name, jsString(name), 0);
0139     putDirect(exec->propertyNames().message, jsString(message), 0);
0140 }
0141 
0142 // ------------------------------ NativeErrorImp -------------------------------
0143 
0144 const ClassInfo NativeErrorImp::info = {"Function", &InternalFunctionImp::info, nullptr, nullptr};
0145 
0146 NativeErrorImp::NativeErrorImp(ExecState *exec, FunctionPrototype *funcProto, JSObject *prot)
0147     : InternalFunctionImp(funcProto)
0148     , proto(prot)
0149 {
0150     putDirect(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
0151     putDirect(exec->propertyNames().prototype, proto, DontDelete | ReadOnly | DontEnum);
0152 }
0153 
0154 bool NativeErrorImp::implementsConstruct() const
0155 {
0156     return true;
0157 }
0158 
0159 JSObject *NativeErrorImp::construct(ExecState *exec, const List &args)
0160 {
0161     JSObject *imp = new ErrorInstance(proto);
0162     JSObject *obj(imp);
0163     if (!JSValue::isUndefined(args[0])) {
0164         imp->putDirect(exec->propertyNames().message, jsString(JSValue::toString(args[0], exec)));
0165     }
0166     return obj;
0167 }
0168 
0169 JSValue *NativeErrorImp::callAsFunction(ExecState *exec, JSObject *, const List &args)
0170 {
0171     return construct(exec, args);
0172 }
0173 
0174 void NativeErrorImp::mark()
0175 {
0176     InternalFunctionImp::mark();
0177     if (proto && !proto->marked()) {
0178         proto->mark();
0179     }
0180 }