Change internal class when attributes of properties change
authorLars Knoll <lars.knoll@digia.com>
Mon, 8 Apr 2013 13:38:30 +0000 (15:38 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 12 Apr 2013 12:25:21 +0000 (14:25 +0200)
This should allow us to share property attributes for different
class instances saving quite some memory. In addition, it
can be used to speed up property access (as we then know in the
lookup whether it's a data or accessor property).

Change-Id: Ide9c6168a07b5c83a1e73d075d8fc4f6594e08fd
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
17 files changed:
src/v4/qv4engine.cpp
src/v4/qv4functionobject.cpp
src/v4/qv4global.h
src/v4/qv4internalclass.cpp
src/v4/qv4internalclass.h
src/v4/qv4jsonobject.cpp
src/v4/qv4managed.h
src/v4/qv4object.cpp
src/v4/qv4object.h
src/v4/qv4propertydescriptor.h
src/v4/qv4regexp.cpp
src/v4/qv4regexp.h
src/v4/qv4regexpobject.cpp
src/v4/qv4runtime.cpp
src/v4/qv4string.cpp
src/v4/qv4string.h
src/v4/qv4v8.cpp

index 54655d1..24770d2 100644 (file)
@@ -109,7 +109,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     id_eval = newIdentifier(QStringLiteral("eval"));
 
     emptyClass = new InternalClass(this);
-    arrayClass = emptyClass->addMember(id_length);
+    arrayClass = emptyClass->addMember(id_length, Attr_ReadOnly);
     initRootContext();
 
     objectPrototype = new (memoryManager) ObjectPrototype(this);
index 0d8bac8..4deb318 100644 (file)
@@ -341,7 +341,7 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
 
     Object *proto = scope->engine->newObject();
     proto->defineDefaultProperty(scope->engine->id_constructor, Value::fromObject(this));
-    PropertyDescriptor *pd = insertMember(scope->engine->id_prototype);
+    PropertyDescriptor *pd = insertMember(scope->engine->id_prototype, Attr_NotEnumerable|Attr_NotConfigurable);
     pd->type = PropertyDescriptor::Data;
     pd->writable = PropertyDescriptor::Enabled;
     pd->enumerable = PropertyDescriptor::Disabled;
@@ -482,8 +482,8 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
     PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower);
     pd.configurable = PropertyDescriptor::Disabled;
     pd.enumerable = PropertyDescriptor::Disabled;
-    *insertMember(scope->engine->id_arguments) = pd;
-    *insertMember(scope->engine->id_caller) = pd;
+    *insertMember(scope->engine->id_arguments, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
+    *insertMember(scope->engine->id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
 }
 
 void BoundFunction::destroy(Managed *that)
index f3964e9..43409b2 100644 (file)
@@ -59,12 +59,18 @@ QT_BEGIN_NAMESPACE
 namespace QQmlJS {
 namespace VM {
 
-enum PropertyFlags {
-    Writable = 0x1,
-    Enumerable = 0x2,
-    Configurable = 0x4
+enum {
+    Attr_Default = 0,
+    Attr_Accessor = 0x1,
+    Attr_NotWritable = 0x2,
+    Attr_NotEnumerable = 0x4,
+    Attr_NotConfigurable = 0x8,
+    Attr_ReadOnly = Attr_NotWritable|Attr_NotEnumerable|Attr_NotConfigurable,
+    Attr_Invalid = 0xff
 };
 
+typedef uchar PropertyAttributes;
+
 }
 }
 
index 25857de..0f4a945 100644 (file)
@@ -52,15 +52,16 @@ InternalClass::InternalClass(const QQmlJS::VM::InternalClass &other)
     : engine(other.engine)
     , propertyTable(other.propertyTable)
     , nameMap(other.nameMap)
+    , propertyData(other.propertyData)
     , transitions()
     , size(other.size)
 {
 }
 
-InternalClass *InternalClass::addMember(String *string, uint *index)
+InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, uint *index)
 {
     engine->identifierCache->toIdentifier(string);
-    uint id = string->identifier;
+    uint id = string->identifier | ((uint)data << 24);
 
     assert(propertyTable.constFind(id) == propertyTable.constEnd());
 
@@ -73,8 +74,9 @@ InternalClass *InternalClass::addMember(String *string, uint *index)
     } else {
         // create a new class and add it to the tree
         InternalClass *newClass = new InternalClass(*this);
-        newClass->propertyTable.insert(id, size);
+        newClass->propertyTable.insert(string->identifier, size);
         newClass->nameMap.append(string);
+        newClass->propertyData.append(data);
         ++newClass->size;
         transitions.insert(id, newClass);
         return newClass;
@@ -100,7 +102,7 @@ void InternalClass::removeMember(Object *object, uint id)
     for (int i = 0; i < nameMap.size(); ++i) {
         if (i == propIdx)
             continue;
-        object->internalClass = object->internalClass->addMember(nameMap.at(i));
+        object->internalClass = object->internalClass->addMember(nameMap.at(i), propertyData.at(i));
     }
 
     transitions.insert(toRemove, object->internalClass);
index 8ad1412..92bf19a 100644 (file)
@@ -43,6 +43,7 @@
 
 #include <QHash>
 #include <QVector>
+#include <qv4global.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -57,12 +58,15 @@ struct InternalClass {
     ExecutionEngine *engine;
     QHash<uint, uint> propertyTable; // id to valueIndex
     QVector<String *> nameMap;
+
+    QVector<PropertyAttributes> propertyData;
+
     QHash<int, InternalClass *> transitions; // id to next class, positive means add, negative delete
     uint size;
 
     InternalClass(ExecutionEngine *engine) : engine(engine), size(0) {}
 
-    InternalClass *addMember(String *string, uint *index = 0);
+    InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
     void removeMember(Object *object, uint id);
     uint find(String *s);
 
index 015557f..64f5a6c 100644 (file)
@@ -281,7 +281,7 @@ bool Parser::parseMember(Object *o)
     if (!parseValue(&val))
         return false;
 
-    PropertyDescriptor *p = o->insertMember(context->engine->newIdentifier(key));
+    PropertyDescriptor *p = o->insertMember(context->engine->newIdentifier(key), Attr_Default);
     p->type = PropertyDescriptor::Data;
     p->writable = PropertyDescriptor::Enabled;
     p->enumerable = PropertyDescriptor::Enabled;
index 264c92c..844c887 100644 (file)
@@ -84,8 +84,8 @@ struct ManagedVTable
     Value (*getIndexed)(Managed *, ExecutionContext *ctx, uint index, bool *hasProperty);
     void (*put)(Managed *, ExecutionContext *ctx, String *name, const Value &value);
     void (*putIndexed)(Managed *, ExecutionContext *ctx, uint index, const Value &value);
-    PropertyFlags (*query)(Managed *, ExecutionContext *ctx, String *name);
-    PropertyFlags (*queryIndexed)(Managed *, ExecutionContext *ctx, uint index);
+    PropertyAttributes (*query)(Managed *, ExecutionContext *ctx, String *name);
+    PropertyAttributes (*queryIndexed)(Managed *, ExecutionContext *ctx, uint index);
     bool (*deleteProperty)(Managed *m, ExecutionContext *ctx, String *name);
     bool (*deleteIndexedProperty)(Managed *m, ExecutionContext *ctx, uint index);
     const char *className;
index 36af4b6..a48a74a 100644 (file)
@@ -192,7 +192,7 @@ void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, const Value &index, c
 
 void Object::defineDefaultProperty(String *name, Value value)
 {
-    PropertyDescriptor *pd = insertMember(name);
+    PropertyDescriptor *pd = insertMember(name, Attr_Default);
     pd->type = PropertyDescriptor::Data;
     pd->writable = PropertyDescriptor::Enabled;
     pd->enumerable = PropertyDescriptor::Disabled;
@@ -221,7 +221,7 @@ void Object::defineReadonlyProperty(ExecutionEngine *engine, const QString &name
 
 void Object::defineReadonlyProperty(String *name, Value value)
 {
-    PropertyDescriptor *pd = insertMember(name);
+    PropertyDescriptor *pd = insertMember(name, Attr_ReadOnly);
     pd->type = PropertyDescriptor::Data;
     pd->writable = PropertyDescriptor::Disabled;
     pd->enumerable = PropertyDescriptor::Disabled;
@@ -250,10 +250,10 @@ void Object::markObjects(Managed *that)
     o->markArrayObjects();
 }
 
-PropertyDescriptor *Object::insertMember(String *s)
+PropertyDescriptor *Object::insertMember(String *s, PropertyAttributes attributes)
 {
     uint idx;
-    internalClass = internalClass->addMember(s, &idx);
+    internalClass = internalClass->addMember(s, attributes, &idx);
 
     if (idx >= memberDataAlloc) {
         memberDataAlloc = qMax((uint)8, 2*memberDataAlloc);
@@ -346,22 +346,22 @@ void Object::putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Val
     static_cast<Object *>(m)->internalPutIndexed(ctx, index, value);
 }
 
-PropertyFlags Object::query(Managed *m, ExecutionContext *ctx, String *name)
+PropertyAttributes Object::query(Managed *m, ExecutionContext *ctx, String *name)
 {
     Object *that = static_cast<Object *>(m);
     PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, name);
     if (!pd || pd->type == PropertyDescriptor::Generic)
-        return PropertyFlags(0);
-    return pd->propertyFlags();
+        return Attr_Invalid;
+    return pd->toPropertyAttributes();
 }
 
-PropertyFlags Object::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
+PropertyAttributes Object::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
 {
     Object *that = static_cast<Object *>(m);
     PropertyDescriptor *pd = that->__getPropertyDescriptor__(ctx, index);
     if (!pd || pd->type == PropertyDescriptor::Generic)
-        return PropertyFlags(0);
-    return pd->propertyFlags();
+        return Attr_Invalid;
+    return pd->toPropertyAttributes();
 }
 
 bool Object::deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
@@ -509,7 +509,7 @@ void Object::internalPut(ExecutionContext *ctx, String *name, const Value &value
     }
 
     {
-        PropertyDescriptor *p = insertMember(name);
+        PropertyDescriptor *p = insertMember(name, Attr_Default);
         p->type = PropertyDescriptor::Data;
         p->value = value;
         p->configurable = PropertyDescriptor::Enabled;
@@ -685,7 +685,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
         if (!extensible)
             goto reject;
         // clause 4
-        PropertyDescriptor *pd = insertMember(name);
+        PropertyDescriptor *pd = insertMember(name, desc->toPropertyAttributes());
         *pd = *desc;
         pd->fullyPopulated();
         return true;
index caee8b6..004b537 100644 (file)
@@ -183,7 +183,7 @@ struct Q_V4_EXPORT Object: Managed {
     void defineReadonlyProperty(ExecutionEngine *engine, const QString &name, Value value);
     void defineReadonlyProperty(String *name, Value value);
 
-    PropertyDescriptor *insertMember(String *s);
+    PropertyDescriptor *insertMember(String *s, PropertyAttributes attributes);
 
     // Array handling
 
@@ -338,8 +338,8 @@ protected:
     static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty);
     static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value);
     static void putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value);
-    static PropertyFlags query(Managed *m, ExecutionContext *ctx, String *name);
-    static PropertyFlags queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
+    static PropertyAttributes query(Managed *m, ExecutionContext *ctx, String *name);
+    static PropertyAttributes queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
     static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name);
     static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
 
index 9a07c39..7bde67b 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "qv4global.h"
 #include "qv4value.h"
+#include "qv4internalclass.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -51,7 +52,18 @@ namespace VM {
 
 struct FunctionObject;
 
-struct PropertyDescriptor {
+struct Property {
+    union {
+        Value value;
+        struct {
+            FunctionObject *get;
+            FunctionObject *set;
+        };
+    };
+};
+
+struct PropertyDescriptor : public Property
+{
     enum Type {
         Generic,
         Data,
@@ -62,29 +74,11 @@ struct PropertyDescriptor {
         Disabled,
         Enabled
     };
-    union {
-        Value value;
-        struct {
-            FunctionObject *get;
-            FunctionObject *set;
-        };
-    };
     uint type : 8;
     uint writable : 8;
     uint enumerable : 8;
     uint configurable : 8;
 
-    PropertyFlags propertyFlags() {
-        int f = 0;
-        if (writable == Enabled)
-            f |= Writable;
-        if (configurable == Enabled)
-            f |= Configurable;
-        if (enumerable == Enabled)
-            f |= Enumerable;
-        return PropertyFlags(f);
-    }
-
     static inline PropertyDescriptor fromValue(Value v) {
         PropertyDescriptor pd;
         pd.value = v;
@@ -105,6 +99,19 @@ struct PropertyDescriptor {
         return pd;
     }
 
+    PropertyAttributes toPropertyAttributes() const {
+        PropertyAttributes attrs = 0;
+        if (type == Accessor)
+            attrs |= Attr_Accessor;
+        else if (writable != Enabled)
+            attrs |= Attr_NotWritable;
+        if (enumerable != Enabled)
+            attrs |= Attr_NotEnumerable;
+        if (configurable != Enabled)
+            attrs |= Attr_NotConfigurable;
+        return attrs;
+    }
+
     // Section 8.10
     inline void fullyPopulated() {
         if (type == Generic) {
index 303d2c1..c0f7cee 100644 (file)
@@ -141,14 +141,14 @@ void RegExp::putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Val
 {
 }
 
-PropertyFlags RegExp::query(Managed *m, ExecutionContext *ctx, String *name)
+PropertyAttributes RegExp::query(Managed *m, ExecutionContext *ctx, String *name)
 {
-    return PropertyFlags(0);
+    return Attr_Invalid;
 }
 
-PropertyFlags RegExp::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
+PropertyAttributes RegExp::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
 {
-    return PropertyFlags(0);
+    return Attr_Invalid;
 }
 
 bool RegExp::deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
index 15b81f4..b0c9584 100644 (file)
@@ -115,8 +115,8 @@ protected:
     static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty);
     static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value);
     static void putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value);
-    static PropertyFlags query(Managed *m, ExecutionContext *ctx, String *name);
-    static PropertyFlags queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
+    static PropertyAttributes query(Managed *m, ExecutionContext *ctx, String *name);
+    static PropertyAttributes queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
     static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name);
     static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
 
index 94f7f79..32db30b 100644 (file)
@@ -73,7 +73,8 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, RegExp* value, bool global)
     vtbl = &static_vtbl;
     type = Type_RegExpObject;
 
-    PropertyDescriptor *lastIndexProperty = insertMember(engine->newIdentifier(QStringLiteral("lastIndex")));
+    PropertyDescriptor *lastIndexProperty = insertMember(engine->newIdentifier(QStringLiteral("lastIndex")),
+                                                         Attr_NotEnumerable|Attr_NotConfigurable);
     lastIndexProperty->type = PropertyDescriptor::Data;
     lastIndexProperty->writable = PropertyDescriptor::Enabled;
     lastIndexProperty->enumerable = PropertyDescriptor::Disabled;
index b539f9d..f85fc51 100644 (file)
@@ -1210,7 +1210,7 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const Value &object,
     assert(o);
 
     uint idx = name->asArrayIndex();
-    PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name);
+    PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Default);
     pd->value = val ? *val : Value::undefinedValue();
     pd->type = PropertyDescriptor::Data;
     pd->writable = PropertyDescriptor::Enabled;
@@ -1255,7 +1255,7 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const Value &ob
     assert(o);
 
     uint idx = name->asArrayIndex();
-    PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name);
+    PropertyDescriptor *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Accessor);
     pd->get = getter ? getter->asFunctionObject() : 0;
     pd->set = setter ? setter->asFunctionObject() : 0;
     pd->type = PropertyDescriptor::Accessor;
index 46e56cc..c16be93 100644 (file)
@@ -150,15 +150,15 @@ void String::putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Val
     o->putIndexed(ctx, index, value);
 }
 
-PropertyFlags String::query(Managed *m, ExecutionContext *ctx, String *name)
+PropertyAttributes String::query(Managed *m, ExecutionContext *ctx, String *name)
 {
-    return PropertyFlags(0);
+    return Attr_Invalid;
 }
 
-PropertyFlags String::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
+PropertyAttributes String::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
 {
     String *that = static_cast<String *>(m);
-    return (index < that->_text.length()) ? PropertyFlags(Enumerable) : PropertyFlags(0);
+    return (index < that->_text.length()) ? Attr_NotConfigurable|Attr_NotWritable : Attr_Invalid;
 }
 
 bool String::deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
index 8c483b2..cc93532 100644 (file)
@@ -117,8 +117,8 @@ protected:
     static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty);
     static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value);
     static void putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value);
-    static PropertyFlags query(Managed *m, ExecutionContext *ctx, String *name);
-    static PropertyFlags queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
+    static PropertyAttributes query(Managed *m, ExecutionContext *ctx, String *name);
+    static PropertyAttributes queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
     static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name);
     static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
 
index 2c7b83a..56acd11 100644 (file)
@@ -920,7 +920,12 @@ bool Object::SetAccessor(Handle<String> name, AccessorGetter getter, AccessorSet
 
     QQmlJS::VM::Object *o = ConstValuePtr(this)->asObject();
     assert(o);
-    VM::PropertyDescriptor *pd = o->insertMember(name->asVMString());
+    PropertyAttributes attrs = Attr_Accessor;
+    if (attribute & DontDelete)
+        attrs |= Attr_NotConfigurable;
+    if (attribute & DontEnum)
+        attrs |= Attr_NotEnumerable;
+    VM::PropertyDescriptor *pd = o->insertMember(name->asVMString(), attrs);
     *pd = VM::PropertyDescriptor::fromAccessor(wrappedGetter, wrappedSetter);
     pd->writable = VM::PropertyDescriptor::Undefined;
     pd->configurable = attribute & DontDelete ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled;
@@ -1424,7 +1429,12 @@ public:
             m_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
 
         foreach (const ObjectTemplate::Accessor &acc, m_template->m_accessors) {
-            VM::PropertyDescriptor *pd = this->insertMember(acc.name->asVMString());
+            PropertyAttributes attrs = Attr_Accessor;
+            if (acc.attribute & DontDelete)
+                attrs |= Attr_NotConfigurable;
+            if (acc.attribute & DontEnum)
+                attrs |= Attr_NotEnumerable;
+            VM::PropertyDescriptor *pd = this->insertMember(acc.name->asVMString(), attrs);
             *pd = VM::PropertyDescriptor::fromAccessor(acc.getter->vmValue().asFunctionObject(),
                                                        acc.setter->vmValue().asFunctionObject());
             pd->writable = VM::PropertyDescriptor::Undefined;
@@ -1438,7 +1448,14 @@ public:
     void initProperties(Template *tmpl)
     {
         foreach (const Template::Property &p, tmpl->m_properties) {
-            VM::PropertyDescriptor *pd = this->insertMember(p.name->asVMString());
+            PropertyAttributes attrs = Attr_Default;
+            if (p.attributes & DontDelete)
+                attrs |= Attr_NotConfigurable;
+            if (p.attributes & DontEnum)
+                attrs |= Attr_NotEnumerable;
+            if (p.attributes & ReadOnly)
+                attrs |= Attr_NotWritable;
+            VM::PropertyDescriptor *pd = this->insertMember(p.name->asVMString(), attrs);
             *pd = VM::PropertyDescriptor::fromValue(p.value->vmValue());
             pd->writable = p.attributes & ReadOnly ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled;
             pd->configurable = p.attributes & DontDelete ? VM::PropertyDescriptor::Disabled : VM::PropertyDescriptor::Enabled;
@@ -1539,20 +1556,20 @@ protected:
         BaseClass::putIndexed(m, ctx, index, value);
     }
 
-    static PropertyFlags propertyAttributesToFlags(const Handle<Value> &attr)
+    static PropertyAttributes propertyAttributesToFlags(const Handle<Value> &attr)
     {
-        int flags = 0;
+        PropertyAttributes flags = 0;
         int intAttr = attr->ToInt32()->Value();
-        if (!(intAttr & ReadOnly))
-            flags |= VM::Writable;
-        if (!(intAttr & DontDelete))
-            flags |= VM::Configurable;
-        if (!(intAttr & DontEnum))
-            flags |= VM::Enumerable;
-        return PropertyFlags(flags);
+        if (intAttr & ReadOnly)
+            flags |= VM::Attr_NotWritable;
+        if (intAttr & DontDelete)
+            flags |= VM::Attr_NotConfigurable;
+        if (intAttr & DontEnum)
+            flags |= VM::Attr_NotEnumerable;
+        return flags;
     }
 
-    static PropertyFlags query(VM::Managed *m, ExecutionContext *ctx, VM::String *name)
+    static PropertyAttributes query(VM::Managed *m, ExecutionContext *ctx, VM::String *name)
     {
         V4V8Object *that = static_cast<V4V8Object*>(m);
         if (that->m_template->m_namedPropertyQuery) {
@@ -1560,7 +1577,7 @@ protected:
             if (!result.IsEmpty())
                 return propertyAttributesToFlags(result);
         }
-        PropertyFlags flags = BaseClass::query(m, ctx, name);
+        PropertyAttributes flags = BaseClass::query(m, ctx, name);
         if (flags == 0 && that->m_template->m_fallbackPropertySetter) {
             Handle<Value> result = that->m_template->m_fallbackPropertyQuery(String::New(name), that->fallbackAccessorInfo());
             if (!result.IsEmpty())
@@ -1570,7 +1587,7 @@ protected:
         return flags;
     }
 
-    static PropertyFlags queryIndexed(VM::Managed *m, ExecutionContext *ctx, uint index)
+    static PropertyAttributes queryIndexed(VM::Managed *m, ExecutionContext *ctx, uint index)
     {
         V4V8Object *that = static_cast<V4V8Object*>(m);
         if (that->m_template->m_indexedPropertyQuery) {