, strictMode(0)
, type(Type_Invalid)
, subtype(0)
+ , stringIdentifier(0)
+#if CPU(X86_64)
, unused(0)
+#endif
{}
virtual ~Managed();
quintptr needsActivation : 1; // used by FunctionObject
quintptr usesArgumentsObject : 1; // used by FunctionObject
quintptr strictMode : 1; // used by FunctionObject
- quintptr type : 8;
- quintptr subtype : 8;
+ quintptr type : 5;
+ mutable quintptr subtype : 3;
+ quintptr stringIdentifier : 16;
#if CPU(X86_64)
- quintptr unused : 40;
-#else
- quintptr unused : 8;
+ quintptr unused : 32;
#endif
};
};
namespace QQmlJS {
namespace VM {
-static uint toArrayIndex(const QChar *ch, const QChar *end)
+static uint toArrayIndex(const QChar *ch, const QChar *end, bool *ok)
{
+ *ok = false;
uint i = ch->unicode() - '0';
if (i > 9)
return String::InvalidArrayIndex;
i = n;
++ch;
}
+ *ok = true;
return i;
}
-uint String::asArrayIndexSlow() const
-{
- if (stringHash < LargestHashedArrayIndex)
- return stringHash;
-
- const QChar *ch = _text.constData();
- const QChar *end = ch + _text.length();
- return toArrayIndex(ch, end);
-}
-
uint String::toUInt(bool *ok) const
{
*ok = true;
- if (stringHash == InvalidHashValue)
+ if (subtype == StringType_Unknown)
createHashValue();
- if (stringHash < LargestHashedArrayIndex)
+ if (subtype == StringType_ArrayIndex)
return stringHash;
double d = __qmljs_string_to_number(this);
const QChar *ch = _text.constData();
const QChar *end = ch + _text.length();
- // array indices get their number as hash value, for large numbers we set to INT_MAX
- stringHash = toArrayIndex(ch, end);
- if (stringHash < UINT_MAX) {
- if (stringHash > INT_MAX)
- stringHash = INT_MAX;
+ // array indices get their number as hash value
+ bool ok;
+ stringHash = toArrayIndex(ch, end, &ok);
+ if (ok) {
+ subtype = StringType_ArrayIndex;
return;
}
++ch;
}
- // set highest bit to mark it as a non number
- stringHash = h | 0xf0000000;
+ stringHash = h;
+ subtype = StringType_Regular;
}
}
namespace VM {
struct String : public Managed {
+ enum StringType {
+ StringType_Unknown,
+ StringType_ArrayIndex,
+ StringType_Regular,
+ StringType_Identifier,
+ };
+
String(const QString &text)
- : _text(text), stringHash(0)
- { type = Type_String; stringHash = InvalidHashValue; }
+ : _text(text), stringHash(InvalidHashValue)
+ { type = Type_String; subtype = StringType_Unknown; }
inline bool isEqualTo(const String *other) const {
if (this == other)
return true;
- else if (other && hashValue() == other->hashValue())
+ else if (hashValue() == other->hashValue()) {
+ if (subtype == StringType_ArrayIndex && other->subtype == StringType_ArrayIndex)
+ return true;
return toQString() == other->toQString();
+ }
return false;
}
}
inline unsigned hashValue() const {
- if (stringHash == InvalidHashValue)
+ if (subtype == StringType_Unknown)
createHashValue();
return stringHash;
}
enum {
InvalidArrayIndex = 0xffffffff,
- LargestHashedArrayIndex = 0x7fffffff,
InvalidHashValue = 0xffffffff
};
uint asArrayIndex() const {
- if (stringHash == InvalidHashValue)
+ if (subtype == StringType_Unknown)
createHashValue();
- if (stringHash > LargestHashedArrayIndex)
- return InvalidArrayIndex;
- if (stringHash < LargestHashedArrayIndex)
+ if (subtype == StringType_ArrayIndex)
return stringHash;
- return asArrayIndexSlow();
+ return UINT_MAX;
}
- uint asArrayIndexSlow() const;
uint toUInt(bool *ok) const;
private: