source: webkit/trunk/JavaScriptCore/runtime/JSString.cpp@ 65177

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

Rubber stamps by Darin Adler & Sam Weinig.

Bug 43867 - Some UString cleanup

Change JSC::UString data(), size(), and from(), to characters(), length(), and number() to match WTF::String.
Move string concatenation methods to a new header to simplify down UString.h. Remove is8Bit().

JavaScriptCore:

  • API/JSClassRef.cpp:

(OpaqueJSClass::~OpaqueJSClass):
(OpaqueJSClass::className):

  • API/OpaqueJSString.cpp:

(OpaqueJSString::create):

(JSC::constantName):
(JSC::idName):
(JSC::CodeBlock::registerName):
(JSC::regexpName):

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::get):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ResolveNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::processClauseList):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createRegex):

  • parser/ParserArena.h:

(JSC::IdentifierArena::makeNumericIdentifier):

  • parser/SourceProvider.h:

(JSC::UStringSourceProvider::data):
(JSC::UStringSourceProvider::length):

  • profiler/Profiler.cpp:
  • runtime/Arguments.cpp:

(JSC::Arguments::getOwnPropertySlot):
(JSC::Arguments::getOwnPropertyNames):
(JSC::Arguments::put):
(JSC::Arguments::deleteProperty):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncToString):

  • runtime/DatePrototype.cpp:

(JSC::formatLocaleDate):

  • runtime/ExceptionHelpers.cpp:
  • runtime/FunctionConstructor.cpp:
  • runtime/FunctionPrototype.cpp:

(JSC::insertSemicolonIfNeeded):

  • runtime/Identifier.h:

(JSC::Identifier::characters):
(JSC::Identifier::length):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::decode):
(JSC::parseInt):
(JSC::parseFloat):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):

  • runtime/JSNumberCell.cpp:

(JSC::JSNumberCell::toString):

  • runtime/JSONObject.cpp:

(JSC::gap):
(JSC::Stringifier::appendQuotedString):
(JSC::Stringifier::appendStringifiedValue):
(JSC::Stringifier::indent):
(JSC::Stringifier::unindent):
(JSC::Walker::walk):

  • runtime/JSString.cpp:

(JSC::JSString::replaceCharacter):
(JSC::JSString::getIndexSlowCase):

  • runtime/JSString.h:

(JSC::RopeBuilder::JSString):
(JSC::RopeBuilder::appendValueInConstructAndIncrementLength):
(JSC::RopeBuilder::fiberCount):
(JSC::jsSingleCharacterSubstring):
(JSC::jsNontrivialString):
(JSC::JSString::getIndex):
(JSC::jsString):
(JSC::jsStringWithFinalizer):
(JSC::jsSubstring):
(JSC::jsOwnedString):

  • runtime/JSStringBuilder.h:

(JSC::JSStringBuilder::append):

  • runtime/LiteralParser.h:

(JSC::LiteralParser::Lexer::Lexer):

  • runtime/NumberPrototype.cpp:

(JSC::numberProtoFuncToString):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToPrecision):

  • runtime/NumericStrings.h:

(JSC::NumericStrings::add):
(JSC::NumericStrings::lookupSmallString):

  • runtime/Operations.h:

(JSC::jsString):

  • runtime/RegExp.cpp:

(JSC::RegExp::match):

  • runtime/RegExpCache.cpp:

(JSC::RegExpCache::lookupOrCreate):
(JSC::RegExpCache::create):

  • runtime/RegExpConstructor.cpp:

(JSC::RegExpConstructor::getRightContext):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::match):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncToString):

  • runtime/StringBuilder.h:

(JSC::StringBuilder::append):

  • runtime/StringConcatenate.h: Copied from JavaScriptCore/runtime/UString.h.

(JSC::):
(JSC::sumWithOverflow):
(JSC::tryMakeString):
(JSC::makeString):

  • runtime/StringObject.cpp:

(JSC::StringObject::getOwnPropertyNames):

  • runtime/StringPrototype.cpp:

(JSC::substituteBackreferencesSlow):
(JSC::localeCompare):
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::stringProtoFuncReplace):
(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncCharCodeAt):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):
(JSC::stringProtoFuncSlice):
(JSC::stringProtoFuncSplit):
(JSC::stringProtoFuncSubstr):
(JSC::stringProtoFuncSubstring):
(JSC::stringProtoFuncToLowerCase):
(JSC::stringProtoFuncToUpperCase):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncLink):
(JSC::trimString):

  • runtime/UString.cpp:

(JSC::UString::number):
(JSC::UString::ascii):
(JSC::UString::operator[]):
(JSC::UString::toDouble):
(JSC::UString::find):
(JSC::UString::rfind):
(JSC::UString::substr):
(JSC::operator==):
(JSC::operator<):
(JSC::operator>):
(JSC::UString::UTF8String):

  • runtime/UString.h:

(JSC::UString::UString):
(JSC::UString::adopt):
(JSC::UString::length):
(JSC::UString::characters):
(JSC::UString::isNull):
(JSC::UString::isEmpty):
(JSC::UString::impl):
(JSC::UString::cost):
(JSC::operator==):
(JSC::operator!=):
(JSC::codePointCompare):
(JSC::UString::toArrayIndex):
(JSC::IdentifierRepHash::hash):
(WTF::):

  • yarr/RegexJIT.cpp:

(JSC::Yarr::jitCompileRegex):

  • yarr/RegexParser.h:

(JSC::Yarr::Parser::Parser):

JavaScriptGlue:

  • JSUtils.cpp:

(UStringToCFString):
(KJSValueToCFTypeInternal):

  • JavaScriptGlue.xcodeproj/project.pbxproj:

WebCore:

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSCSSStyleDeclarationCustom.cpp:

(WebCore::hasCSSPropertyNamePrefix):
(WebCore::cssPropertyName):

  • bindings/js/JSLocationCustom.cpp:

(WebCore::JSLocation::setPort):

  • bindings/js/ScriptDebugServer.cpp:

(WebCore::ScriptDebugServer::dispatchDidParseSource):

  • bindings/js/ScriptString.h:

(WebCore::ScriptString::size):

  • bindings/js/ScriptValue.cpp:

(WebCore::jsToInspectorValue):

  • bindings/objc/WebScriptObject.mm:

(+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):

  • bridge/jni/jni_jsobject.mm:

(JavaJSObject::convertValueToJObject):

  • bridge/jni/jsc/JNIUtilityPrivate.cpp:

(JSC::Bindings::convertArrayInstanceToJavaArray):
(JSC::Bindings::convertValueToJValue):

  • bridge/objc/objc_runtime.mm:

(JSC::Bindings::callObjCFallbackObject):

WebKit/mac:

  • WebView/WebScriptDebugger.mm:

(toNSString):

  • Property svn:eol-style set to native
File size: 9.4 KB
Line 
1/*
2 * Copyright (C) 1999-2002 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2004, 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#include "config.h"
24#include "JSString.h"
25
26#include "JSGlobalObject.h"
27#include "JSObject.h"
28#include "Operations.h"
29#include "StringObject.h"
30#include "StringPrototype.h"
31
32namespace JSC {
33
34// Overview: this methods converts a JSString from holding a string in rope form
35// down to a simple UString representation. It does so by building up the string
36// backwards, since we want to avoid recursion, we expect that the tree structure
37// representing the rope is likely imbalanced with more nodes down the left side
38// (since appending to the string is likely more common) - and as such resolving
39// in this fashion should minimize work queue size. (If we built the queue forwards
40// we would likely have to place all of the constituent StringImpls into the
41// Vector before performing any concatenation, but by working backwards we likely
42// only fill the queue with the number of substrings at any given level in a
43// rope-of-ropes.)
44void JSString::resolveRope(ExecState* exec) const
45{
46 ASSERT(isRope());
47
48 // Allocate the buffer to hold the final string, position initially points to the end.
49 UChar* buffer;
50 if (PassRefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer))
51 m_value = newImpl;
52 else {
53 for (unsigned i = 0; i < m_fiberCount; ++i) {
54 RopeImpl::deref(m_other.m_fibers[i]);
55 m_other.m_fibers[i] = 0;
56 }
57 m_fiberCount = 0;
58 ASSERT(!isRope());
59 ASSERT(m_value == UString());
60 if (exec)
61 throwOutOfMemoryError(exec);
62 return;
63 }
64 UChar* position = buffer + m_length;
65
66 // Start with the current RopeImpl.
67 Vector<RopeImpl::Fiber, 32> workQueue;
68 RopeImpl::Fiber currentFiber;
69 for (unsigned i = 0; i < (m_fiberCount - 1); ++i)
70 workQueue.append(m_other.m_fibers[i]);
71 currentFiber = m_other.m_fibers[m_fiberCount - 1];
72 while (true) {
73 if (RopeImpl::isRope(currentFiber)) {
74 RopeImpl* rope = static_cast<RopeImpl*>(currentFiber);
75 // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
76 // (we will be working backwards over the rope).
77 unsigned fiberCountMinusOne = rope->fiberCount() - 1;
78 for (unsigned i = 0; i < fiberCountMinusOne; ++i)
79 workQueue.append(rope->fibers()[i]);
80 currentFiber = rope->fibers()[fiberCountMinusOne];
81 } else {
82 StringImpl* string = static_cast<StringImpl*>(currentFiber);
83 unsigned length = string->length();
84 position -= length;
85 StringImpl::copyChars(position, string->characters(), length);
86
87 // Was this the last item in the work queue?
88 if (workQueue.isEmpty()) {
89 // Create a string from the UChar buffer, clear the rope RefPtr.
90 ASSERT(buffer == position);
91 for (unsigned i = 0; i < m_fiberCount; ++i) {
92 RopeImpl::deref(m_other.m_fibers[i]);
93 m_other.m_fibers[i] = 0;
94 }
95 m_fiberCount = 0;
96
97 ASSERT(!isRope());
98 return;
99 }
100
101 // No! - set the next item up to process.
102 currentFiber = workQueue.last();
103 workQueue.removeLast();
104 }
105 }
106}
107
108JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement)
109{
110 if (!isRope()) {
111 unsigned matchPosition = m_value.find(character);
112 if (matchPosition == UString::NotFound)
113 return JSValue(this);
114 return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1));
115 }
116
117 RopeIterator end;
118
119 // Count total fibers and find matching string.
120 size_t fiberCount = 0;
121 StringImpl* matchString = 0;
122 int matchPosition = -1;
123 for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) {
124 ++fiberCount;
125 if (matchString)
126 continue;
127
128 StringImpl* string = *it;
129 matchPosition = string->find(character);
130 if (matchPosition == -1)
131 continue;
132 matchString = string;
133 }
134
135 if (!matchString)
136 return this;
137
138 RopeBuilder builder(replacement.length() ? fiberCount + 2 : fiberCount + 1);
139 if (UNLIKELY(builder.isOutOfMemory()))
140 return throwOutOfMemoryError(exec);
141
142 for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) {
143 StringImpl* string = *it;
144 if (string != matchString) {
145 builder.append(UString(string));
146 continue;
147 }
148
149 builder.append(UString(string).substr(0, matchPosition));
150 if (replacement.length())
151 builder.append(replacement);
152 builder.append(UString(string).substr(matchPosition + 1));
153 matchString = 0;
154 }
155
156 JSGlobalData* globalData = &exec->globalData();
157 return JSValue(new (globalData) JSString(globalData, builder.release()));
158}
159
160JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i)
161{
162 ASSERT(isRope());
163 resolveRope(exec);
164 // Return a safe no-value result, this should never be used, since the excetion will be thrown.
165 if (exec->exception())
166 return jsString(exec, "");
167 ASSERT(!isRope());
168 ASSERT(i < m_value.length());
169 return jsSingleCharacterSubstring(exec, m_value, i);
170}
171
172JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
173{
174 return const_cast<JSString*>(this);
175}
176
177bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
178{
179 result = this;
180 number = value(exec).toDouble();
181 return false;
182}
183
184bool JSString::toBoolean(ExecState*) const
185{
186 return m_length;
187}
188
189double JSString::toNumber(ExecState* exec) const
190{
191 return value(exec).toDouble();
192}
193
194UString JSString::toString(ExecState* exec) const
195{
196 return value(exec);
197}
198
199inline StringObject* StringObject::create(ExecState* exec, JSString* string)
200{
201 return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
202}
203
204JSObject* JSString::toObject(ExecState* exec) const
205{
206 return StringObject::create(exec, const_cast<JSString*>(this));
207}
208
209JSObject* JSString::toThisObject(ExecState* exec) const
210{
211 return StringObject::create(exec, const_cast<JSString*>(this));
212}
213
214bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
215{
216 // The semantics here are really getPropertySlot, not getOwnPropertySlot.
217 // This function should only be called by JSValue::get.
218 if (getStringPropertySlot(exec, propertyName, slot))
219 return true;
220 if (propertyName == exec->propertyNames().underscoreProto) {
221 slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
222 return true;
223 }
224 slot.setBase(this);
225 JSObject* object;
226 for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
227 object = asObject(prototype);
228 if (object->getOwnPropertySlot(exec, propertyName, slot))
229 return true;
230 }
231 slot.setUndefined();
232 return true;
233}
234
235bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
236{
237 if (propertyName == exec->propertyNames().length) {
238 descriptor.setDescriptor(jsNumber(exec, m_length), DontEnum | DontDelete | ReadOnly);
239 return true;
240 }
241
242 bool isStrictUInt32;
243 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
244 if (isStrictUInt32 && i < m_length) {
245 descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
246 return true;
247 }
248
249 return false;
250}
251
252bool JSString::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
253{
254 if (getStringPropertyDescriptor(exec, propertyName, descriptor))
255 return true;
256 if (propertyName != exec->propertyNames().underscoreProto)
257 return false;
258 descriptor.setDescriptor(exec->lexicalGlobalObject()->stringPrototype(), DontEnum);
259 return true;
260}
261
262bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
263{
264 // The semantics here are really getPropertySlot, not getOwnPropertySlot.
265 // This function should only be called by JSValue::get.
266 if (getStringPropertySlot(exec, propertyName, slot))
267 return true;
268 return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
269}
270
271} // namespace JSC
Note: See TracBrowser for help on using the repository browser.