blob: c58354a2c23a38b8d92ee6f00d6c3bbdf87f9bcc [file] [log] [blame]
weinig@apple.comefdce0f2008-06-30 20:52:03 +00001/*
2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
fpizlo@apple.com3cb36ea2015-10-05 19:35:32 +00004 * Copyright (C) 2004, 2007, 2008, 2015 Apple Inc. All rights reserved.
weinig@apple.comefdce0f2008-06-30 20:52:03 +00005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "JSString.h"
25
26#include "JSGlobalObject.h"
barraclough@apple.com794f4612010-08-18 07:41:22 +000027#include "JSGlobalObjectFunctions.h"
weinig@apple.comefdce0f2008-06-30 20:52:03 +000028#include "JSObject.h"
fpizlo@apple.comfb7eff22014-02-11 01:45:50 +000029#include "JSCInlines.h"
weinig@apple.comefdce0f2008-06-30 20:52:03 +000030#include "StringObject.h"
31#include "StringPrototype.h"
akling@apple.comede8a982014-07-08 22:36:59 +000032#include "StrongInlines.h"
weinig@apple.comefdce0f2008-06-30 20:52:03 +000033
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000034namespace JSC {
antti@apple.com6261f1f2010-12-07 11:11:08 +000035
akling@apple.com2de49b72014-07-30 22:26:22 +000036const ClassInfo JSString::s_info = { "string", 0, 0, CREATE_METHOD_TABLE(JSString) };
oliver@apple.com23ce68f2011-04-25 21:21:28 +000037
msaboff@apple.com6e74e922012-04-27 23:51:17 +000038void JSRopeString::RopeBuilder::expand()
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000039{
msaboff@apple.com6e74e922012-04-27 23:51:17 +000040 ASSERT(m_index == JSRopeString::s_maxInternalRopeLength);
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000041 JSString* jsString = m_jsString;
fpizlo@apple.com75104a32014-04-15 23:33:11 +000042 RELEASE_ASSERT(jsString);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000043 m_jsString = jsStringBuilder(&m_vm);
ggaren@apple.comffbe44d2011-10-19 19:45:35 +000044 m_index = 0;
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000045 append(jsString);
46}
47
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +000048void JSString::destroy(JSCell* cell)
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000049{
ggaren@apple.com72da8112012-05-26 22:40:46 +000050 JSString* thisObject = static_cast<JSString*>(cell);
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +000051 thisObject->JSString::~JSString();
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000052}
53
mhahnenberg@apple.com040ef242014-04-05 20:05:04 +000054void JSString::dumpToStream(const JSCell* cell, PrintStream& out)
55{
56 const JSString* thisObject = jsCast<const JSString*>(cell);
akling@apple.com63e35432014-05-05 06:24:44 +000057 out.printf("<%p, %s, [%u], ", thisObject, thisObject->className(), thisObject->length());
mhahnenberg@apple.com040ef242014-04-05 20:05:04 +000058 if (thisObject->isRope())
59 out.printf("[rope]");
60 else {
61 WTF::StringImpl* ourImpl = thisObject->m_value.impl();
62 if (ourImpl->is8Bit())
63 out.printf("[8 %p]", ourImpl->characters8());
64 else
65 out.printf("[16 %p]", ourImpl->characters16());
66 }
67 out.printf(">");
68}
69
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000070void JSString::visitChildren(JSCell* cell, SlotVisitor& visitor)
71{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +000072 JSString* thisObject = jsCast<JSString*>(cell);
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000073 Base::visitChildren(thisObject, visitor);
msaboff@apple.com6e74e922012-04-27 23:51:17 +000074
75 if (thisObject->isRope())
76 static_cast<JSRopeString*>(thisObject)->visitFibers(visitor);
oliver@apple.com8cebf372013-07-25 04:03:46 +000077 else {
78 StringImpl* impl = thisObject->m_value.impl();
79 ASSERT(impl);
fpizlo@apple.com3cb36ea2015-10-05 19:35:32 +000080 visitor.reportExtraMemoryVisited(impl->costDuringGC());
oliver@apple.com8cebf372013-07-25 04:03:46 +000081 }
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +000082}
83
msaboff@apple.com6e74e922012-04-27 23:51:17 +000084void JSRopeString::visitFibers(SlotVisitor& visitor)
85{
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +000086 if (isSubstring()) {
87 visitor.append(&substringBase());
88 return;
89 }
90 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
91 visitor.append(&fiber(i));
msaboff@apple.com6e74e922012-04-27 23:51:17 +000092}
93
akling@apple.com63e35432014-05-05 06:24:44 +000094static const unsigned maxLengthForOnStackResolve = 2048;
95
96void JSRopeString::resolveRopeInternal8(LChar* buffer) const
97{
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +000098 if (isSubstring()) {
99 StringImpl::copyChars(
100 buffer, substringBase()->m_value.characters8() + substringOffset(), m_length);
101 return;
102 }
103
104 resolveRopeInternal8NoSubstring(buffer);
105}
106
107void JSRopeString::resolveRopeInternal8NoSubstring(LChar* buffer) const
108{
109 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
110 if (fiber(i)->isRope()) {
akling@apple.com63e35432014-05-05 06:24:44 +0000111 resolveRopeSlowCase8(buffer);
112 return;
113 }
114 }
115
116 LChar* position = buffer;
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000117 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
118 const StringImpl& fiberString = *fiber(i)->m_value.impl();
akling@apple.com63e35432014-05-05 06:24:44 +0000119 unsigned length = fiberString.length();
120 StringImpl::copyChars(position, fiberString.characters8(), length);
121 position += length;
122 }
123 ASSERT((buffer + m_length) == position);
124}
125
126void JSRopeString::resolveRopeInternal16(UChar* buffer) const
127{
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000128 if (isSubstring()) {
129 StringImpl::copyChars(
130 buffer, substringBase()->m_value.characters16() + substringOffset(), m_length);
131 return;
132 }
133
134 resolveRopeInternal16NoSubstring(buffer);
135}
136
137void JSRopeString::resolveRopeInternal16NoSubstring(UChar* buffer) const
138{
139 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
140 if (fiber(i)->isRope()) {
akling@apple.com63e35432014-05-05 06:24:44 +0000141 resolveRopeSlowCase(buffer);
142 return;
143 }
144 }
145
146 UChar* position = buffer;
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000147 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
148 const StringImpl& fiberString = *fiber(i)->m_value.impl();
akling@apple.com63e35432014-05-05 06:24:44 +0000149 unsigned length = fiberString.length();
150 if (fiberString.is8Bit())
151 StringImpl::copyChars(position, fiberString.characters8(), length);
152 else
153 StringImpl::copyChars(position, fiberString.characters16(), length);
154 position += length;
155 }
156 ASSERT((buffer + m_length) == position);
157}
158
159void JSRopeString::resolveRopeToAtomicString(ExecState* exec) const
160{
161 if (m_length > maxLengthForOnStackResolve) {
162 resolveRope(exec);
163 m_value = AtomicString(m_value);
akling@apple.coma8c49de2014-08-18 21:33:01 +0000164 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000165 return;
166 }
167
168 if (is8Bit()) {
169 LChar buffer[maxLengthForOnStackResolve];
170 resolveRopeInternal8(buffer);
171 m_value = AtomicString(buffer, m_length);
akling@apple.coma8c49de2014-08-18 21:33:01 +0000172 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000173 } else {
174 UChar buffer[maxLengthForOnStackResolve];
175 resolveRopeInternal16(buffer);
176 m_value = AtomicString(buffer, m_length);
akling@apple.coma8c49de2014-08-18 21:33:01 +0000177 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000178 }
179
180 clearFibers();
181
182 // If we resolved a string that didn't previously exist, notify the heap that we've grown.
183 if (m_value.impl()->hasOneRef())
ggaren@apple.come2ebb8c2015-03-11 21:29:57 +0000184 Heap::heap(this)->reportExtraMemoryAllocated(m_value.impl()->cost());
akling@apple.com63e35432014-05-05 06:24:44 +0000185}
186
187void JSRopeString::clearFibers() const
188{
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000189 for (size_t i = 0; i < s_maxInternalRopeLength; ++i)
190 u[i].number = 0;
akling@apple.com63e35432014-05-05 06:24:44 +0000191}
192
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000193RefPtr<AtomicStringImpl> JSRopeString::resolveRopeToExistingAtomicString(ExecState* exec) const
akling@apple.com63e35432014-05-05 06:24:44 +0000194{
195 if (m_length > maxLengthForOnStackResolve) {
196 resolveRope(exec);
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000197 if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(m_value.impl())) {
akling@apple.com63e35432014-05-05 06:24:44 +0000198 m_value = *existingAtomicString;
akling@apple.coma8c49de2014-08-18 21:33:01 +0000199 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000200 clearFibers();
201 return existingAtomicString;
202 }
203 return nullptr;
204 }
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000205
akling@apple.com63e35432014-05-05 06:24:44 +0000206 if (is8Bit()) {
207 LChar buffer[maxLengthForOnStackResolve];
208 resolveRopeInternal8(buffer);
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000209 if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, m_length)) {
akling@apple.com63e35432014-05-05 06:24:44 +0000210 m_value = *existingAtomicString;
akling@apple.coma8c49de2014-08-18 21:33:01 +0000211 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000212 clearFibers();
213 return existingAtomicString;
214 }
215 } else {
216 UChar buffer[maxLengthForOnStackResolve];
217 resolveRopeInternal16(buffer);
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000218 if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, m_length)) {
akling@apple.com63e35432014-05-05 06:24:44 +0000219 m_value = *existingAtomicString;
akling@apple.coma8c49de2014-08-18 21:33:01 +0000220 setIs8Bit(m_value.impl()->is8Bit());
akling@apple.com63e35432014-05-05 06:24:44 +0000221 clearFibers();
222 return existingAtomicString;
223 }
224 }
225
226 return nullptr;
227}
228
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000229void JSRopeString::resolveRope(ExecState* exec) const
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000230{
231 ASSERT(isRope());
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000232
233 if (isSubstring()) {
234 ASSERT(!substringBase()->isRope());
235 m_value = substringBase()->m_value.substring(substringOffset(), m_length);
236 substringBase().clear();
237 return;
238 }
239
msaboff@apple.com203e7852011-11-14 23:51:06 +0000240 if (is8Bit()) {
241 LChar* buffer;
commit-queue@webkit.org1a15efe2012-02-28 16:02:02 +0000242 if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
ggaren@apple.come2ebb8c2015-03-11 21:29:57 +0000243 Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost());
msaboff@apple.com0111dc82011-11-15 00:16:59 +0000244 m_value = newImpl.release();
commit-queue@webkit.org1a15efe2012-02-28 16:02:02 +0000245 } else {
msaboff@apple.com203e7852011-11-14 23:51:06 +0000246 outOfMemory(exec);
247 return;
248 }
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000249 resolveRopeInternal8NoSubstring(buffer);
akling@apple.com63e35432014-05-05 06:24:44 +0000250 clearFibers();
msaboff@apple.com203e7852011-11-14 23:51:06 +0000251 ASSERT(!isRope());
msaboff@apple.com203e7852011-11-14 23:51:06 +0000252 return;
253 }
254
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000255 UChar* buffer;
commit-queue@webkit.org1a15efe2012-02-28 16:02:02 +0000256 if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
ggaren@apple.come2ebb8c2015-03-11 21:29:57 +0000257 Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost());
msaboff@apple.com0111dc82011-11-15 00:16:59 +0000258 m_value = newImpl.release();
commit-queue@webkit.org1a15efe2012-02-28 16:02:02 +0000259 } else {
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000260 outOfMemory(exec);
261 return;
262 }
263
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000264 resolveRopeInternal16NoSubstring(buffer);
akling@apple.com63e35432014-05-05 06:24:44 +0000265 clearFibers();
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000266 ASSERT(!isRope());
267}
268
msaboff@apple.com203e7852011-11-14 23:51:06 +0000269// Overview: These functions convert a JSString from holding a string in rope form
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000270// down to a simple String representation. It does so by building up the string
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000271// backwards, since we want to avoid recursion, we expect that the tree structure
272// representing the rope is likely imbalanced with more nodes down the left side
273// (since appending to the string is likely more common) - and as such resolving
274// in this fashion should minimize work queue size. (If we built the queue forwards
barraclough@apple.com4d95c9e2010-08-10 22:32:19 +0000275// we would likely have to place all of the constituent StringImpls into the
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000276// Vector before performing any concatenation, but by working backwards we likely
277// only fill the queue with the number of substrings at any given level in a
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000278// rope-of-ropes.)
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000279void JSRopeString::resolveRopeSlowCase8(LChar* buffer) const
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000280{
msaboff@apple.com203e7852011-11-14 23:51:06 +0000281 LChar* position = buffer + m_length; // We will be working backwards over the rope.
oliver@apple.com4e3f9652013-04-08 04:14:50 +0000282 Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // Putting strings into a Vector is only OK because there are no GC points in this method.
ggaren@apple.comffbe44d2011-10-19 19:45:35 +0000283
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000284 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
285 workQueue.append(fiber(i).get());
ggaren@apple.comffbe44d2011-10-19 19:45:35 +0000286
287 while (!workQueue.isEmpty()) {
288 JSString* currentFiber = workQueue.last();
289 workQueue.removeLast();
akling@apple.com77ee6bf2014-05-05 06:10:03 +0000290
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000291 const LChar* characters;
292
ggaren@apple.comfbf6d9a2011-10-19 02:54:29 +0000293 if (currentFiber->isRope()) {
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000294 JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000295 if (!currentFiberAsRope->isSubstring()) {
296 for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
297 workQueue.append(currentFiberAsRope->fiber(i).get());
298 continue;
299 }
300 ASSERT(!currentFiberAsRope->substringBase()->isRope());
301 characters =
302 currentFiberAsRope->substringBase()->m_value.characters8() +
303 currentFiberAsRope->substringOffset();
304 } else
305 characters = currentFiber->m_value.characters8();
306
307 unsigned length = currentFiber->length();
ggaren@apple.comffbe44d2011-10-19 19:45:35 +0000308 position -= length;
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000309 StringImpl::copyChars(position, characters, length);
msaboff@apple.com203e7852011-11-14 23:51:06 +0000310 }
311
312 ASSERT(buffer == position);
msaboff@apple.com203e7852011-11-14 23:51:06 +0000313}
314
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000315void JSRopeString::resolveRopeSlowCase(UChar* buffer) const
msaboff@apple.com203e7852011-11-14 23:51:06 +0000316{
msaboff@apple.com203e7852011-11-14 23:51:06 +0000317 UChar* position = buffer + m_length; // We will be working backwards over the rope.
oliver@apple.com4e3f9652013-04-08 04:14:50 +0000318 Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // These strings are kept alive by the parent rope, so using a Vector is OK.
msaboff@apple.com203e7852011-11-14 23:51:06 +0000319
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000320 for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
321 workQueue.append(fiber(i).get());
msaboff@apple.com203e7852011-11-14 23:51:06 +0000322
323 while (!workQueue.isEmpty()) {
324 JSString* currentFiber = workQueue.last();
325 workQueue.removeLast();
326
327 if (currentFiber->isRope()) {
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000328 JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +0000329 if (currentFiberAsRope->isSubstring()) {
330 ASSERT(!currentFiberAsRope->substringBase()->isRope());
331 StringImpl* string = static_cast<StringImpl*>(
332 currentFiberAsRope->substringBase()->m_value.impl());
333 unsigned offset = currentFiberAsRope->substringOffset();
334 unsigned length = currentFiberAsRope->length();
335 position -= length;
336 if (string->is8Bit())
337 StringImpl::copyChars(position, string->characters8() + offset, length);
338 else
339 StringImpl::copyChars(position, string->characters16() + offset, length);
340 continue;
341 }
342 for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
343 workQueue.append(currentFiberAsRope->fiber(i).get());
msaboff@apple.com203e7852011-11-14 23:51:06 +0000344 continue;
345 }
346
347 StringImpl* string = static_cast<StringImpl*>(currentFiber->m_value.impl());
348 unsigned length = string->length();
349 position -= length;
msaboff@apple.comf25bc162012-09-07 01:29:12 +0000350 if (string->is8Bit())
351 StringImpl::copyChars(position, string->characters8(), length);
352 else
353 StringImpl::copyChars(position, string->characters16(), length);
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000354 }
ggaren@apple.comffbe44d2011-10-19 19:45:35 +0000355
356 ASSERT(buffer == position);
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000357}
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000358
msaboff@apple.com6e74e922012-04-27 23:51:17 +0000359void JSRopeString::outOfMemory(ExecState* exec) const
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000360{
akling@apple.com63e35432014-05-05 06:24:44 +0000361 clearFibers();
commit-queue@webkit.org7914d5a2012-02-23 19:29:14 +0000362 ASSERT(isRope());
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000363 ASSERT(m_value.isNull());
msaboff@apple.com8cae2b12011-04-21 17:23:16 +0000364 if (exec)
365 throwOutOfMemoryError(exec);
366}
367
ggaren@apple.comdc067b62009-05-01 22:43:39 +0000368JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000369{
weinig@apple.com2947a912008-07-07 02:49:29 +0000370 return const_cast<JSString*>(this);
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000371}
372
mhahnenberg@apple.com061133e2011-09-27 19:53:49 +0000373bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) const
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000374{
barraclough@apple.com35d680c2009-12-04 02:15:18 +0000375 result = this;
akling@apple.com7e84ac52015-05-19 17:06:23 +0000376 number = jsToNumber(view(exec));
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000377 return false;
378}
379
barraclough@apple.comb749f0b2009-12-07 23:14:04 +0000380double JSString::toNumber(ExecState* exec) const
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000381{
akling@apple.com7e84ac52015-05-19 17:06:23 +0000382 return jsToNumber(view(exec));
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000383}
384
akling@apple.com019809c2013-10-06 18:16:48 +0000385inline StringObject* StringObject::create(VM& vm, JSGlobalObject* globalObject, JSString* string)
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000386{
akling@apple.com019809c2013-10-06 18:16:48 +0000387 StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, globalObject->stringObjectStructure());
388 object->finishCreation(vm, string);
mhahnenberg@apple.com7317a7f2011-09-09 21:43:14 +0000389 return object;
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000390}
391
oliver@apple.com3b6dc572011-03-28 23:39:16 +0000392JSObject* JSString::toObject(ExecState* exec, JSGlobalObject* globalObject) const
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000393{
akling@apple.com019809c2013-10-06 18:16:48 +0000394 return StringObject::create(exec->vm(), globalObject, const_cast<JSString*>(this));
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000395}
396
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000397JSValue JSString::toThis(JSCell* cell, ExecState* exec, ECMAMode ecmaMode)
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000398{
oliver@apple.come2fe4ce2013-07-25 03:59:41 +0000399 if (ecmaMode == StrictMode)
400 return cell;
akling@apple.com019809c2013-10-06 18:16:48 +0000401 return StringObject::create(exec->vm(), exec->lexicalGlobalObject(), jsCast<JSString*>(cell));
weinig@apple.comefdce0f2008-06-30 20:52:03 +0000402}
403
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000404bool JSString::getStringPropertyDescriptor(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000405{
406 if (propertyName == exec->propertyNames().length) {
oliver@apple.com5b67d9e2010-10-25 22:40:53 +0000407 descriptor.setDescriptor(jsNumber(m_length), DontEnum | DontDelete | ReadOnly);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000408 return true;
409 }
410
utatane.tea@gmail.comc7c203c2015-04-06 12:40:33 +0000411 Optional<uint32_t> index = parseIndex(propertyName);
412 if (index && index.value() < m_length) {
413 descriptor.setDescriptor(getIndex(exec, index.value()), DontDelete | ReadOnly);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000414 return true;
415 }
416
417 return false;
418}
419
akling@apple.comc3e85a62014-07-05 03:36:36 +0000420JSString* jsStringWithCacheSlowCase(VM& vm, StringImpl& stringImpl)
421{
akling@apple.com926b1102015-03-10 00:09:39 +0000422 if (JSString* string = vm.stringCache.get(&stringImpl))
423 return string;
424
425 JSString* string = jsString(&vm, String(stringImpl));
426 vm.lastCachedString.set(vm, string);
427 return string;
akling@apple.comc3e85a62014-07-05 03:36:36 +0000428}
429
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000430} // namespace JSC