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