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 "JSStringBuilder.h" 28 29namespace JSC { 30 31ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype); 32 33static EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*); 34static EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*); 35static EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*); 36static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*); 37static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*); 38static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*); 39static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*); 40static EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*); 41static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*); 42 43ObjectPrototype::ObjectPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* stucture, Structure* functionStructure) 44 : JSNonFinalObject(exec->globalData(), stucture) 45 , m_hasNoPropertiesWithUInt32Names(true) 46{ 47 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum); 48 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum); 49 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum); 50 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum); 51 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum); 52 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum); 53 54 // Mozilla extensions 55 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum); 56 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum); 57 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum); 58 putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum); 59} 60 61void ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 62{ 63 JSObject::put(exec, propertyName, value, slot); 64 65 if (m_hasNoPropertiesWithUInt32Names) { 66 bool isUInt32; 67 propertyName.toUInt32(isUInt32); 68 m_hasNoPropertiesWithUInt32Names = !isUInt32; 69 } 70} 71 72bool ObjectPrototype::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 73{ 74 if (m_hasNoPropertiesWithUInt32Names) 75 return false; 76 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 77} 78 79// ------------------------------ Functions -------------------------------- 80 81// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 82 83EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec) 84{ 85 JSValue thisValue = exec->hostThisValue(); 86 return JSValue::encode(thisValue.toThisObject(exec)); 87} 88 89EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec) 90{ 91 JSValue thisValue = exec->hostThisValue(); 92 return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec))))); 93} 94 95EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec) 96{ 97 JSValue thisValue = exec->hostThisValue(); 98 JSObject* thisObj = thisValue.toThisObject(exec); 99 100 if (!exec->argument(0).isObject()) 101 return JSValue::encode(jsBoolean(false)); 102 103 JSValue v = asObject(exec->argument(0))->prototype(); 104 105 while (true) { 106 if (!v.isObject()) 107 return JSValue::encode(jsBoolean(false)); 108 if (v == thisObj) 109 return JSValue::encode(jsBoolean(true)); 110 v = asObject(v)->prototype(); 111 } 112} 113 114EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec) 115{ 116 JSValue thisValue = exec->hostThisValue(); 117 CallData callData; 118 if (getCallData(exec->argument(1), callData) == CallTypeNone) 119 return throwVMError(exec, createSyntaxError(exec, "invalid getter usage")); 120 thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1))); 121 return JSValue::encode(jsUndefined()); 122} 123 124EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec) 125{ 126 JSValue thisValue = exec->hostThisValue(); 127 CallData callData; 128 if (getCallData(exec->argument(1), callData) == CallTypeNone) 129 return throwVMError(exec, createSyntaxError(exec, "invalid setter usage")); 130 thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1))); 131 return JSValue::encode(jsUndefined()); 132} 133 134EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec) 135{ 136 JSValue thisValue = exec->hostThisValue(); 137 return JSValue::encode(thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec)))); 138} 139 140EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec) 141{ 142 JSValue thisValue = exec->hostThisValue(); 143 return JSValue::encode(thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec)))); 144} 145 146EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec) 147{ 148 JSValue thisValue = exec->hostThisValue(); 149 return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec))))); 150} 151 152EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec) 153{ 154 JSValue thisValue = exec->hostThisValue(); 155 return JSValue::encode(thisValue.toThisJSString(exec)); 156} 157 158EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec) 159{ 160 JSValue thisValue = exec->hostThisValue(); 161 return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]")); 162} 163 164} // namespace JSC 165