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

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

Rubber stamped by Oliver Hunt.

Rename JSC::UStringImpl::data() to characters(), to match WebCore::StringImpl.

JavaScriptCore:

  • API/JSClassRef.cpp:

(OpaqueJSClassContextData::OpaqueJSClassContextData):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::keyForCharacterSwitch):

  • bytecompiler/NodesCodegen.cpp:

(JSC::processClauseList):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncToString):

  • runtime/Identifier.cpp:

(JSC::Identifier::equal):
(JSC::Identifier::addSlowCase):

  • runtime/JSString.cpp:

(JSC::JSString::resolveRope):

  • runtime/UString.cpp:

(JSC::UString::toStrictUInt32):
(JSC::equal):

  • runtime/UString.h:

(JSC::UString::data):

  • runtime/UStringImpl.h:

(JSC::UStringImpl::characters):
(JSC::UStringImpl::hash):
(JSC::UStringImpl::setHash):

WebCore:

  • bridge/jni/jsc/JavaStringJSC.h:

(JSC::Bindings::JavaStringImpl::uchars):

  • platform/text/AtomicString.cpp:

(WebCore::AtomicString::add):
(WebCore::AtomicString::find):

  • Property svn:eol-style set to native
File size: 7.5 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 UStringImpls 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<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_length, buffer))
51 m_value = newImpl;
52 else {
53 for (unsigned i = 0; i < m_fiberCount; ++i) {
54 m_other.m_fibers[i]->deref();
55 m_other.m_fibers[i] = 0;
56 }
57 m_fiberCount = 0;
58 ASSERT(!isRope());
59 ASSERT(m_value == UString());
60 throwOutOfMemoryError(exec);
61 return;
62 }
63 UChar* position = buffer + m_length;
64
65 // Start with the current Rope.
66 Vector<Rope::Fiber, 32> workQueue;
67 Rope::Fiber currentFiber;
68 for (unsigned i = 0; i < (m_fiberCount - 1); ++i)
69 workQueue.append(m_other.m_fibers[i]);
70 currentFiber = m_other.m_fibers[m_fiberCount - 1];
71 while (true) {
72 if (currentFiber->isRope()) {
73 Rope* rope = static_cast<URopeImpl*>(currentFiber);
74 // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
75 // (we will be working backwards over the rope).
76 unsigned fiberCountMinusOne = rope->fiberCount() - 1;
77 for (unsigned i = 0; i < fiberCountMinusOne; ++i)
78 workQueue.append(rope->fibers(i));
79 currentFiber = rope->fibers(fiberCountMinusOne);
80 } else {
81 UStringImpl* string = static_cast<UStringImpl*>(currentFiber);
82 unsigned length = string->length();
83 position -= length;
84 UStringImpl::copyChars(position, string->characters(), length);
85
86 // Was this the last item in the work queue?
87 if (workQueue.isEmpty()) {
88 // Create a string from the UChar buffer, clear the rope RefPtr.
89 ASSERT(buffer == position);
90 for (unsigned i = 0; i < m_fiberCount; ++i) {
91 m_other.m_fibers[i]->deref();
92 m_other.m_fibers[i] = 0;
93 }
94 m_fiberCount = 0;
95
96 ASSERT(!isRope());
97 return;
98 }
99
100 // No! - set the next item up to process.
101 currentFiber = workQueue.last();
102 workQueue.removeLast();
103 }
104 }
105}
106
107JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
108{
109 return const_cast<JSString*>(this);
110}
111
112bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
113{
114 result = this;
115 number = value(exec).toDouble();
116 return false;
117}
118
119bool JSString::toBoolean(ExecState*) const
120{
121 return m_length;
122}
123
124double JSString::toNumber(ExecState* exec) const
125{
126 return value(exec).toDouble();
127}
128
129UString JSString::toString(ExecState* exec) const
130{
131 return value(exec);
132}
133
134UString JSString::toThisString(ExecState* exec) const
135{
136 return value(exec);
137}
138
139JSString* JSString::toThisJSString(ExecState*)
140{
141 return this;
142}
143
144inline StringObject* StringObject::create(ExecState* exec, JSString* string)
145{
146 return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
147}
148
149JSObject* JSString::toObject(ExecState* exec) const
150{
151 return StringObject::create(exec, const_cast<JSString*>(this));
152}
153
154JSObject* JSString::toThisObject(ExecState* exec) const
155{
156 return StringObject::create(exec, const_cast<JSString*>(this));
157}
158
159bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
160{
161 // The semantics here are really getPropertySlot, not getOwnPropertySlot.
162 // This function should only be called by JSValue::get.
163 if (getStringPropertySlot(exec, propertyName, slot))
164 return true;
165 if (propertyName == exec->propertyNames().underscoreProto) {
166 slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
167 return true;
168 }
169 slot.setBase(this);
170 JSObject* object;
171 for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
172 object = asObject(prototype);
173 if (object->getOwnPropertySlot(exec, propertyName, slot))
174 return true;
175 }
176 slot.setUndefined();
177 return true;
178}
179
180bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
181{
182 if (propertyName == exec->propertyNames().length) {
183 descriptor.setDescriptor(jsNumber(exec, m_length), DontEnum | DontDelete | ReadOnly);
184 return true;
185 }
186
187 bool isStrictUInt32;
188 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
189 if (isStrictUInt32 && i < m_length) {
190 descriptor.setDescriptor(jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);
191 return true;
192 }
193
194 return false;
195}
196
197bool JSString::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
198{
199 if (getStringPropertyDescriptor(exec, propertyName, descriptor))
200 return true;
201 if (propertyName != exec->propertyNames().underscoreProto)
202 return false;
203 descriptor.setDescriptor(exec->lexicalGlobalObject()->stringPrototype(), DontEnum);
204 return true;
205}
206
207bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
208{
209 // The semantics here are really getPropertySlot, not getOwnPropertySlot.
210 // This function should only be called by JSValue::get.
211 if (getStringPropertySlot(exec, propertyName, slot))
212 return true;
213 return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
214}
215
216} // namespace JSC
Note: See TracBrowser for help on using the repository browser.