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 "Operations.h"
27 #include "PropertyNameArray.h"
31 ASSERT_HAS_TRIVIAL_DESTRUCTOR(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(&s_info
));
44 setInternalValue(vm
, string
);
47 bool StringObject::getOwnPropertySlot(JSCell
* 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(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
, PropertySlot
& slot
)
57 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
58 if (thisObject
->internalValue()->getStringPropertySlot(exec
, propertyName
, slot
))
60 return JSObject::getOwnPropertySlot(thisObject
, exec
, Identifier::from(exec
, propertyName
), slot
);
63 bool StringObject::getOwnPropertyDescriptor(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertyDescriptor
& descriptor
)
65 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
66 if (thisObject
->internalValue()->getStringPropertyDescriptor(exec
, propertyName
, descriptor
))
68 return JSObject::getOwnPropertyDescriptor(thisObject
, exec
, propertyName
, descriptor
);
71 void StringObject::put(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, PutPropertySlot
& slot
)
73 if (propertyName
== exec
->propertyNames().length
) {
74 if (slot
.isStrictMode())
75 throwTypeError(exec
, StrictModeReadonlyPropertyWriteError
);
78 JSObject::put(cell
, exec
, propertyName
, value
, slot
);
81 void StringObject::putByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
, JSValue value
, bool shouldThrow
)
83 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
84 if (thisObject
->internalValue()->canGetIndex(propertyName
)) {
86 throwTypeError(exec
, StrictModeReadonlyPropertyWriteError
);
89 JSObject::putByIndex(cell
, exec
, propertyName
, value
, shouldThrow
);
92 bool StringObject::defineOwnProperty(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertyDescriptor
& descriptor
, bool throwException
)
94 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
96 if (propertyName
== exec
->propertyNames().length
) {
97 if (!object
->isExtensible()) {
99 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to define property on object that is not extensible.")));
102 if (descriptor
.configurablePresent() && descriptor
.configurable()) {
104 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
107 if (descriptor
.enumerablePresent() && descriptor
.enumerable()) {
109 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
112 if (descriptor
.isAccessorDescriptor()) {
114 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
117 if (descriptor
.writablePresent() && descriptor
.writable()) {
119 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
122 if (!descriptor
.value())
124 if (propertyName
== exec
->propertyNames().length
&& sameValue(exec
, descriptor
.value(), jsNumber(thisObject
->internalValue()->length())))
127 throwError(exec
, createTypeError(exec
, ASCIILiteral("Attempting to change value of a readonly property.")));
131 return Base::defineOwnProperty(object
, exec
, propertyName
, descriptor
, throwException
);
134 bool StringObject::deleteProperty(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
)
136 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
137 if (propertyName
== exec
->propertyNames().length
)
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!
144 return JSObject::deleteProperty(thisObject
, exec
, propertyName
);
147 bool StringObject::deletePropertyByIndex(JSCell
* cell
, ExecState
* exec
, unsigned i
)
149 StringObject
* thisObject
= jsCast
<StringObject
*>(cell
);
150 if (thisObject
->internalValue()->canGetIndex(i
))
152 return JSObject::deletePropertyByIndex(thisObject
, exec
, i
);
155 void StringObject::getOwnPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
)
157 StringObject
* thisObject
= jsCast
<StringObject
*>(object
);
158 int size
= thisObject
->internalValue()->length();
159 for (int i
= 0; i
< size
; ++i
)
160 propertyNames
.add(Identifier(exec
, String::number(i
)));
161 if (mode
== IncludeDontEnumProperties
)
162 propertyNames
.add(exec
->propertyNames().length
);
163 return JSObject::getOwnPropertyNames(thisObject
, exec
, propertyNames
, mode
);
166 StringObject
* constructString(ExecState
* exec
, JSGlobalObject
* globalObject
, JSValue string
)
168 StringObject
* object
= StringObject::create(exec
, globalObject
->stringObjectStructure());
169 object
->setInternalValue(exec
->vm(), string
);