Use StringRef for most methods in Object

Change-Id: I8e2dad0e9e34c5a549952bc0765cd57f6aa8aadf
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2013-09-18 14:30:53 +02:00 committed by The Qt Project
parent 3c325823a7
commit 1aa618970a
16 changed files with 103 additions and 70 deletions

View File

@ -974,12 +974,16 @@ bool QJSValue::deleteProperty(const QString &name)
*/
bool QJSValue::hasProperty(const QString &name) const
{
Object *o = d->value.asObject();
ExecutionEngine *engine = d->engine;
if (!engine)
return false;
Scope scope(engine);
ScopedObject o(scope, d->value);
if (!o)
return false;
ExecutionEngine *engine = d->engine;
String *s = engine->newIdentifier(name);
ScopedString s(scope, engine->newIdentifier(name));
return o->__hasProperty__(s);
}
@ -991,12 +995,16 @@ bool QJSValue::hasProperty(const QString &name) const
*/
bool QJSValue::hasOwnProperty(const QString &name) const
{
Object *o = d->value.asObject();
ExecutionEngine *engine = d->engine;
if (!engine)
return false;
Scope scope(engine);
ScopedObject o(scope, d->value);
if (!o)
return false;
ExecutionEngine *engine = d->engine;
String *s = engine->newIdentifier(name);
ScopedString s(scope, engine->newIdentifier(name));
return o->__getOwnProperty__(s);
}

View File

@ -174,6 +174,8 @@ CallContext *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml)
void ExecutionContext::createMutableBinding(String *name, bool deletable)
{
Scope scope(this);
ScopedString n(scope, name);
// find the right context to create the binding on
Object *activation = engine->globalObject;
@ -189,12 +191,12 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
ctx = ctx->outer;
}
if (activation->__hasProperty__(name))
if (activation->__hasProperty__(n))
return;
Property desc = Property::fromValue(Value::undefinedValue());
PropertyAttributes attrs(Attr_Data);
attrs.setConfigurable(deletable);
activation->__defineOwnProperty__(this, name, desc, attrs);
activation->__defineOwnProperty__(this, n, desc, attrs);
}
String * const *ExecutionContext::formals() const
@ -286,12 +288,14 @@ void CallContext::initQmlContext(ExecutionContext *parentContext, Object *qml, F
bool ExecutionContext::deleteProperty(String *name)
{
Scope scope(this);
ScopedString n(scope, name);
bool hasWith = false;
for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
if (ctx->type == Type_WithContext) {
hasWith = true;
WithContext *w = static_cast<WithContext *>(ctx);
if (w->withObject->__hasProperty__(name))
if (w->withObject->__hasProperty__(n))
return w->withObject->deleteProperty(name);
} else if (ctx->type == Type_CatchContext) {
CatchContext *c = static_cast<CatchContext *>(ctx);
@ -308,11 +312,11 @@ bool ExecutionContext::deleteProperty(String *name)
if (f->formalParameterList[i]->isEqualTo(name))
return false;
}
if (c->activation && c->activation->__hasProperty__(name))
if (c->activation && c->activation->__hasProperty__(n))
return c->activation->deleteProperty(name);
} else if (ctx->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
if (g->global->__hasProperty__(name))
if (g->global->__hasProperty__(n))
return g->global->deleteProperty(name);
}
}
@ -366,10 +370,11 @@ void ExecutionContext::mark()
void ExecutionContext::setProperty(String *name, const Value& value)
{
Scope scope(this);
ScopedString n(scope, name);
for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
if (ctx->type == Type_WithContext) {
Object *w = static_cast<WithContext *>(ctx)->withObject;
if (w->__hasProperty__(name)) {
if (w->__hasProperty__(n)) {
w->put(name, value);
return;
}
@ -395,7 +400,7 @@ void ExecutionContext::setProperty(String *name, const Value& value)
activation = static_cast<GlobalContext *>(ctx)->global;
}
if (activation && (ctx->type == Type_QmlContext || activation->__hasProperty__(name))) {
if (activation && (ctx->type == Type_QmlContext || activation->__hasProperty__(n))) {
activation->put(name, value);
return;
}

View File

@ -273,11 +273,11 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
cout << prefix << "properties:" << endl;
ForEachIteratorObject it(ctx, o);
QV4::ScopedValue name(scope);
ScopedValue name(scope);
for (name = it.nextPropertyName(); !name->isNull(); name = it.nextPropertyName()) {
cout << prefix << "\t\"" << qPrintable(name->stringValue()->toQString()) << "\"" << endl;
PropertyAttributes attrs;
Property *d = o->__getOwnProperty__(name->stringValue(), &attrs);
Property *d = o->__getOwnProperty__(ScopedString(scope, name), &attrs);
Value pval = Value::fromReturnedValue(o->getValue(d, attrs));
cout << prefix << "\tvalue:" << endl;
realDumpValue(pval, ctx, prefix + "\t");

View File

@ -135,7 +135,7 @@ String *IdentifierTable::insertString(const QString &s)
}
Identifier *IdentifierTable::identifierImpl(String *str)
Identifier *IdentifierTable::identifierImpl(const String *str)
{
if (str->identifier)
return str->identifier;
@ -153,7 +153,7 @@ Identifier *IdentifierTable::identifierImpl(String *str)
idx %= alloc;
}
addEntry(str);
addEntry(const_cast<QV4::String *>(str));
return str->identifier;
}

View File

@ -68,7 +68,7 @@ public:
String *insertString(const QString &s);
Identifier *identifier(String *str) {
Identifier *identifier(const String *str) {
if (str->identifier)
return str->identifier;
return identifierImpl(str);
@ -77,7 +77,7 @@ public:
Identifier *identifier(const QString &s);
Identifier *identifier(const char *s, int len);
Identifier *identifierImpl(String *str);
Identifier *identifierImpl(const String *str);
void mark() {
for (int i = 0; i < alloc; ++i)

View File

@ -255,7 +255,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
transitions.insert(t, object->internalClass);
}
uint InternalClass::find(String *string)
uint InternalClass::find(const String *string)
{
engine->identifierTable->identifier(string);
const Identifier *id = string->identifier;

View File

@ -140,7 +140,7 @@ struct InternalClass {
InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
InternalClass *changeMember(String *string, PropertyAttributes data, uint *index = 0);
void removeMember(Object *object, Identifier *id);
uint find(String *s);
uint find(const String *s);
InternalClass *sealed();
InternalClass *frozen();

View File

@ -318,7 +318,7 @@ Property *Object::insertMember(const StringRef s, PropertyAttributes attributes)
}
// Section 8.12.1
Property *Object::__getOwnProperty__(String *name, PropertyAttributes *attrs)
Property *Object::__getOwnProperty__(const StringRef name, PropertyAttributes *attrs)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@ -363,7 +363,7 @@ Property *Object::__getOwnProperty__(uint index, PropertyAttributes *attrs)
}
// Section 8.12.2
Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *attrs) const
Property *Object::__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@ -372,7 +372,7 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
const Object *o = this;
while (o) {
uint idx = o->internalClass->find(name);
uint idx = o->internalClass->find(name.getPointer());
if (idx < UINT_MAX) {
if (attrs)
*attrs = o->internalClass->propertyData[idx];
@ -414,14 +414,14 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
return 0;
}
bool Object::__hasProperty__(String *name) const
bool Object::__hasProperty__(const StringRef name) const
{
if (__getPropertyDescriptor__(name))
return true;
const Object *o = this;
while (o) {
if (!o->query(name).isEmpty())
if (!o->query(name.getPointer()).isEmpty())
return true;
o = o->prototype();
}
@ -456,7 +456,9 @@ ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty)
void Object::put(Managed *m, String *name, const Value &value)
{
static_cast<Object *>(m)->internalPut(name, value);
Scope scope(m->engine());
ScopedString s(scope, name);
static_cast<Object *>(m)->internalPut(s, value);
}
void Object::putIndexed(Managed *m, uint index, const Value &value)
@ -704,7 +706,7 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
// Section 8.12.5
void Object::internalPut(String *name, const Value &value)
void Object::internalPut(const StringRef name, const Value &value)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@ -712,7 +714,7 @@ void Object::internalPut(String *name, const Value &value)
name->makeIdentifier();
uint member = internalClass->find(name);
uint member = internalClass->find(name.getPointer());
Property *pd = 0;
PropertyAttributes attrs;
if (member < UINT_MAX) {
@ -772,9 +774,7 @@ void Object::internalPut(String *name, const Value &value)
}
{
Scope scope(engine());
ScopedString s(scope, name);
Property *p = insertMember(s, Attr_Data);
Property *p = insertMember(name, Attr_Data);
p->value = value;
return;
}
@ -910,7 +910,7 @@ bool Object::internalDeleteIndexedProperty(uint index)
}
// Section 8.12.9
bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Property &p, PropertyAttributes attrs)
bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@ -948,7 +948,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
// Clause 1
{
uint member = internalClass->find(name);
uint member = internalClass->find(name.getPointer());
current = (member < UINT_MAX) ? memberData + member : 0;
cattrs = internalClass->propertyData.data() + member;
}
@ -958,9 +958,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
if (!extensible)
goto reject;
// clause 4
Scope scope(engine());
ScopedString s(scope, name);
Property *pd = insertMember(s, attrs);
Property *pd = insertMember(name, attrs);
*pd = p;
pd->fullyPopulated(&attrs);
return true;
@ -1004,21 +1002,21 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
return true;
}
return __defineOwnProperty__(ctx, current, 0 /*member*/, p, attrs);
return __defineOwnProperty__(ctx, current, StringRef::null(), p, attrs);
reject:
if (ctx->strictMode)
ctx->throwTypeError();
return false;
}
bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, String *member, const Property &p, PropertyAttributes attrs)
bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, const StringRef member, const Property &p, PropertyAttributes attrs)
{
// clause 5
if (attrs.isEmpty())
return true;
PropertyAttributes cattrs = Attr_Data;
if (member)
if (!member.isNull())
cattrs = internalClass->propertyData[current - memberData];
else if (arrayAttributes)
cattrs = arrayAttributes[current - arrayData];
@ -1074,8 +1072,8 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, Str
accept:
current->merge(cattrs, p, attrs);
if (member) {
internalClass = internalClass->changeMember(member, cattrs);
if (!member.isNull()) {
internalClass = internalClass->changeMember(member.getPointer(), cattrs);
} else {
if (cattrs != Attr_Data)
ensureArrayAttributes();
@ -1094,7 +1092,9 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, Str
bool Object::__defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs)
{
return __defineOwnProperty__(ctx, ctx->engine->newString(name), p, attrs);
Scope scope(ctx);
ScopedString s(scope, ctx->engine->newString(name));
return __defineOwnProperty__(ctx, s, p, attrs);
}

View File

@ -131,17 +131,17 @@ struct Q_QML_EXPORT Object: Managed {
Object *prototype() const { return internalClass->prototype; }
bool setPrototype(Object *proto);
Property *__getOwnProperty__(String *name, PropertyAttributes *attrs = 0);
Property *__getOwnProperty__(const StringRef name, PropertyAttributes *attrs = 0);
Property *__getOwnProperty__(uint index, PropertyAttributes *attrs = 0);
Property *__getPropertyDescriptor__(String *name, PropertyAttributes *attrs = 0) const;
Property *__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs = 0) const;
Property *__getPropertyDescriptor__(uint index, PropertyAttributes *attrs = 0) const;
bool __hasProperty__(String *name) const;
bool __hasProperty__(const StringRef name) const;
bool __hasProperty__(uint index) const;
bool __defineOwnProperty__(ExecutionContext *ctx, Property *current, String *member, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, Property *current, const StringRef member, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs);
@ -325,7 +325,7 @@ protected:
private:
ReturnedValue internalGet(String *name, bool *hasProperty);
ReturnedValue internalGetIndexed(uint index, bool *hasProperty);
void internalPut(String *name, const Value &value);
void internalPut(const StringRef name, const Value &value);
void internalPutIndexed(uint index, const Value &value);
bool internalDeleteProperty(String *name);
bool internalDeleteIndexedProperty(uint index);

View File

@ -70,7 +70,9 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
if (current != object) {
Property *pp;
if (*name) {
pp = object->__getPropertyDescriptor__(*name);
Scope scope(object->engine());
ScopedString n(scope, *name);
pp = object->__getPropertyDescriptor__(n);
} else {
assert (*index != UINT_MAX);
pp = object->__getPropertyDescriptor__(*index);

View File

@ -158,7 +158,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext
ScopedValue v(scope, ctx->argument(1));
Scoped<String> name(scope, v->toString(ctx));
PropertyAttributes attrs;
Property *desc = O->__getOwnProperty__(name.getPointer(), &attrs);
Property *desc = O->__getOwnProperty__(name, &attrs);
return fromPropertyDescriptor(ctx, desc, attrs);
}
@ -204,7 +204,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
PropertyAttributes attrs;
toPropertyDescriptor(ctx, attributes, &pd, &attrs);
if (!O->__defineOwnProperty__(ctx, name.getPointer(), pd, attrs))
if (!O->__defineOwnProperty__(ctx, name, pd, attrs))
ctx->throwTypeError();
return O.asReturnedValue();
@ -222,9 +222,11 @@ ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
while (1) {
uint index;
String *name;
ScopedString name(scope);
PropertyAttributes attrs;
Property *pd = it.next(&name, &index, &attrs);
String *tmp = 0;
Property *pd = it.next(&tmp, &index, &attrs);
name = tmp;
if (!pd)
break;
Property n;
@ -416,7 +418,7 @@ ReturnedValue ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
Scope scope(ctx);
Scoped<String> P(scope, ctx->argument(0), Scoped<String>::Convert);
Scoped<Object> O(scope, ctx->thisObject, Scoped<Object>::Convert);
bool r = O->__getOwnProperty__(P.getPointer()) != 0;
bool r = O->__getOwnProperty__(P) != 0;
if (!r)
r = !O->query(P.getPointer()).isEmpty();
return Encode(r);
@ -446,7 +448,7 @@ ReturnedValue ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ct
Scoped<Object> o(scope, ctx->thisObject, Scoped<Object>::Convert);
PropertyAttributes attrs;
o->__getOwnProperty__(p.getPointer(), &attrs);
o->__getOwnProperty__(p, &attrs);
return Encode(attrs.isEnumerable());
}
@ -470,7 +472,7 @@ ReturnedValue ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
}
Property pd = Property::fromAccessor(f.getPointer(), 0);
o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
return Encode::undefined();
}
@ -494,7 +496,7 @@ ReturnedValue ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
}
Property pd = Property::fromAccessor(0, f.getPointer());
o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
return Encode::undefined();
}
@ -607,23 +609,30 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
Scope scope(engine);
// Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
Scoped<Object> o(scope, engine->newObject());
ScopedString s(scope);
Property pd;
if (attrs.isData()) {
pd.value = desc->value;
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("value")), pd, Attr_Data);
s = engine->newString(QStringLiteral("value"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
pd.value = Value::fromBoolean(attrs.isWritable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("writable")), pd, Attr_Data);
s = engine->newString(QStringLiteral("writable"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
} else {
pd.value = desc->getter() ? Value::fromObject(desc->getter()) : Value::undefinedValue();
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("get")), pd, Attr_Data);
s = engine->newString(QStringLiteral("get"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
pd.value = desc->setter() ? Value::fromObject(desc->setter()) : Value::undefinedValue();
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("set")), pd, Attr_Data);
s = engine->newString(QStringLiteral("set"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
}
pd.value = Value::fromBoolean(attrs.isEnumerable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("enumerable")), pd, Attr_Data);
s = engine->newString(QStringLiteral("enumerable"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
pd.value = Value::fromBoolean(attrs.isConfigurable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), pd, Attr_Data);
s = engine->newString(QStringLiteral("configurable"));
o->__defineOwnProperty__(ctx, s, pd, Attr_Data);
return o.asReturnedValue();
}

View File

@ -304,7 +304,8 @@ QV4::ReturnedValue __qmljs_in(ExecutionContext *ctx, const ValueRef left, const
{
if (!right->isObject())
ctx->throwTypeError();
String *s = left->toString(ctx);
Scope scope(ctx);
ScopedString s(scope, left->toString(ctx));
bool r = right->objectValue()->__hasProperty__(s);
return Value::fromBoolean(r).asReturnedValue();
}

View File

@ -450,7 +450,11 @@ struct Referenced {
}
ReturnedValue asReturnedValue() const { return ptr->val; }
static Referenced null() { return Referenced(Null); }
bool isNull() const { return !ptr; }
private:
enum _Null { Null };
Referenced(_Null) { ptr = 0; }
Value *ptr;
};

View File

@ -131,6 +131,9 @@ void String::destroy(Managed *that)
ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
{
Scope scope(m->engine());
ScopedString n(scope, name);
String *that = static_cast<String *>(m);
ExecutionEngine *v4 = m->engine();
if (name == v4->id_length) {
@ -139,7 +142,7 @@ ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
return Value::fromInt32(that->_text.length()).asReturnedValue();
}
PropertyAttributes attrs;
Property *pd = v4->stringClass->prototype->__getPropertyDescriptor__(name, &attrs);
Property *pd = v4->stringClass->prototype->__getPropertyDescriptor__(n, &attrs);
if (!pd || attrs.isGeneric()) {
if (hasProperty)
*hasProperty = false;
@ -256,7 +259,7 @@ uint String::toUInt(bool *ok) const
return UINT_MAX;
}
void String::makeIdentifierImpl()
void String::makeIdentifierImpl() const
{
engine()->identifierTable->identifier(this);
}

View File

@ -101,13 +101,13 @@ struct Q_QML_EXPORT String : public Managed {
}
uint toUInt(bool *ok) const;
void makeIdentifier() {
void makeIdentifier() const {
if (identifier)
return;
makeIdentifierImpl();
}
void makeIdentifierImpl();
void makeIdentifierImpl() const;
void createHashValue() const;
static uint createHashValue(const QChar *ch, int length);

View File

@ -293,7 +293,8 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
}
PropertyAttributes attrs;
Property *pd = wrapper->__getOwnProperty__(name, &attrs);
ScopedString n(scope, name);
Property *pd = wrapper->__getOwnProperty__(n, &attrs);
if (pd) {
wrapper->putValue(pd, attrs, value);
return;