if (str->subtype == String::StringType_ArrayIndex)
return str;
- str->stringIdentifier = currentIndex;
+ str->identifier = currentIndex;
if (currentIndex <= USHRT_MAX) {
- str->subtype = String::StringType_Identifier;
identifiers.insert(s, str);
++currentIndex;
}
}
void toIdentifier(String *s) {
- if (s->subtype >= String::StringType_Identifier)
+ if (s->identifier != UINT_MAX)
return;
if (s->subtype == String::StringType_Unknown)
s->createHashValue();
- if (s->subtype >= String::StringType_Identifier)
+ if (s->subtype == String::StringType_ArrayIndex)
return;
QHash<QString, String*>::const_iterator it = identifiers.find(s->toQString());
if (it != identifiers.constEnd()) {
- s->subtype = String::StringType_Identifier;
- s->stringIdentifier = (*it)->stringIdentifier;
+ s->identifier = (*it)->identifier;
return;
}
- s->stringIdentifier = currentIndex;
+ s->identifier = currentIndex;
if (currentIndex <= USHRT_MAX) {
- s->subtype = String::StringType_Identifier;
identifiers.insert(s->toQString(), s);
++currentIndex;
}
uint InternalClass::getOrAddMember(Object *object, String *string)
{
engine->identifierCache->toIdentifier(string);
- uint id = string->stringIdentifier;
+ uint id = string->identifier;
QHash<uint, uint>::const_iterator it = propertyTable.constFind(id);
if (it != propertyTable.constEnd())
uint InternalClass::find(String *string)
{
engine->identifierCache->toIdentifier(string);
- uint id = string->stringIdentifier;
+ uint id = string->identifier;
QHash<uint, uint>::const_iterator it = propertyTable.constFind(id);
if (it != propertyTable.constEnd())
: prototype(0)
, internalClass(engine->emptyClass)
, memberDataAlloc(0), memberData(0)
- , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), sparseArray(0)
+ , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayData(0), sparseArray(0)
{
type = Type_Object;
}
PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, String *name)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __getOwnProperty__(ctx, idx);
uint member = internalClass->find(name);
PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *ctx, String *name)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __getPropertyDescriptor__(ctx, idx);
Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __get__(ctx, idx, hasProperty);
name->makeIdentifier(ctx);
void Object::__put__(ExecutionContext *ctx, String *name, Value value)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __put__(ctx, idx, value);
name->makeIdentifier(ctx);
bool Object::__hasProperty__(const ExecutionContext *ctx, String *name) const
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __hasProperty__(ctx, idx);
name->makeIdentifier(ctx);
bool Object::__delete__(ExecutionContext *ctx, String *name)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __delete__(ctx, idx);
name->makeIdentifier(ctx);
if (memberIdx != UINT_MAX) {
PropertyDescriptor &pd = memberData[memberIdx];
if (pd.isConfigurable()) {
- internalClass->removeMember(this, name->stringIdentifier);
+ internalClass->removeMember(this, name->identifier);
memmove(memberData + memberIdx, memberData + memberIdx + 1, (internalClass->size - memberIdx)*sizeof(PropertyDescriptor));
return true;
}
bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const PropertyDescriptor *desc)
{
uint idx = name->asArrayIndex();
- if (idx != String::InvalidArrayIndex)
+ if (idx != UINT_MAX)
return __defineOwnProperty__(ctx, idx, desc);
name->makeIdentifier(ctx);
*ok = false;
uint i = ch->unicode() - '0';
if (i > 9)
- return String::InvalidArrayIndex;
+ return UINT_MAX;
++ch;
// reject "01", "001", ...
if (i == 0 && ch != end)
- return String::InvalidArrayIndex;
+ return UINT_MAX;
while (ch < end) {
uint x = ch->unicode() - '0';
if (x > 9)
- return String::InvalidArrayIndex;
+ return UINT_MAX;
uint n = i*10 + x;
if (n < i)
// overflow
- return String::InvalidArrayIndex;
+ return UINT_MAX;
i = n;
++ch;
}
if (subtype == StringType_Unknown)
createHashValue();
- if (subtype == StringType_ArrayIndex)
+ if (subtype >= StringType_UInt)
return stringHash;
+ // ### this conversion shouldn't be required
double d = __qmljs_string_to_number(this);
uint l = (uint)d;
if (d == l)
bool ok;
stringHash = toArrayIndex(ch, end, &ok);
if (ok) {
- subtype = StringType_ArrayIndex;
+ subtype = (stringHash == UINT_MAX) ? StringType_UInt : StringType_ArrayIndex;
return;
}
enum StringType {
StringType_Unknown,
StringType_Regular,
- StringType_Identifier,
+ StringType_UInt,
StringType_ArrayIndex
};
String(const QString &text)
- : _text(text), stringHash(InvalidHashValue)
+ : _text(text), stringHash(UINT_MAX), identifier(UINT_MAX)
{ type = Type_String; subtype = StringType_Unknown; }
inline bool isEqualTo(const String *other) const {
return true;
if (hashValue() != other->hashValue())
return false;
- if (subtype == other->subtype) {
- if (subtype == StringType_ArrayIndex)
- return true;
- if (subtype == StringType_Identifier)
- return stringIdentifier == other->stringIdentifier;
- }
+ if (identifier != UINT_MAX && identifier == other->identifier)
+ return true;
+ if (subtype >= StringType_UInt && subtype == other->subtype)
+ return true;
+
return toQString() == other->toQString();
}
return stringHash;
}
- enum {
- InvalidArrayIndex = 0xffffffff,
- InvalidHashValue = 0xffffffff
- };
uint asArrayIndex() const {
if (subtype == StringType_Unknown)
createHashValue();
uint toUInt(bool *ok) const;
void makeIdentifier(const ExecutionContext *ctx) {
- if (subtype == StringType_Identifier)
+ if (identifier != UINT_MAX)
return;
makeIdentifierImpl(ctx);
}
void makeIdentifierImpl(const ExecutionContext *ctx);
-private:
- friend struct Identifiers;
void createHashValue() const;
QString _text;
mutable uint stringHash;
+ mutable uint identifier;
};
} // namespace VM