2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2008, 2011 Apple Inc. All rights reserved.
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.
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.
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
22 #include "ObjectPrototype.h"
25 #include "JSFunction.h"
27 #include "JSStringBuilder.h"
31 static EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*);
32 static EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*);
33 static EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*);
34 static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*);
35 static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*);
36 static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*);
37 static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*);
38 static EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*);
39 static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
43 #include "ObjectPrototype.lut.h"
47 const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, ExecState::objectPrototypeTable, CREATE_METHOD_TABLE(ObjectPrototype) };
49 /* Source for ObjectPrototype.lut.h
50 @begin objectPrototypeTable
51 toString objectProtoFuncToString DontEnum|Function 0
52 toLocaleString objectProtoFuncToLocaleString DontEnum|Function 0
53 valueOf objectProtoFuncValueOf DontEnum|Function 0
54 hasOwnProperty objectProtoFuncHasOwnProperty DontEnum|Function 1
55 propertyIsEnumerable objectProtoFuncPropertyIsEnumerable DontEnum|Function 1
56 isPrototypeOf objectProtoFuncIsPrototypeOf DontEnum|Function 1
57 __defineGetter__ objectProtoFuncDefineGetter DontEnum|Function 2
58 __defineSetter__ objectProtoFuncDefineSetter DontEnum|Function 2
59 __lookupGetter__ objectProtoFuncLookupGetter DontEnum|Function 1
60 __lookupSetter__ objectProtoFuncLookupSetter DontEnum|Function 1
64 ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
66 ObjectPrototype::ObjectPrototype(ExecState* exec, Structure* stucture)
67 : JSNonFinalObject(exec->globalData(), stucture)
68 , m_hasNoPropertiesWithUInt32Names(true)
72 void ObjectPrototype::finishCreation(JSGlobalData& globalData, JSGlobalObject*)
74 Base::finishCreation(globalData);
75 ASSERT(inherits(&s_info));
78 void ObjectPrototype::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
80 ObjectPrototype* thisObject = jsCast<ObjectPrototype*>(cell);
81 JSNonFinalObject::put(cell, exec, propertyName, value, slot);
83 if (thisObject->m_hasNoPropertiesWithUInt32Names) {
85 propertyName.toUInt32(isUInt32);
86 thisObject->m_hasNoPropertiesWithUInt32Names = !isUInt32;
90 bool ObjectPrototype::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
92 ObjectPrototype* thisObject = jsCast<ObjectPrototype*>(cell);
93 if (thisObject->m_hasNoPropertiesWithUInt32Names)
95 return JSNonFinalObject::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
98 bool ObjectPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
100 return getStaticFunctionSlot<JSNonFinalObject>(exec, ExecState::objectPrototypeTable(exec), jsCast<ObjectPrototype*>(cell), propertyName, slot);
103 bool ObjectPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
105 return getStaticFunctionDescriptor<JSNonFinalObject>(exec, ExecState::objectPrototypeTable(exec), jsCast<ObjectPrototype*>(object), propertyName, descriptor);
108 // ------------------------------ Functions --------------------------------
110 EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec)
112 JSValue thisValue = exec->hostThisValue();
113 return JSValue::encode(thisValue.toObject(exec));
116 EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
118 JSValue thisValue = exec->hostThisValue();
119 return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)))));
122 EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
124 JSValue thisValue = exec->hostThisValue();
125 JSObject* thisObj = thisValue.toObject(exec);
127 if (!exec->argument(0).isObject())
128 return JSValue::encode(jsBoolean(false));
130 JSValue v = asObject(exec->argument(0))->prototype();
134 return JSValue::encode(jsBoolean(false));
136 return JSValue::encode(jsBoolean(true));
137 v = asObject(v)->prototype();
141 EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
143 JSObject* thisObject = exec->hostThisValue().toObject(exec);
144 if (exec->hadException())
145 return JSValue::encode(jsUndefined());
148 if (getCallData(exec->argument(1), callData) == CallTypeNone)
149 return throwVMError(exec, createSyntaxError(exec, "invalid getter usage"));
150 thisObject->methodTable()->defineGetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)), 0);
151 return JSValue::encode(jsUndefined());
154 EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
156 JSObject* thisObject = exec->hostThisValue().toObject(exec);
157 if (exec->hadException())
158 return JSValue::encode(jsUndefined());
161 if (getCallData(exec->argument(1), callData) == CallTypeNone)
162 return throwVMError(exec, createSyntaxError(exec, "invalid setter usage"));
163 thisObject->methodTable()->defineSetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)), 0);
164 return JSValue::encode(jsUndefined());
167 EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec)
169 JSObject* thisObject = exec->hostThisValue().toObject(exec);
170 if (exec->hadException())
171 return JSValue::encode(jsUndefined());
173 return JSValue::encode(thisObject->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
176 EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
178 JSObject* thisObject = exec->hostThisValue().toObject(exec);
179 if (exec->hadException())
180 return JSValue::encode(jsUndefined());
182 return JSValue::encode(thisObject->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
185 EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec)
187 JSValue thisValue = exec->hostThisValue();
188 return JSValue::encode(jsBoolean(thisValue.toObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)))));
191 // 15.2.4.3 Object.prototype.toLocaleString()
192 EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec)
194 // 1. Let O be the result of calling ToObject passing the this value as the argument.
195 JSObject* object = exec->hostThisValue().toObject(exec);
196 if (exec->hadException())
197 return JSValue::encode(jsUndefined());
199 // 2. Let toString be the result of calling the [[Get]] internal method of O passing "toString" as the argument.
200 JSValue toString = object->get(exec, exec->propertyNames().toString);
202 // 3. If IsCallable(toString) is false, throw a TypeError exception.
204 CallType callType = getCallData(toString, callData);
205 if (callType == CallTypeNone)
206 return JSValue::encode(jsUndefined());
208 // 4. Return the result of calling the [[Call]] internal method of toString passing O as the this value and no arguments.
209 return JSValue::encode(call(exec, toString, callType, callData, object, exec->emptyList()));
212 EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
214 JSValue thisValue = exec->hostThisValue();
215 if (thisValue.isUndefinedOrNull())
216 return JSValue::encode(jsNontrivialString(exec, thisValue.isUndefined() ? "[object Undefined]" : "[object Null]"));
217 JSObject* thisObject = thisValue.toObject(exec);
218 return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]"));