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