2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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
22 #include "StringObject.h"
25 #include "JSGlobalObject.h"
26 #include "JSCInlines.h"
27 #include "PropertyNameArray.h"
31 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StringObject
);
33 const ClassInfo
StringObject::s_info
= { "String", &JSWrapperObject::s_info
, 0, 0, CREATE_METHOD_TABLE(StringObject
) };
35 StringObject::StringObject(VM
& vm
, Structure
* structure
)
36 : JSWrapperObject(vm
, structure
)
40 void StringObject::finishCreation(VM
& vm
, JSString
* string
)
42 Base::finishCreation(vm
);
43 ASSERT(inherits(info()));
44 setInternalValue(vm
, string
);
47 bool StringObject::getOwnPropertySlot(JSObject
* cell
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
49 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
50 if (thisObject
->internalValue()->getStringPropertySlot(exec
, propertyName
, slot
))
52 return JSObject::getOwnPropertySlot(thisObject
, exec
, propertyName
, slot
);
55 bool StringObject::getOwnPropertySlotByIndex(JSObject
* object
, ExecState
* exec
, unsigned propertyName
, PropertySlot
& slot
)
57 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
58 if (thisObject
->internalValue()->getStringPropertySlot(exec
, propertyName
, slot
))
60 return JSObject::getOwnPropertySlot(thisObject
, exec
, Identifier::from(exec
, propertyName
), slot
);
63 void StringObject::put(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, PutPropertySlot
& slot
)
65 if (propertyName
== exec
->propertyNames().length
) {
66 if (slot
.isStrictMode())
67 throwTypeError(exec
, StrictModeReadonlyPropertyWriteError
);
70 JSObject::put(cell
, exec
, propertyName
, value
, slot
);
73 void StringObject::putByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
, JSValue value
, bool shouldThrow
)
75 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
76 if (thisObject
->internalValue()->canGetIndex(propertyName
)) {
78 throwTypeError(exec
, StrictModeReadonlyPropertyWriteError
);
81 JSObject::putByIndex(cell
, exec
, propertyName
, value
, shouldThrow
);
84 bool StringObject::defineOwnProperty(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, const PropertyDescriptor
& descriptor
, bool throwException
)
86 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
88 if (propertyName
== exec
->propertyNames().length
) {
89 if (!object
->isExtensible()) {
91 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to define property on object that is not extensible.")));
94 if (descriptor
.configurablePresent() && descriptor
.configurable()) {
96 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
99 if (descriptor
.enumerablePresent() && descriptor
.enumerable()) {
101 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
104 if (descriptor
.isAccessorDescriptor()) {
106 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
109 if (descriptor
.writablePresent() && descriptor
.writable()) {
111 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
114 if (!descriptor
.value())
116 if (propertyName
== exec
->propertyNames().length
&& sameValue(exec
, descriptor
.value(), jsNumber(thisObject
->internalValue()->length())))
119 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change value of a readonly property.")));
123 return Base::defineOwnProperty(object
, exec
, propertyName
, descriptor
, throwException
);
126 bool StringObject::deleteProperty(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
)
128 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
129 if (propertyName
== exec
->propertyNames().length
)
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!
136 return JSObject::deleteProperty(thisObject
, exec
, propertyName
);
139 bool StringObject::deletePropertyByIndex(JSCell
* cell
, ExecState
* exec
, unsigned i
)
141 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
142 if (thisObject
->internalValue()->canGetIndex(i
))
144 return JSObject::deletePropertyByIndex(thisObject
, exec
, i
);
147 void StringObject::getOwnPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
)
149 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
150 int size
= thisObject
->internalValue()->length();
151 for (int i
= 0; i
< size
; ++i
)
152 propertyNames
.add(Identifier::from(exec
, i
));
153 if (mode
== IncludeDontEnumProperties
)
154 propertyNames
.add(exec
->propertyNames().length
);
155 return JSObject::getOwnPropertyNames(thisObject
, exec
, propertyNames
, mode
);
158 StringObject
* constructString(VM
& vm
, JSGlobalObject
* globalObject
, JSValue string
)
160 StringObject
* object
= StringObject::create(vm
, globalObject
->stringObjectStructure());
161 object
->setInternalValue(vm
, string
);