]>
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" |
93a37866 A |
25 | #include "JSGlobalObject.h" |
26 | #include "Operations.h" | |
9dae56ea A |
27 | #include "PropertyNameArray.h" |
28 | ||
29 | namespace JSC { | |
30 | ||
6fe7ccc8 | 31 | ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject); |
9dae56ea | 32 | |
6fe7ccc8 | 33 | const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) }; |
9dae56ea | 34 | |
93a37866 A |
35 | StringObject::StringObject(VM& vm, Structure* structure) |
36 | : JSWrapperObject(vm, structure) | |
9dae56ea | 37 | { |
9dae56ea A |
38 | } |
39 | ||
93a37866 | 40 | void StringObject::finishCreation(VM& vm, JSString* string) |
9dae56ea | 41 | { |
93a37866 | 42 | Base::finishCreation(vm); |
14957cd0 | 43 | ASSERT(inherits(&s_info)); |
93a37866 | 44 | setInternalValue(vm, string); |
9dae56ea A |
45 | } |
46 | ||
93a37866 | 47 | bool StringObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) |
9dae56ea | 48 | { |
6fe7ccc8 A |
49 | StringObject* thisObject = jsCast<StringObject*>(cell); |
50 | if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot)) | |
9dae56ea | 51 | return true; |
6fe7ccc8 | 52 | return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
9dae56ea A |
53 | } |
54 | ||
6fe7ccc8 | 55 | bool StringObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot) |
9dae56ea | 56 | { |
6fe7ccc8 A |
57 | StringObject* thisObject = jsCast<StringObject*>(cell); |
58 | if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot)) | |
9dae56ea | 59 | return true; |
6fe7ccc8 | 60 | return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot); |
9dae56ea A |
61 | } |
62 | ||
93a37866 | 63 | bool StringObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) |
f9bf01c6 | 64 | { |
6fe7ccc8 A |
65 | StringObject* thisObject = jsCast<StringObject*>(object); |
66 | if (thisObject->internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor)) | |
f9bf01c6 | 67 | return true; |
6fe7ccc8 | 68 | return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
f9bf01c6 A |
69 | } |
70 | ||
93a37866 | 71 | void StringObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) |
9dae56ea | 72 | { |
6fe7ccc8 A |
73 | if (propertyName == exec->propertyNames().length) { |
74 | if (slot.isStrictMode()) | |
75 | throwTypeError(exec, StrictModeReadonlyPropertyWriteError); | |
9dae56ea | 76 | return; |
6fe7ccc8 A |
77 | } |
78 | JSObject::put(cell, exec, propertyName, value, slot); | |
79 | } | |
80 | ||
93a37866 A |
81 | void StringObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow) |
82 | { | |
83 | StringObject* thisObject = jsCast<StringObject*>(cell); | |
84 | if (thisObject->internalValue()->canGetIndex(propertyName)) { | |
85 | if (shouldThrow) | |
86 | throwTypeError(exec, StrictModeReadonlyPropertyWriteError); | |
87 | return; | |
88 | } | |
89 | JSObject::putByIndex(cell, exec, propertyName, value, shouldThrow); | |
90 | } | |
91 | ||
92 | bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException) | |
6fe7ccc8 A |
93 | { |
94 | StringObject* thisObject = jsCast<StringObject*>(object); | |
95 | ||
96 | if (propertyName == exec->propertyNames().length) { | |
97 | if (!object->isExtensible()) { | |
98 | if (throwException) | |
93a37866 | 99 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible."))); |
6fe7ccc8 A |
100 | return false; |
101 | } | |
102 | if (descriptor.configurablePresent() && descriptor.configurable()) { | |
103 | if (throwException) | |
93a37866 | 104 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property."))); |
6fe7ccc8 A |
105 | return false; |
106 | } | |
107 | if (descriptor.enumerablePresent() && descriptor.enumerable()) { | |
108 | if (throwException) | |
93a37866 | 109 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."))); |
6fe7ccc8 A |
110 | return false; |
111 | } | |
112 | if (descriptor.isAccessorDescriptor()) { | |
113 | if (throwException) | |
93a37866 | 114 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property."))); |
6fe7ccc8 A |
115 | return false; |
116 | } | |
117 | if (descriptor.writablePresent() && descriptor.writable()) { | |
118 | if (throwException) | |
93a37866 | 119 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."))); |
6fe7ccc8 A |
120 | return false; |
121 | } | |
122 | if (!descriptor.value()) | |
123 | return true; | |
124 | if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length()))) | |
125 | return true; | |
126 | if (throwException) | |
93a37866 | 127 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."))); |
6fe7ccc8 A |
128 | return false; |
129 | } | |
130 | ||
131 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); | |
9dae56ea A |
132 | } |
133 | ||
93a37866 | 134 | bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) |
9dae56ea | 135 | { |
6fe7ccc8 | 136 | StringObject* thisObject = jsCast<StringObject*>(cell); |
9dae56ea A |
137 | if (propertyName == exec->propertyNames().length) |
138 | return false; | |
93a37866 A |
139 | unsigned i = propertyName.asIndex(); |
140 | if (thisObject->internalValue()->canGetIndex(i)) { | |
141 | ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail! | |
f9bf01c6 | 142 | return false; |
93a37866 | 143 | } |
6fe7ccc8 | 144 | return JSObject::deleteProperty(thisObject, exec, propertyName); |
9dae56ea A |
145 | } |
146 | ||
93a37866 A |
147 | bool StringObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) |
148 | { | |
149 | StringObject* thisObject = jsCast<StringObject*>(cell); | |
150 | if (thisObject->internalValue()->canGetIndex(i)) | |
151 | return false; | |
152 | return JSObject::deletePropertyByIndex(thisObject, exec, i); | |
153 | } | |
154 | ||
6fe7ccc8 | 155 | void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) |
9dae56ea | 156 | { |
6fe7ccc8 A |
157 | StringObject* thisObject = jsCast<StringObject*>(object); |
158 | int size = thisObject->internalValue()->length(); | |
9dae56ea | 159 | for (int i = 0; i < size; ++i) |
93a37866 | 160 | propertyNames.add(Identifier(exec, String::number(i))); |
f9bf01c6 A |
161 | if (mode == IncludeDontEnumProperties) |
162 | propertyNames.add(exec->propertyNames().length); | |
6fe7ccc8 | 163 | return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); |
9dae56ea A |
164 | } |
165 | ||
93a37866 A |
166 | StringObject* constructString(ExecState* exec, JSGlobalObject* globalObject, JSValue string) |
167 | { | |
168 | StringObject* object = StringObject::create(exec, globalObject->stringObjectStructure()); | |
169 | object->setInternalValue(exec->vm(), string); | |
170 | return object; | |
171 | } | |
172 | ||
9dae56ea | 173 | } // namespace JSC |