18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2008 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ObjectPrototype.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Error.h"
255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "JSFunction.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSString.h"
278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "JSStringBuilder.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*);
34545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*);
35545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*);
36545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*);
37545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*);
38545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*);
39545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*);
40545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*);
41545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochObjectPrototype::ObjectPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* stucture, Structure* functionStructure)
442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : JSNonFinalObject(exec->globalData(), stucture)
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_hasNoPropertiesWithUInt32Names(true)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Mozilla extensions
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    JSObject::put(exec, propertyName, value, slot);
64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_hasNoPropertiesWithUInt32Names) {
66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool isUInt32;
67f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        propertyName.toUInt32(isUInt32);
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_hasNoPropertiesWithUInt32Names = !isUInt32;
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool ObjectPrototype::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_hasNoPropertiesWithUInt32Names)
75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return false;
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ------------------------------ Functions --------------------------------
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
83545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec)
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
86545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(thisValue.toThisObject(exec));
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
89545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
92545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)))));
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
95545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    JSObject* thisObj = thisValue.toThisObject(exec);
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!exec->argument(0).isObject())
101545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return JSValue::encode(jsBoolean(false));
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue v = asObject(exec->argument(0))->prototype();
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (!v.isObject())
107545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(jsBoolean(false));
1085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (v == thisObj)
109545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(jsBoolean(true));
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        v = asObject(v)->prototype();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
114545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CallData callData;
118545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (getCallData(exec->argument(1), callData) == CallTypeNone)
119545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return throwVMError(exec, createSyntaxError(exec, "invalid getter usage"));
1205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)));
121545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
124545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CallData callData;
128545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (getCallData(exec->argument(1), callData) == CallTypeNone)
129545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return throwVMError(exec, createSyntaxError(exec, "invalid setter usage"));
1305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)));
131545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
134545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec)
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
137545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
143545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
146545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec)
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
149545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)))));
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
152545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
155545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(thisValue.toThisJSString(exec));
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
158545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue thisValue = exec->hostThisValue();
161545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]"));
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
165