source: webkit/trunk/JavaScriptCore/runtime/JSString.h@ 38463

Last change on this file since 38463 was 38463, checked in by [email protected], 17 years ago

2008-11-16 Geoffrey Garen <[email protected]>

Roll out r38461 (my last patch) because it broke the world.

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
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
25
26#include "CommonIdentifiers.h"
27#include "ExecState.h"
28#include "Identifier.h"
29#include "JSNumberCell.h"
30#include "PropertySlot.h"
31
32namespace JSC {
33
34 class JSString;
35
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
40
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);
47
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*);
54
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&);
60
61 class JSString : public JSCell {
62 friend class CTI;
63 friend class BytecodeInterpreter;
64
65 public:
66 JSString(JSGlobalData* globalData, const UString& value)
67 : JSCell(globalData->stringStructure.get())
68 , m_value(value)
69 {
70 Heap::heap(this)->reportExtraMemoryCost(value.cost());
71 }
72
73 enum HasOtherOwnerType { HasOtherOwner };
74 JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
75 : JSCell(globalData->stringStructure.get())
76 , m_value(value)
77 {
78 }
79 JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
80 : JSCell(globalData->stringStructure.get())
81 , m_value(value)
82 {
83 }
84
85 const UString& value() const { return m_value; }
86
87 bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
88 bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
89
90 bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
91 JSString* getIndex(JSGlobalData*, unsigned);
92
93 static PassRefPtr<Structure> createStructure(JSValue* proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
94
95 private:
96 enum VPtrStealingHackType { VPtrStealingHack };
97 JSString(VPtrStealingHackType)
98 : JSCell(0)
99 {
100 }
101
102 virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
103 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& 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;
108
109 virtual JSObject* toThisObject(ExecState*) const;
110 virtual UString toThisString(ExecState*) const;
111 virtual JSString* toThisJSString(ExecState*);
112
113 // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
114 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
115 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
116
117 UString m_value;
118 };
119
120 JSString* asString(JSValue*);
121
122 inline JSString* asString(JSValue* value)
123 {
124 ASSERT(asCell(value)->isString());
125 return static_cast<JSString*>(asCell(value));
126 }
127
128 inline JSString* jsEmptyString(JSGlobalData* globalData)
129 {
130 return globalData->smallStrings.emptyString(globalData);
131 }
132
133 inline JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
134 {
135 if (c <= 0xFF)
136 return globalData->smallStrings.singleCharacterString(globalData, c);
137 return new (globalData) JSString(globalData, UString(&c, 1));
138 }
139
140 inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset)
141 {
142 ASSERT(offset < static_cast<unsigned>(s.size()));
143 UChar c = s.data()[offset];
144 if (c <= 0xFF)
145 return globalData->smallStrings.singleCharacterString(globalData, c);
146 return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, 1));
147 }
148
149 inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
150 {
151 ASSERT(s);
152 ASSERT(s[0]);
153 ASSERT(s[1]);
154 return new (globalData) JSString(globalData, s);
155 }
156
157 inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s)
158 {
159 ASSERT(s.size() > 1);
160 return new (globalData) JSString(globalData, s);
161 }
162
163 inline JSString* JSString::getIndex(JSGlobalData* globalData, unsigned i)
164 {
165 ASSERT(canGetIndex(i));
166 return jsSingleCharacterSubstring(globalData, m_value, i);
167 }
168
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); }
177
178 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
179 {
180 if (propertyName == exec->propertyNames().length) {
181 slot.setValue(jsNumber(exec, m_value.size()));
182 return true;
183 }
184
185 bool isStrictUInt32;
186 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
187 if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
188 slot.setValue(jsSingleCharacterSubstring(exec, m_value, i));
189 return true;
190 }
191
192 return false;
193 }
194
195 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
196 {
197 if (propertyName < static_cast<unsigned>(m_value.size())) {
198 slot.setValue(jsSingleCharacterSubstring(exec, m_value, propertyName));
199 return true;
200 }
201
202 return false;
203 }
204
205 // --- JSValue inlines ----------------------------
206
207 inline JSString* JSValue::toThisJSString(ExecState* exec)
208 {
209 return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
210 }
211
212} // namespace JSC
213
214#endif // JSString_h
Note: See TracBrowser for help on using the repository browser.