]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSString.h
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.
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.
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.
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.
26 #include "CommonIdentifiers.h"
27 #include "CallFrame.h"
28 #include "Identifier.h"
29 #include "JSNumberCell.h"
30 #include "PropertySlot.h"
36 JSString
* jsEmptyString(JSGlobalData
*);
37 JSString
* jsEmptyString(ExecState
*);
38 JSString
* jsString(JSGlobalData
*, const UString
&); // returns empty string if passed null string
39 JSString
* jsString(ExecState
*, const UString
&); // returns empty string if passed null string
41 JSString
* jsSingleCharacterString(JSGlobalData
*, UChar
);
42 JSString
* jsSingleCharacterString(ExecState
*, UChar
);
43 JSString
* jsSingleCharacterSubstring(JSGlobalData
*, const UString
&, unsigned offset
);
44 JSString
* jsSingleCharacterSubstring(ExecState
*, const UString
&, unsigned offset
);
45 JSString
* jsSubstring(JSGlobalData
*, const UString
&, unsigned offset
, unsigned length
);
46 JSString
* jsSubstring(ExecState
*, const UString
&, unsigned offset
, unsigned length
);
48 // Non-trivial strings are two or more characters long.
49 // These functions are faster than just calling jsString.
50 JSString
* jsNontrivialString(JSGlobalData
*, const UString
&);
51 JSString
* jsNontrivialString(ExecState
*, const UString
&);
52 JSString
* jsNontrivialString(JSGlobalData
*, const char*);
53 JSString
* jsNontrivialString(ExecState
*, const char*);
55 // Should be used for strings that are owned by an object that will
56 // likely outlive the JSValue this makes, such as the parse tree or a
57 // DOM object that contains a UString
58 JSString
* jsOwnedString(JSGlobalData
*, const UString
&);
59 JSString
* jsOwnedString(ExecState
*, const UString
&);
61 class JSString
: public JSCell
{
63 friend class Interpreter
;
66 JSString(JSGlobalData
* globalData
, const UString
& value
)
67 : JSCell(globalData
->stringStructure
.get())
70 Heap::heap(this)->reportExtraMemoryCost(value
.cost());
73 enum HasOtherOwnerType
{ HasOtherOwner
};
74 JSString(JSGlobalData
* globalData
, const UString
& value
, HasOtherOwnerType
)
75 : JSCell(globalData
->stringStructure
.get())
79 JSString(JSGlobalData
* globalData
, PassRefPtr
<UString::Rep
> value
, HasOtherOwnerType
)
80 : JSCell(globalData
->stringStructure
.get())
85 const UString
& value() const { return m_value
; }
87 bool getStringPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
88 bool getStringPropertySlot(ExecState
*, unsigned propertyName
, PropertySlot
&);
90 bool canGetIndex(unsigned i
) { return i
< static_cast<unsigned>(m_value
.size()); }
91 JSString
* getIndex(JSGlobalData
*, unsigned);
93 static PassRefPtr
<Structure
> createStructure(JSValuePtr proto
) { return Structure::create(proto
, TypeInfo(StringType
, NeedsThisConversion
)); }
96 enum VPtrStealingHackType
{ VPtrStealingHack
};
97 JSString(VPtrStealingHackType
)
102 virtual JSValuePtr
toPrimitive(ExecState
*, PreferredPrimitiveType
) const;
103 virtual bool getPrimitiveNumber(ExecState
*, double& number
, JSValuePtr
& value
);
104 virtual bool toBoolean(ExecState
*) const;
105 virtual double toNumber(ExecState
*) const;
106 virtual JSObject
* toObject(ExecState
*) const;
107 virtual UString
toString(ExecState
*) const;
109 virtual JSObject
* toThisObject(ExecState
*) const;
110 virtual UString
toThisString(ExecState
*) const;
111 virtual JSString
* toThisJSString(ExecState
*);
113 // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
114 virtual bool getOwnPropertySlot(ExecState
*, const Identifier
& propertyName
, PropertySlot
&);
115 virtual bool getOwnPropertySlot(ExecState
*, unsigned propertyName
, PropertySlot
&);
120 JSString
* asString(JSValuePtr
);
122 inline JSString
* asString(JSValuePtr value
)
124 ASSERT(asCell(value
)->isString());
125 return static_cast<JSString
*>(asCell(value
));
128 inline JSString
* jsEmptyString(JSGlobalData
* globalData
)
130 return globalData
->smallStrings
.emptyString(globalData
);
133 inline JSString
* jsSingleCharacterString(JSGlobalData
* globalData
, UChar c
)
136 return globalData
->smallStrings
.singleCharacterString(globalData
, c
);
137 return new (globalData
) JSString(globalData
, UString(&c
, 1));
140 inline JSString
* jsSingleCharacterSubstring(JSGlobalData
* globalData
, const UString
& s
, unsigned offset
)
142 ASSERT(offset
< static_cast<unsigned>(s
.size()));
143 UChar c
= s
.data()[offset
];
145 return globalData
->smallStrings
.singleCharacterString(globalData
, c
);
146 return new (globalData
) JSString(globalData
, UString::Rep::create(s
.rep(), offset
, 1));
149 inline JSString
* jsNontrivialString(JSGlobalData
* globalData
, const char* s
)
154 return new (globalData
) JSString(globalData
, s
);
157 inline JSString
* jsNontrivialString(JSGlobalData
* globalData
, const UString
& s
)
159 ASSERT(s
.size() > 1);
160 return new (globalData
) JSString(globalData
, s
);
163 inline JSString
* JSString::getIndex(JSGlobalData
* globalData
, unsigned i
)
165 ASSERT(canGetIndex(i
));
166 return jsSingleCharacterSubstring(globalData
, m_value
, i
);
169 inline JSString
* jsEmptyString(ExecState
* exec
) { return jsEmptyString(&exec
->globalData()); }
170 inline JSString
* jsString(ExecState
* exec
, const UString
& s
) { return jsString(&exec
->globalData(), s
); }
171 inline JSString
* jsSingleCharacterString(ExecState
* exec
, UChar c
) { return jsSingleCharacterString(&exec
->globalData(), c
); }
172 inline JSString
* jsSingleCharacterSubstring(ExecState
* exec
, const UString
& s
, unsigned offset
) { return jsSingleCharacterSubstring(&exec
->globalData(), s
, offset
); }
173 inline JSString
* jsSubstring(ExecState
* exec
, const UString
& s
, unsigned offset
, unsigned length
) { return jsSubstring(&exec
->globalData(), s
, offset
, length
); }
174 inline JSString
* jsNontrivialString(ExecState
* exec
, const UString
& s
) { return jsNontrivialString(&exec
->globalData(), s
); }
175 inline JSString
* jsNontrivialString(ExecState
* exec
, const char* s
) { return jsNontrivialString(&exec
->globalData(), s
); }
176 inline JSString
* jsOwnedString(ExecState
* exec
, const UString
& s
) { return jsOwnedString(&exec
->globalData(), s
); }
178 ALWAYS_INLINE
bool JSString::getStringPropertySlot(ExecState
* exec
, const Identifier
& propertyName
, PropertySlot
& slot
)
180 if (propertyName
== exec
->propertyNames().length
) {
181 slot
.setValue(jsNumber(exec
, m_value
.size()));
186 unsigned i
= propertyName
.toStrictUInt32(&isStrictUInt32
);
187 if (isStrictUInt32
&& i
< static_cast<unsigned>(m_value
.size())) {
188 slot
.setValue(jsSingleCharacterSubstring(exec
, m_value
, i
));
195 ALWAYS_INLINE
bool JSString::getStringPropertySlot(ExecState
* exec
, unsigned propertyName
, PropertySlot
& slot
)
197 if (propertyName
< static_cast<unsigned>(m_value
.size())) {
198 slot
.setValue(jsSingleCharacterSubstring(exec
, m_value
, propertyName
));
205 // --- JSValue inlines ----------------------------
207 inline JSString
* JSValuePtr::toThisJSString(ExecState
* exec
)
209 return JSImmediate::isImmediate(asValue()) ? jsString(exec
, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec
);