]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) | |
3 | * Copyright (C) 2004, 2005, 2006, 2007, 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 "StringObject.h" | |
23 | ||
6fe7ccc8 | 24 | #include "Error.h" |
9dae56ea A |
25 | #include "PropertyNameArray.h" |
26 | ||
27 | namespace JSC { | |
28 | ||
29 | ASSERT_CLASS_FITS_IN_CELL(StringObject); | |
6fe7ccc8 | 30 | ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject); |
9dae56ea | 31 | |
6fe7ccc8 | 32 | const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) }; |
9dae56ea | 33 | |
6fe7ccc8 | 34 | StringObject::StringObject(JSGlobalData& globalData, Structure* structure) |
14957cd0 | 35 | : JSWrapperObject(globalData, structure) |
9dae56ea | 36 | { |
9dae56ea A |
37 | } |
38 | ||
6fe7ccc8 | 39 | void StringObject::finishCreation(JSGlobalData& globalData, JSString* string) |
9dae56ea | 40 | { |
6fe7ccc8 | 41 | Base::finishCreation(globalData); |
14957cd0 | 42 | ASSERT(inherits(&s_info)); |
6fe7ccc8 | 43 | setInternalValue(globalData, string); |
9dae56ea A |
44 | } |
45 | ||
6fe7ccc8 | 46 | bool StringObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) |
9dae56ea | 47 | { |
6fe7ccc8 A |
48 | StringObject* thisObject = jsCast<StringObject*>(cell); |
49 | if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot)) | |
9dae56ea | 50 | return true; |
6fe7ccc8 | 51 | return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
9dae56ea A |
52 | } |
53 | ||
6fe7ccc8 | 54 | bool StringObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot) |
9dae56ea | 55 | { |
6fe7ccc8 A |
56 | StringObject* thisObject = jsCast<StringObject*>(cell); |
57 | if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot)) | |
9dae56ea | 58 | return true; |
6fe7ccc8 | 59 | return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot); |
9dae56ea A |
60 | } |
61 | ||
6fe7ccc8 | 62 | bool StringObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) |
f9bf01c6 | 63 | { |
6fe7ccc8 A |
64 | StringObject* thisObject = jsCast<StringObject*>(object); |
65 | if (thisObject->internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor)) | |
f9bf01c6 | 66 | return true; |
6fe7ccc8 | 67 | return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
f9bf01c6 A |
68 | } |
69 | ||
6fe7ccc8 | 70 | void StringObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) |
9dae56ea | 71 | { |
6fe7ccc8 A |
72 | if (propertyName == exec->propertyNames().length) { |
73 | if (slot.isStrictMode()) | |
74 | throwTypeError(exec, StrictModeReadonlyPropertyWriteError); | |
9dae56ea | 75 | return; |
6fe7ccc8 A |
76 | } |
77 | JSObject::put(cell, exec, propertyName, value, slot); | |
78 | } | |
79 | ||
80 | bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) | |
81 | { | |
82 | StringObject* thisObject = jsCast<StringObject*>(object); | |
83 | ||
84 | if (propertyName == exec->propertyNames().length) { | |
85 | if (!object->isExtensible()) { | |
86 | if (throwException) | |
87 | throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible.")); | |
88 | return false; | |
89 | } | |
90 | if (descriptor.configurablePresent() && descriptor.configurable()) { | |
91 | if (throwException) | |
92 | throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); | |
93 | return false; | |
94 | } | |
95 | if (descriptor.enumerablePresent() && descriptor.enumerable()) { | |
96 | if (throwException) | |
97 | throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); | |
98 | return false; | |
99 | } | |
100 | if (descriptor.isAccessorDescriptor()) { | |
101 | if (throwException) | |
102 | throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); | |
103 | return false; | |
104 | } | |
105 | if (descriptor.writablePresent() && descriptor.writable()) { | |
106 | if (throwException) | |
107 | throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); | |
108 | return false; | |
109 | } | |
110 | if (!descriptor.value()) | |
111 | return true; | |
112 | if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length()))) | |
113 | return true; | |
114 | if (throwException) | |
115 | throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); | |
116 | return false; | |
117 | } | |
118 | ||
119 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); | |
9dae56ea A |
120 | } |
121 | ||
6fe7ccc8 | 122 | bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName) |
9dae56ea | 123 | { |
6fe7ccc8 | 124 | StringObject* thisObject = jsCast<StringObject*>(cell); |
9dae56ea A |
125 | if (propertyName == exec->propertyNames().length) |
126 | return false; | |
f9bf01c6 | 127 | bool isStrictUInt32; |
14957cd0 | 128 | unsigned i = propertyName.toUInt32(isStrictUInt32); |
6fe7ccc8 | 129 | if (isStrictUInt32 && thisObject->internalValue()->canGetIndex(i)) |
f9bf01c6 | 130 | return false; |
6fe7ccc8 | 131 | return JSObject::deleteProperty(thisObject, exec, propertyName); |
9dae56ea A |
132 | } |
133 | ||
6fe7ccc8 | 134 | void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) |
9dae56ea | 135 | { |
6fe7ccc8 A |
136 | StringObject* thisObject = jsCast<StringObject*>(object); |
137 | int size = thisObject->internalValue()->length(); | |
9dae56ea | 138 | for (int i = 0; i < size; ++i) |
14957cd0 | 139 | propertyNames.add(Identifier(exec, UString::number(i))); |
f9bf01c6 A |
140 | if (mode == IncludeDontEnumProperties) |
141 | propertyNames.add(exec->propertyNames().length); | |
6fe7ccc8 | 142 | return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); |
9dae56ea A |
143 | } |
144 | ||
145 | } // namespace JSC |