adapt patch by Alexey Proskuryakov <ap@nypop.com>
[kdelibs.git] / kjs / object_object.cpp
blob52b3d440cbac6e7c8cd171bcd1d9fbe7fcd6009c
1 // -*- c-basic-offset: 2 -*-
2 // krazy:excludeall=doublequote_chars (UStrings aren't QStrings)
3 /*
4 * This file is part of the KDE libraries
5 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
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.
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.
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
23 #include "object_object.h"
24 #include <config.h>
26 #include "operations.h"
27 #include "function_object.h"
28 #include <stdio.h>
30 using namespace KJS;
32 // ------------------------------ ObjectPrototype --------------------------------
34 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* funcProto)
35 : JSObject() // [[Prototype]] is null
37 static const Identifier* hasOwnPropertyPropertyName = new Identifier("hasOwnProperty");
38 static const Identifier* propertyIsEnumerablePropertyName = new Identifier("propertyIsEnumerable");
39 static const Identifier* isPrototypeOfPropertyName = new Identifier("isPrototypeOf");
40 static const Identifier* defineGetterPropertyName = new Identifier("__defineGetter__");
41 static const Identifier* defineSetterPropertyName = new Identifier("__defineSetter__");
42 static const Identifier* lookupGetterPropertyName = new Identifier("__lookupGetter__");
43 static const Identifier* lookupSetterPropertyName = new Identifier("__lookupSetter__");
45 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum);
46 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToLocaleString, 0, exec->propertyNames().toLocaleString), DontEnum);
47 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum);
48 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::HasOwnProperty, 1, *hasOwnPropertyPropertyName), DontEnum);
49 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::PropertyIsEnumerable, 1, *propertyIsEnumerablePropertyName), DontEnum);
50 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::IsPrototypeOf, 1, *isPrototypeOfPropertyName), DontEnum);
52 // Mozilla extensions
53 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineGetter, 2, *defineGetterPropertyName), DontEnum);
54 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineSetter, 2, *defineSetterPropertyName), DontEnum);
55 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupGetter, 1, *lookupGetterPropertyName), DontEnum);
56 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupSetter, 1, *lookupSetterPropertyName), DontEnum);
60 // ------------------------------ ObjectProtoFunc --------------------------------
62 ObjectProtoFunc::ObjectProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
63 : InternalFunctionImp(funcProto, name)
64 , id(i)
66 putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
70 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
72 JSValue *ObjectProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
74 switch (id) {
75 case ValueOf:
76 return thisObj;
77 case HasOwnProperty: {
78 PropertySlot slot;
79 return jsBoolean(thisObj->getOwnPropertySlot(exec, Identifier(args[0]->toString(exec)), slot));
81 case IsPrototypeOf: {
82 if (!args[0]->isObject())
83 return jsBoolean(false);
85 JSValue *v = static_cast<JSObject *>(args[0])->prototype();
87 while (true) {
88 if (!v->isObject())
89 return jsBoolean(false);
91 if (thisObj == static_cast<JSObject *>(v))\v
92 return jsBoolean(true);
94 v = static_cast<JSObject *>(v)->prototype();
97 case DefineGetter:
98 case DefineSetter: {
99 if (!args[1]->isObject() ||
100 !static_cast<JSObject *>(args[1])->implementsCall()) {
101 if (id == DefineGetter)
102 return throwError(exec, SyntaxError, "invalid getter usage");
103 else
104 return throwError(exec, SyntaxError, "invalid setter usage");
107 if (id == DefineGetter)
108 thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
109 else
110 thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
111 return jsUndefined();
113 case LookupGetter:
114 case LookupSetter: {
115 Identifier propertyName = Identifier(args[0]->toString(exec));
117 JSObject *obj = thisObj;
118 while (true) {
119 JSValue *v = obj->getDirect(propertyName);
121 if (v) {
122 if (v->type() != GetterSetterType)
123 return jsUndefined();
125 JSObject *funcObj;
127 if (id == LookupGetter)
128 funcObj = static_cast<GetterSetterImp *>(v)->getGetter();
129 else
130 funcObj = static_cast<GetterSetterImp *>(v)->getSetter();
132 if (!funcObj)
133 return jsUndefined();
134 else
135 return funcObj;
138 if (!obj->prototype() || !obj->prototype()->isObject())
139 return jsUndefined();
141 obj = static_cast<JSObject *>(obj->prototype());
144 case PropertyIsEnumerable:
145 return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec))));
146 case ToLocaleString:
147 return jsString(thisObj->toString(exec));
148 case ToString:
149 default:
150 return jsString("[object " + thisObj->className() + "]");
154 // ------------------------------ ObjectObjectImp --------------------------------
156 ObjectObjectImp::ObjectObjectImp(ExecState* exec, ObjectPrototype* objProto, FunctionPrototype* funcProto)
157 : InternalFunctionImp(funcProto)
159 // ECMA 15.2.3.1
160 putDirect(exec->propertyNames().prototype, objProto, DontEnum|DontDelete|ReadOnly);
162 // no. of arguments for constructor
163 putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
167 bool ObjectObjectImp::implementsConstruct() const
169 return true;
172 // ECMA 15.2.2
173 JSObject* ObjectObjectImp::construct(ExecState* exec, const List& args)
175 JSValue* arg = args[0];
176 switch (arg->type()) {
177 case StringType:
178 case BooleanType:
179 case NumberType:
180 case ObjectType:
181 return arg->toObject(exec);
182 case NullType:
183 case UndefinedType:
184 return new JSObject(exec->lexicalInterpreter()->builtinObjectPrototype());
185 default:
186 //### ASSERT_NOT_REACHED();
187 return 0;
191 JSValue* ObjectObjectImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List &args)
193 return construct(exec, args);