]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSString.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / runtime / JSString.h
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 *
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#ifndef JSString_h
24#define JSString_h
9dae56ea 25#include "CallFrame.h"
ba379fdc 26#include "CommonIdentifiers.h"
9dae56ea 27#include "Identifier.h"
f9bf01c6 28#include "PropertyDescriptor.h"
9dae56ea 29#include "PropertySlot.h"
14957cd0 30#include "Structure.h"
9dae56ea
A
31
32namespace JSC {
33
34 class JSString;
6fe7ccc8
A
35 class JSRopeString;
36 class LLIntOffsetsExtractor;
9dae56ea
A
37
38 JSString* jsEmptyString(JSGlobalData*);
39 JSString* jsEmptyString(ExecState*);
40 JSString* jsString(JSGlobalData*, const UString&); // returns empty string if passed null string
41 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string
42
43 JSString* jsSingleCharacterString(JSGlobalData*, UChar);
44 JSString* jsSingleCharacterString(ExecState*, UChar);
9dae56ea
A
45 JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset);
46 JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length);
47 JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length);
48
49 // Non-trivial strings are two or more characters long.
50 // These functions are faster than just calling jsString.
51 JSString* jsNontrivialString(JSGlobalData*, const UString&);
52 JSString* jsNontrivialString(ExecState*, const UString&);
53 JSString* jsNontrivialString(JSGlobalData*, const char*);
54 JSString* jsNontrivialString(ExecState*, const char*);
55
56 // Should be used for strings that are owned by an object that will
57 // likely outlive the JSValue this makes, such as the parse tree or a
58 // DOM object that contains a UString
59 JSString* jsOwnedString(JSGlobalData*, const UString&);
60 JSString* jsOwnedString(ExecState*, const UString&);
61
6fe7ccc8
A
62 JSRopeString* jsStringBuilder(JSGlobalData*);
63
64 class JSString : public JSCell {
9dae56ea 65 public:
f9bf01c6
A
66 friend class JIT;
67 friend class JSGlobalData;
4e4e5a6f 68 friend class SpecializedThunkJIT;
6fe7ccc8 69 friend class JSRopeString;
4e4e5a6f 70 friend struct ThunkHelpers;
f9bf01c6 71
6fe7ccc8 72 typedef JSCell Base;
f9bf01c6 73
6fe7ccc8 74 static void destroy(JSCell*);
4e4e5a6f 75
6fe7ccc8
A
76 private:
77 JSString(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
78 : JSCell(globalData, globalData.stringStructure.get())
9dae56ea
A
79 , m_value(value)
80 {
9dae56ea
A
81 }
82
6fe7ccc8
A
83 JSString(JSGlobalData& globalData)
84 : JSCell(globalData, globalData.stringStructure.get())
9dae56ea 85 {
f9bf01c6
A
86 }
87
6fe7ccc8 88 void finishCreation(JSGlobalData& globalData, size_t length)
4e4e5a6f 89 {
6fe7ccc8
A
90 ASSERT(!m_value.isNull());
91 Base::finishCreation(globalData);
92 m_length = length;
93 m_is8Bit = m_value.impl()->is8Bit();
4e4e5a6f
A
94 }
95
6fe7ccc8 96 void finishCreation(JSGlobalData& globalData, size_t length, size_t cost)
4e4e5a6f 97 {
6fe7ccc8
A
98 ASSERT(!m_value.isNull());
99 Base::finishCreation(globalData);
100 m_length = length;
101 m_is8Bit = m_value.impl()->is8Bit();
102 Heap::heap(this)->reportExtraMemoryCost(cost);
4e4e5a6f
A
103 }
104
6fe7ccc8
A
105 protected:
106 void finishCreation(JSGlobalData& globalData)
f9bf01c6 107 {
6fe7ccc8
A
108 Base::finishCreation(globalData);
109 m_length = 0;
110 m_is8Bit = true;
f9bf01c6 111 }
6fe7ccc8
A
112
113 public:
114 static JSString* create(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
f9bf01c6 115 {
6fe7ccc8
A
116 ASSERT(value);
117 size_t length = value->length();
118 size_t cost = value->cost();
119 JSString* newString = new (NotNull, allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
120 newString->finishCreation(globalData, length, cost);
121 return newString;
f9bf01c6 122 }
6fe7ccc8 123 static JSString* createHasOtherOwner(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
f9bf01c6 124 {
6fe7ccc8
A
125 ASSERT(value);
126 size_t length = value->length();
127 JSString* newString = new (NotNull, allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
128 newString->finishCreation(globalData, length);
129 return newString;
f9bf01c6 130 }
6fe7ccc8
A
131
132 const UString& value(ExecState*) const;
133 const UString& tryGetValue() const;
4e4e5a6f 134 unsigned length() { return m_length; }
9dae56ea 135
6fe7ccc8
A
136 JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
137 JS_EXPORT_PRIVATE bool toBoolean(ExecState*) const;
138 bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
139 JSObject* toObject(ExecState*, JSGlobalObject*) const;
140 double toNumber(ExecState*) const;
141
9dae56ea
A
142 bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
143 bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
f9bf01c6 144 bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
9dae56ea 145
4e4e5a6f 146 bool canGetIndex(unsigned i) { return i < m_length; }
f9bf01c6 147 JSString* getIndex(ExecState*, unsigned);
9dae56ea 148
6fe7ccc8 149 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
14957cd0 150 {
6fe7ccc8 151 return Structure::create(globalData, globalObject, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot), &s_info);
14957cd0 152 }
6fe7ccc8
A
153
154 static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
155 static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
156
157 static JS_EXPORTDATA const ClassInfo s_info;
158
159 static void visitChildren(JSCell*, SlotVisitor&);
160
161 protected:
162 bool isRope() const { return m_value.isNull(); }
163 bool is8Bit() const { return m_is8Bit; }
164
165 // A string is represented either by a UString or a rope of fibers.
166 bool m_is8Bit : 1;
167 unsigned m_length;
168 mutable UString m_value;
169
170 private:
171 friend class LLIntOffsetsExtractor;
14957cd0 172
6fe7ccc8
A
173 static JSObject* toThisObject(JSCell*, ExecState*);
174
175 // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
176 static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
177 static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
178
179 UString& string() { ASSERT(!isRope()); return m_value; }
180
181 friend JSValue jsString(ExecState*, JSString*, JSString*);
182 friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
183 };
184
185 class JSRopeString : public JSString {
186 friend class JSString;
9dae56ea 187
6fe7ccc8
A
188 friend JSRopeString* jsStringBuilder(JSGlobalData*);
189
190 class RopeBuilder {
191 public:
192 RopeBuilder(JSGlobalData& globalData)
193 : m_globalData(globalData)
194 , m_jsString(jsStringBuilder(&globalData))
195 , m_index(0)
196 {
197 }
198
199 void append(JSString* jsString)
200 {
201 if (m_index == JSRopeString::s_maxInternalRopeLength)
202 expand();
203 m_jsString->m_fibers[m_index++].set(m_globalData, m_jsString, jsString);
204 m_jsString->m_length += jsString->m_length;
205 m_jsString->m_is8Bit = m_jsString->m_is8Bit && jsString->m_is8Bit;
206 }
207
208 JSRopeString* release()
209 {
210 JSRopeString* tmp = m_jsString;
211 m_jsString = 0;
212 return tmp;
213 }
214
215 unsigned length() { return m_jsString->m_length; }
216
217 private:
218 void expand();
219
220 JSGlobalData& m_globalData;
221 JSRopeString* m_jsString;
222 size_t m_index;
223 };
224
9dae56ea 225 private:
6fe7ccc8
A
226 JSRopeString(JSGlobalData& globalData)
227 : JSString(globalData)
f9bf01c6
A
228 {
229 }
230
6fe7ccc8
A
231 void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2)
232 {
233 Base::finishCreation(globalData);
234 m_length = s1->length() + s2->length();
235 m_is8Bit = (s1->is8Bit() && s2->is8Bit());
236 m_fibers[0].set(globalData, this, s1);
237 m_fibers[1].set(globalData, this, s2);
238 }
239
240 void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
241 {
242 Base::finishCreation(globalData);
243 m_length = s1->length() + s2->length() + s3->length();
244 m_is8Bit = (s1->is8Bit() && s2->is8Bit() && s3->is8Bit());
245 m_fibers[0].set(globalData, this, s1);
246 m_fibers[1].set(globalData, this, s2);
247 m_fibers[2].set(globalData, this, s3);
248 }
f9bf01c6 249
6fe7ccc8 250 void finishCreation(JSGlobalData& globalData)
f9bf01c6 251 {
6fe7ccc8 252 JSString::finishCreation(globalData);
f9bf01c6
A
253 }
254
6fe7ccc8 255 static JSRopeString* createNull(JSGlobalData& globalData)
f9bf01c6 256 {
6fe7ccc8
A
257 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
258 newString->finishCreation(globalData);
259 return newString;
f9bf01c6
A
260 }
261
6fe7ccc8
A
262 public:
263 static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2)
9dae56ea 264 {
6fe7ccc8
A
265 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
266 newString->finishCreation(globalData, s1, s2);
267 return newString;
268 }
269 static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
270 {
271 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
272 newString->finishCreation(globalData, s1, s2, s3);
273 return newString;
9dae56ea
A
274 }
275
6fe7ccc8 276 void visitFibers(SlotVisitor&);
9dae56ea 277
6fe7ccc8
A
278 private:
279 friend JSValue jsString(ExecState*, Register*, unsigned);
280 friend JSValue jsStringFromArguments(ExecState*, JSValue);
9dae56ea 281
6fe7ccc8
A
282 JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
283 void resolveRopeSlowCase8(LChar*) const;
284 void resolveRopeSlowCase(UChar*) const;
285 void outOfMemory(ExecState*) const;
286
287 JSString* getIndexSlowCase(ExecState*, unsigned);
f9bf01c6
A
288
289 static const unsigned s_maxInternalRopeLength = 3;
6fe7ccc8
A
290
291 mutable FixedArray<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers;
9dae56ea
A
292 };
293
ba379fdc 294 JSString* asString(JSValue);
9dae56ea 295
ba379fdc 296 inline JSString* asString(JSValue value)
9dae56ea 297 {
14957cd0 298 ASSERT(value.asCell()->isString());
6fe7ccc8 299 return jsCast<JSString*>(value.asCell());
9dae56ea
A
300 }
301
302 inline JSString* jsEmptyString(JSGlobalData* globalData)
303 {
304 return globalData->smallStrings.emptyString(globalData);
305 }
306
6fe7ccc8 307 ALWAYS_INLINE JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
9dae56ea 308 {
14957cd0 309 if (c <= maxSingleCharacterString)
9dae56ea 310 return globalData->smallStrings.singleCharacterString(globalData, c);
6fe7ccc8 311 return JSString::create(*globalData, UString(&c, 1).impl());
9dae56ea
A
312 }
313
6fe7ccc8 314 ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset)
9dae56ea 315 {
4e4e5a6f 316 JSGlobalData* globalData = &exec->globalData();
14957cd0 317 ASSERT(offset < static_cast<unsigned>(s.length()));
6fe7ccc8 318 UChar c = s[offset];
14957cd0 319 if (c <= maxSingleCharacterString)
9dae56ea 320 return globalData->smallStrings.singleCharacterString(globalData, c);
6fe7ccc8 321 return JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1));
9dae56ea
A
322 }
323
324 inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
325 {
326 ASSERT(s);
327 ASSERT(s[0]);
328 ASSERT(s[1]);
6fe7ccc8 329 return JSString::create(*globalData, UString(s).impl());
9dae56ea
A
330 }
331
332 inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s)
333 {
14957cd0 334 ASSERT(s.length() > 1);
6fe7ccc8
A
335 return JSString::create(*globalData, s.impl());
336 }
337
338 inline const UString& JSString::value(ExecState* exec) const
339 {
340 if (isRope())
341 static_cast<const JSRopeString*>(this)->resolveRope(exec);
342 return m_value;
343 }
344
345 inline const UString& JSString::tryGetValue() const
346 {
347 if (isRope())
348 static_cast<const JSRopeString*>(this)->resolveRope(0);
349 return m_value;
9dae56ea
A
350 }
351
f9bf01c6 352 inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
9dae56ea
A
353 {
354 ASSERT(canGetIndex(i));
4e4e5a6f 355 if (isRope())
6fe7ccc8 356 return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
14957cd0 357 ASSERT(i < m_value.length());
4e4e5a6f 358 return jsSingleCharacterSubstring(exec, m_value, i);
f9bf01c6
A
359 }
360
361 inline JSString* jsString(JSGlobalData* globalData, const UString& s)
362 {
14957cd0 363 int size = s.length();
f9bf01c6
A
364 if (!size)
365 return globalData->smallStrings.emptyString(globalData);
366 if (size == 1) {
6fe7ccc8 367 UChar c = s[0];
14957cd0 368 if (c <= maxSingleCharacterString)
f9bf01c6
A
369 return globalData->smallStrings.singleCharacterString(globalData, c);
370 }
6fe7ccc8 371 return JSString::create(*globalData, s.impl());
f9bf01c6
A
372 }
373
b80e6193
A
374 inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
375 {
376 ASSERT(offset <= static_cast<unsigned>(s->length()));
377 ASSERT(length <= static_cast<unsigned>(s->length()));
378 ASSERT(offset + length <= static_cast<unsigned>(s->length()));
379 JSGlobalData* globalData = &exec->globalData();
380 if (!length)
381 return globalData->smallStrings.emptyString(globalData);
6fe7ccc8
A
382 return jsSubstring(globalData, s->value(exec), offset, length);
383 }
384
385 inline JSString* jsSubstring8(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
386 {
387 ASSERT(offset <= static_cast<unsigned>(s.length()));
388 ASSERT(length <= static_cast<unsigned>(s.length()));
389 ASSERT(offset + length <= static_cast<unsigned>(s.length()));
390 if (!length)
391 return globalData->smallStrings.emptyString(globalData);
392 if (length == 1) {
393 UChar c = s[offset];
394 if (c <= maxSingleCharacterString)
395 return globalData->smallStrings.singleCharacterString(globalData, c);
396 }
397 return JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length));
b80e6193 398 }
f9bf01c6
A
399
400 inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
401 {
14957cd0
A
402 ASSERT(offset <= static_cast<unsigned>(s.length()));
403 ASSERT(length <= static_cast<unsigned>(s.length()));
404 ASSERT(offset + length <= static_cast<unsigned>(s.length()));
f9bf01c6
A
405 if (!length)
406 return globalData->smallStrings.emptyString(globalData);
407 if (length == 1) {
6fe7ccc8 408 UChar c = s[offset];
14957cd0 409 if (c <= maxSingleCharacterString)
f9bf01c6
A
410 return globalData->smallStrings.singleCharacterString(globalData, c);
411 }
6fe7ccc8 412 return JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length));
f9bf01c6
A
413 }
414
415 inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
416 {
14957cd0 417 int size = s.length();
f9bf01c6
A
418 if (!size)
419 return globalData->smallStrings.emptyString(globalData);
420 if (size == 1) {
6fe7ccc8 421 UChar c = s[0];
14957cd0 422 if (c <= maxSingleCharacterString)
f9bf01c6
A
423 return globalData->smallStrings.singleCharacterString(globalData, c);
424 }
6fe7ccc8
A
425 return JSString::createHasOtherOwner(*globalData, s.impl());
426 }
427
428 inline JSRopeString* jsStringBuilder(JSGlobalData* globalData)
429 {
430 return JSRopeString::createNull(*globalData);
9dae56ea
A
431 }
432
433 inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
434 inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); }
435 inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); }
6fe7ccc8 436 inline JSString* jsSubstring8(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->globalData(), s, offset, length); }
9dae56ea
A
437 inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
438 inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); }
439 inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); }
440 inline JSString* jsOwnedString(ExecState* exec, const UString& s) { return jsOwnedString(&exec->globalData(), s); }
441
442 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
443 {
444 if (propertyName == exec->propertyNames().length) {
14957cd0 445 slot.setValue(jsNumber(m_length));
9dae56ea
A
446 return true;
447 }
448
449 bool isStrictUInt32;
14957cd0 450 unsigned i = propertyName.toUInt32(isStrictUInt32);
4e4e5a6f
A
451 if (isStrictUInt32 && i < m_length) {
452 slot.setValue(getIndex(exec, i));
9dae56ea
A
453 return true;
454 }
455
456 return false;
457 }
458
459 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
460 {
4e4e5a6f
A
461 if (propertyName < m_length) {
462 slot.setValue(getIndex(exec, propertyName));
9dae56ea
A
463 return true;
464 }
465
466 return false;
467 }
468
6fe7ccc8
A
469 inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSString::s_info; }
470
471 inline bool JSCell::toBoolean(ExecState* exec) const
472 {
473 if (isString())
474 return static_cast<const JSString*>(this)->toBoolean(exec);
475 return !structure()->typeInfo().masqueradesAsUndefined();
476 }
ba379fdc 477
9dae56ea 478 // --- JSValue inlines ----------------------------
6fe7ccc8
A
479
480 inline bool JSValue::toBoolean(ExecState* exec) const
481 {
482 if (isInt32())
483 return asInt32();
484 if (isDouble())
485 return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
486 if (isCell())
487 return asCell()->toBoolean(exec);
488 return isTrue(); // false, null, and undefined all convert to false.
489 }
9dae56ea 490
6fe7ccc8
A
491 inline JSString* JSValue::toString(ExecState* exec) const
492 {
493 if (isString())
494 return jsCast<JSString*>(asCell());
495 return toStringSlowCase(exec);
496 }
497
498 inline UString JSValue::toUString(ExecState* exec) const
f9bf01c6
A
499 {
500 if (isString())
501 return static_cast<JSString*>(asCell())->value(exec);
6fe7ccc8 502 return toUStringSlowCase(exec);
f9bf01c6
A
503 }
504
6fe7ccc8 505 ALWAYS_INLINE UString inlineJSValueNotStringtoUString(const JSValue& value, ExecState* exec)
f9bf01c6 506 {
6fe7ccc8
A
507 JSGlobalData& globalData = exec->globalData();
508 if (value.isInt32())
509 return globalData.numericStrings.add(value.asInt32());
510 if (value.isDouble())
511 return globalData.numericStrings.add(value.asDouble());
512 if (value.isTrue())
513 return globalData.propertyNames->trueKeyword.ustring();
514 if (value.isFalse())
515 return globalData.propertyNames->falseKeyword.ustring();
516 if (value.isNull())
517 return globalData.propertyNames->nullKeyword.ustring();
518 if (value.isUndefined())
519 return globalData.propertyNames->undefinedKeyword.ustring();
520 return value.toString(exec)->value(exec);
521 }
522
523 ALWAYS_INLINE UString JSValue::toUStringInline(ExecState* exec) const
524 {
525 if (isString())
526 return static_cast<JSString*>(asCell())->value(exec);
527
528 return inlineJSValueNotStringtoUString(*this, exec);
f9bf01c6
A
529 }
530
9dae56ea
A
531} // namespace JSC
532
533#endif // JSString_h