1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 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 "ObjectPrototype.h"
23
24 #include "Error.h"
25 #include "JSString.h"
26 #include "PrototypeFunction.h"
27
28 namespace JSC {
29
30 ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
31
32 static JSValuePtr objectProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
33 static JSValuePtr objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValuePtr, const ArgList&);
34 static JSValuePtr objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
35 static JSValuePtr objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
36 static JSValuePtr objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
37 static JSValuePtr objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
38 static JSValuePtr objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
39 static JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValuePtr, const ArgList&);
40 static JSValuePtr objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
41
ObjectPrototype(ExecState * exec,PassRefPtr<Structure> stucture,Structure * prototypeFunctionStructure)42 ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
43 : JSObject(stucture)
44 {
45 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
46 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
47 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
48 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
49 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
50 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
51
52 // Mozilla extensions
53 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
54 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
55 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
56 putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
57 }
58
59 // ------------------------------ Functions --------------------------------
60
61 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
62
objectProtoFuncValueOf(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList &)63 JSValuePtr objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
64 {
65 return thisValue.toThisObject(exec);
66 }
67
objectProtoFuncHasOwnProperty(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)68 JSValuePtr objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
69 {
70 return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
71 }
72
objectProtoFuncIsPrototypeOf(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)73 JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
74 {
75 JSObject* thisObj = thisValue.toThisObject(exec);
76
77 if (!args.at(exec, 0).isObject())
78 return jsBoolean(false);
79
80 JSValuePtr v = asObject(args.at(exec, 0))->prototype();
81
82 while (true) {
83 if (!v.isObject())
84 return jsBoolean(false);
85 if (v == thisObj)
86 return jsBoolean(true);
87 v = asObject(v)->prototype();
88 }
89 }
90
objectProtoFuncDefineGetter(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)91 JSValuePtr objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
92 {
93 CallData callData;
94 if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
95 return throwError(exec, SyntaxError, "invalid getter usage");
96 thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
97 return jsUndefined();
98 }
99
objectProtoFuncDefineSetter(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)100 JSValuePtr objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
101 {
102 CallData callData;
103 if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
104 return throwError(exec, SyntaxError, "invalid setter usage");
105 thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
106 return jsUndefined();
107 }
108
objectProtoFuncLookupGetter(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)109 JSValuePtr objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
110 {
111 return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
112 }
113
objectProtoFuncLookupSetter(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)114 JSValuePtr objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
115 {
116 return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
117 }
118
objectProtoFuncPropertyIsEnumerable(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList & args)119 JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
120 {
121 return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
122 }
123
objectProtoFuncToLocaleString(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList &)124 JSValuePtr objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
125 {
126 return thisValue.toThisJSString(exec);
127 }
128
objectProtoFuncToString(ExecState * exec,JSObject *,JSValuePtr thisValue,const ArgList &)129 JSValuePtr objectProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
130 {
131 return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
132 }
133
134 } // namespace JSC
135