1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5 * Copyright (C) 2003 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include "error_object.h"
24#include <config-kjs.h>
25
26#include "value.h"
27#include "object.h"
28#include "types.h"
29#include "interpreter.h"
30#include "operations.h"
31//#include "debugger.h"
32
33using namespace KJS;
34
35// ------------------------------ ErrorInstance ----------------------------
36
37const ClassInfo ErrorInstance::info = {"Error", 0, 0, 0};
38
39ErrorInstance::ErrorInstance(JSObject *proto)
40: JSObject(proto)
41{
42}
43
44// ------------------------------ ErrorPrototype ----------------------------
45
46// ECMA 15.9.4
47ErrorPrototype::ErrorPrototype(ExecState* exec,
48 ObjectPrototype* objectProto,
49 FunctionPrototype* funcProto)
50 : ErrorInstance(objectProto)
51{
52 // Interpreter::initGlobalObject sets the constructor property
53 // on the prototypes for this and the native error types
54
55 put(exec, exec->propertyNames().name, jsString("Error"), DontEnum);
56 // ECMA Edition 5.1r6 - 15.11.4.3
57 // The initial value of Error.prototype.message is the empty String.
58 put(exec, exec->propertyNames().message, jsString(""), DontEnum);
59 putDirectFunction(new ErrorProtoFunc(exec, funcProto, exec->propertyNames().toString), DontEnum);
60}
61
62// ------------------------------ ErrorProtoFunc ----------------------------
63
64ErrorProtoFunc::ErrorProtoFunc(ExecState* exec, FunctionPrototype* funcProto, const Identifier& name)
65 : InternalFunctionImp(funcProto, name)
66{
67 putDirect(exec->propertyNames().length, jsNumber(0), DontDelete|ReadOnly|DontEnum);
68}
69
70JSValue* ErrorProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &/*args*/)
71{
72 // toString()
73 UString name;
74 JSValue* v = thisObj->get(exec, exec->propertyNames().name);
75 if (!v->isUndefined())
76 name = v->toString(exec);
77 else
78 name = "Error";
79
80 UString message;
81 v = thisObj->get(exec, exec->propertyNames().message);
82 if (!v->isUndefined())
83 message = v->toString(exec);
84
85 if (name.isEmpty())
86 return jsString(message);
87 if (message.isEmpty())
88 return jsString(name);
89
90 return jsString(name + ": " + message);
91}
92
93// ------------------------------ ErrorObjectImp -------------------------------
94
95ErrorObjectImp::ErrorObjectImp(ExecState* exec, FunctionPrototype* funcProto, ErrorPrototype* errorProto)
96 : InternalFunctionImp(funcProto)
97{
98 // ECMA 15.11.3.1 Error.prototype
99 putDirect(exec->propertyNames().prototype, errorProto, DontEnum|DontDelete|ReadOnly);
100 putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
101 //putDirect(namePropertyName, jsString(n));
102}
103
104bool ErrorObjectImp::implementsConstruct() const
105{
106 return true;
107}
108
109// ECMA 15.9.3
110JSObject* ErrorObjectImp::construct(ExecState* exec, const List& args)
111{
112 JSObject* proto = static_cast<JSObject*>(exec->lexicalInterpreter()->builtinErrorPrototype());
113 JSObject* imp = new ErrorInstance(proto);
114 JSObject* obj(imp);
115
116 if (!args[0]->isUndefined())
117 imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
118
119 return obj;
120}
121
122// ECMA 15.9.2
123JSValue* ErrorObjectImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List &args)
124{
125 // "Error()" gives the sames result as "new Error()"
126 return construct(exec, args);
127}
128
129// ------------------------------ NativeErrorPrototype ----------------------
130
131NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, ErrorPrototype* errorProto, ErrorType et, UString name, UString message)
132 : JSObject(errorProto)
133{
134 errType = et;
135 putDirect(exec->propertyNames().name, jsString(name), 0);
136 putDirect(exec->propertyNames().message, jsString(message), 0);
137}
138
139// ------------------------------ NativeErrorImp -------------------------------
140
141const ClassInfo NativeErrorImp::info = {"Function", &InternalFunctionImp::info, 0, 0};
142
143NativeErrorImp::NativeErrorImp(ExecState* exec, FunctionPrototype* funcProto, JSObject* prot)
144 : InternalFunctionImp(funcProto)
145 , proto(prot)
146{
147 putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
148 putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum);
149}
150
151bool NativeErrorImp::implementsConstruct() const
152{
153 return true;
154}
155
156JSObject* NativeErrorImp::construct(ExecState* exec, const List& args)
157{
158 JSObject* imp = new ErrorInstance(proto);
159 JSObject* obj(imp);
160 if (!args[0]->isUndefined())
161 imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
162 return obj;
163}
164
165JSValue* NativeErrorImp::callAsFunction(ExecState* exec, JSObject*, const List& args)
166{
167 return construct(exec, args);
168}
169
170void NativeErrorImp::mark()
171{
172 InternalFunctionImp::mark();
173 if (proto && !proto->marked())
174 proto->mark();
175}
176