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