void String::markObjects(Managed *that)
{
String *s = static_cast<String *>(that);
- if (s->depth) {
+ if (s->largestSubLength) {
s->left->mark();
s->right->mark();
}
String::String(ExecutionEngine *engine, const QString &text)
: Managed(engine ? engine->emptyClass : 0), _text(const_cast<QString &>(text).data_ptr())
, identifier(0), stringHash(UINT_MAX)
- , depth(0)
+ , largestSubLength(0)
{
_text->ref.ref();
+ len = _text->size;
vtbl = &static_vtbl;
type = Type_String;
subtype = StringType_Unknown;
String::String(ExecutionEngine *engine, String *l, String *r)
: Managed(engine ? engine->emptyClass : 0)
, left(l), right(r)
- , stringHash(UINT_MAX), depth(qMax(l->depth, r->depth) + 1)
+ , stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength))
+ , len(l->len + r->len)
{
vtbl = &static_vtbl;
type = Type_String;
subtype = StringType_Unknown;
+ if (!l->largestSubLength && l->len > largestSubLength)
+ largestSubLength = l->len;
+ if (!r->largestSubLength && r->len > largestSubLength)
+ largestSubLength = r->len;
+
// make sure we don't get excessive depth in our strings
- if (depth >= 16)
+ if (len > 256 && len >= 2*largestSubLength)
simplifyString();
}
void String::makeIdentifierImpl() const
{
- if (depth)
+ if (largestSubLength)
simplifyString();
- Q_ASSERT(!depth);
+ Q_ASSERT(!largestSubLength);
engine()->identifierTable->identifier(this);
}
void String::simplifyString() const
{
- Q_ASSERT(depth);
+ Q_ASSERT(largestSubLength);
int l = length();
QString result(l, Qt::Uninitialized);
_text = result.data_ptr();
_text->ref.ref();
identifier = 0;
- depth = 0;
+ largestSubLength = 0;
}
QChar *String::recursiveAppend(QChar *ch) const
{
- if (depth) {
+ if (largestSubLength) {
ch = left->recursiveAppend(ch);
ch = right->recursiveAppend(ch);
} else {
void String::createHashValue() const
{
- if (depth)
+ if (largestSubLength)
simplifyString();
- Q_ASSERT(!depth);
+ Q_ASSERT(!largestSubLength);
const QChar *ch = reinterpret_cast<const QChar *>(_text->data());
const QChar *end = ch + _text->size;
String()
: Managed(0), _text(QStringData::sharedNull()), identifier(0)
- , stringHash(UINT_MAX), depth(0)
+ , stringHash(UINT_MAX), largestSubLength(0), len(0)
{ vtbl = &static_vtbl; type = Type_String; subtype = StringType_Unknown; }
String(ExecutionEngine *engine, const QString &text);
String(ExecutionEngine *engine, String *l, String *n);
~String() {
- if (!depth && !_text->ref.deref())
+ if (!largestSubLength && !_text->ref.deref())
QStringData::deallocate(_text);
_data = 0;
}
return true;
if (hashValue() != other->hashValue())
return false;
- Q_ASSERT(!depth);
+ Q_ASSERT(!largestSubLength);
if (identifier && identifier == other->identifier)
return true;
if (subtype >= StringType_UInt && subtype == other->subtype)
return toQString() < other->toQString();
}
- inline bool isEmpty() const { return _text && !_text->size; }
inline QString toQString() const {
- if (depth)
+ if (largestSubLength)
simplifyString();
QStringDataPtr ptr = { _text };
_text->ref.ref();
inline unsigned hashValue() const {
if (subtype == StringType_Unknown)
createHashValue();
- Q_ASSERT(!depth);
+ Q_ASSERT(!largestSubLength);
return stringHash;
}
uint asArrayIndex() const {
if (subtype == StringType_Unknown)
createHashValue();
- Q_ASSERT(!depth);
+ Q_ASSERT(!largestSubLength);
if (subtype == StringType_ArrayIndex)
return stringHash;
return UINT_MAX;
bool startsWithUpper() const {
const String *l = this;
- while (l->depth)
+ while (l->largestSubLength)
l = l->left;
return l->_text->size && QChar::isUpper(l->_text->data()[0]);
}
int length() const {
- if (!depth)
- return _text->size;
- return left->length() + right->length();
+ Q_ASSERT((largestSubLength && (len == left->len + right->len)) || len == (uint)_text->size);
+ return len;
}
union {
mutable String *right;
};
mutable uint stringHash;
- mutable uint depth;
+ mutable uint largestSubLength;
+ uint len;
protected:
if (!ctx->callData->args[1].isString())
V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
QV4::String *fs = ctx->callData->args[1].toString(ctx);
- if (!fs->isEmpty())
+ if (fs->length())
format = fs->toQString().at(0).unicode();
}
int prec = 2;
}
QV4::String *ns = ctx->callData->args[numberIdx].toString(ctx);
- if (ns->isEmpty())
+ if (!ns->length())
return QV4::Encode(Q_QNAN);
bool ok = false;