diff options
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4errorobject.cpp | 34 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4global_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 26 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4memberdata_p.h | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject_p.h | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 38 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4variantobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4variantobject_p.h | 4 |
16 files changed, 132 insertions, 106 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 4a83c4e8dc..318db4f904 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -61,20 +61,20 @@ void Heap::ArgumentsObject::init(QV4::CallContext *context) if (context->d()->strictMode) { Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee())); Q_ASSERT(CallerPropertyIndex == args->internalClass()->find(context->d()->engine->id_caller())); - *args->propertyData(CalleePropertyIndex + QV4::Object::GetterOffset) = v4->thrower(); - *args->propertyData(CalleePropertyIndex + QV4::Object::SetterOffset) = v4->thrower(); - *args->propertyData(CallerPropertyIndex + QV4::Object::GetterOffset) = v4->thrower(); - *args->propertyData(CallerPropertyIndex + QV4::Object::SetterOffset) = v4->thrower(); + args->setProperty(CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower()); + args->setProperty(CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower()); + args->setProperty(CallerPropertyIndex + QV4::Object::GetterOffset, *v4->thrower()); + args->setProperty(CallerPropertyIndex + QV4::Object::SetterOffset, *v4->thrower()); args->arrayReserve(context->argc()); args->arrayPut(0, context->args(), context->argc()); args->d()->fullyCreated = true; } else { Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee())); - *args->propertyData(CalleePropertyIndex) = context->d()->function->asReturnedValue(); + args->setProperty(CalleePropertyIndex, context->d()->function); } Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(context->d()->engine->id_length())); - *args->propertyData(LengthPropertyIndex) = Primitive::fromInt32(context->d()->callData->argc); + args->setProperty(LengthPropertyIndex, Primitive::fromInt32(context->d()->callData->argc)); } void ArgumentsObject::fullyCreate() @@ -92,7 +92,7 @@ void ArgumentsObject::fullyCreate() if (numAccessors) { d()->mappedArguments.set(scope.engine, md->allocate(engine(), numAccessors)); for (uint i = 0; i < numAccessors; ++i) { - d()->mappedArguments->values[i] = context()->callData->args[i]; + d()->mappedArguments->values.set(scope.engine, i, context()->callData->args[i]); arraySet(i, context()->engine->argumentsAccessors + i, Attr_Accessor); } } diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index daa4f2d9a6..58742a0b84 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -78,10 +78,10 @@ void Heap::ErrorObject::init() if (internalClass == scope.engine->errorProtoClass) return; - *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction(); - *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined(); - *propertyData(QV4::ErrorObject::Index_FileName) = Encode::undefined(); - *propertyData(QV4::ErrorObject::Index_LineNumber) = Encode::undefined(); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d()); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue()); + setProperty(scope.engine, QV4::ErrorObject::Index_FileName, Primitive::undefinedValue()); + setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::undefinedValue()); } void Heap::ErrorObject::init(const Value &message, ErrorType t) @@ -92,17 +92,17 @@ void Heap::ErrorObject::init(const Value &message, ErrorType t) Scope scope(internalClass->engine); Scoped<QV4::ErrorObject> e(scope, this); - *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction(); - *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined(); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d()); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue()); e->d()->stackTrace = new StackTrace(scope.engine->stackTrace()); if (!e->d()->stackTrace->isEmpty()) { - *propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source); - *propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line); + setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source)); + setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::fromInt32(e->d()->stackTrace->at(0).line)); } if (!message.isUndefined()) - *propertyData(QV4::ErrorObject::Index_Message) = message; + setProperty(scope.engine, QV4::ErrorObject::Index_Message, message); } void Heap::ErrorObject::init(const Value &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t) @@ -113,8 +113,8 @@ void Heap::ErrorObject::init(const Value &message, const QString &fileName, int Scope scope(internalClass->engine); Scoped<QV4::ErrorObject> e(scope, this); - *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction(); - *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined(); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d()); + setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue()); e->d()->stackTrace = new StackTrace(scope.engine->stackTrace()); StackFrame frame; @@ -124,12 +124,12 @@ void Heap::ErrorObject::init(const Value &message, const QString &fileName, int e->d()->stackTrace->prepend(frame); if (!e->d()->stackTrace->isEmpty()) { - *propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source); - *propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line); + setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source)); + setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::fromInt32(e->d()->stackTrace->at(0).line)); } if (!message.isUndefined()) - *propertyData(QV4::ErrorObject::Index_Message) = message; + setProperty(scope.engine, QV4::ErrorObject::Index_Message, message); } const char *ErrorObject::className(Heap::ErrorObject::ErrorType t) @@ -319,9 +319,9 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He ScopedObject o(scope); ctor->defineReadonlyProperty(engine->id_prototype(), (o = obj)); ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1)); - *obj->propertyData(Index_Constructor) = ctor; - *obj->propertyData(Index_Message) = engine->id_empty(); - *obj->propertyData(Index_Name) = engine->newString(QString::fromLatin1(ErrorObject::className(t))); + obj->setProperty(Index_Constructor, ctor->d()); + obj->setProperty(Index_Message, engine->id_empty()->d()); + obj->setProperty(Index_Name, engine->newString(QString::fromLatin1(ErrorObject::className(t)))); if (t == Heap::ErrorObject::Error) obj->defineDefaultProperty(engine->id_toString(), method_toString, 0); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 55b0175a47..5c8f03dc72 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -106,7 +106,7 @@ void Heap::FunctionObject::init() function = nullptr; this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d()); Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()) == Index_Prototype); - *propertyData(Index_Prototype) = Encode::undefined(); + setProperty(internalClass->engine, Index_Prototype, Primitive::undefinedValue()); } @@ -126,10 +126,10 @@ void FunctionObject::init(String *n, bool createProto) if (createProto) { ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype())); Q_ASSERT(s.engine->protoClass->find(s.engine->id_constructor()) == Heap::FunctionObject::Index_ProtoConstructor); - *proto->propertyData(Heap::FunctionObject::Index_ProtoConstructor) = this->asReturnedValue(); - *propertyData(Heap::FunctionObject::Index_Prototype) = proto.asReturnedValue(); + proto->setProperty(Heap::FunctionObject::Index_ProtoConstructor, d()); + setProperty(Heap::FunctionObject::Index_Prototype, proto); } else { - *propertyData(Heap::FunctionObject::Index_Prototype) = Encode::undefined(); + setProperty(Heap::FunctionObject::Index_Prototype, Primitive::undefinedValue()); } if (n) @@ -346,7 +346,8 @@ void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallD if (callData->argc > 1) { boundArgs = MemberData::allocate(scope.engine, callData->argc - 1); boundArgs->d()->values.size = callData->argc - 1; - memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value)); + for (uint i = 0; i < static_cast<uint>(callData->argc - 1); ++i) + boundArgs->set(scope.engine, i, callData->args[i + 1]); } ExecutionContext *global = scope.engine->rootContext(); @@ -426,7 +427,7 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function ScopedString name(s, function->name()); f->init(name, true); Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()) == Index_Length); - *propertyData(Index_Length) = Primitive::fromInt32(f->formalParameterCount()); + setProperty(s.engine, Index_Length, Primitive::fromInt32(f->formalParameterCount())); if (scope->d()->strictMode) { ScopedProperty pd(s); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index cd8fb91f7a..68418ba770 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -201,6 +201,7 @@ struct Property; struct Value; template<size_t> struct HeapValue; template<size_t> struct ValueArray; +template<size_t> struct HeapValueArray; struct Lookup; struct ArrayData; struct VTable; diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index bac71b4537..9b18a5566e 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -126,26 +126,6 @@ InternalClass::InternalClass(const QV4::InternalClass &other) Q_ASSERT(extensible); } -static void insertHoleIntoPropertyData(Object *object, int idx) -{ - int icSize = object->internalClass()->size; - int from = idx; - int to = from + 1; - if (from < icSize) - memmove(object->propertyData(to), object->propertyData(from), - (icSize - from - 1) * sizeof(Value)); -} - -static void removeFromPropertyData(Object *object, int idx, bool accessor = false) -{ - int delta = (accessor ? 2 : 1); - int oldSize = object->internalClass()->size + delta; - int to = idx; - int from = to + delta; - if (from < oldSize) - memmove(object->propertyData(to), object->d()->propertyData(from), (oldSize - to)*sizeof(Value)); -} - void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index) { uint idx; @@ -157,10 +137,10 @@ void InternalClass::changeMember(Object *object, String *string, PropertyAttribu object->setInternalClass(newClass); if (newClass->size > oldClass->size) { Q_ASSERT(newClass->size == oldClass->size + 1); - insertHoleIntoPropertyData(object, idx + 1); + object->d()->memberData->values.insertData(newClass->engine, idx + 1, Primitive::emptyValue()); } else if (newClass->size < oldClass->size) { Q_ASSERT(newClass->size == oldClass->size - 1); - removeFromPropertyData(object, idx + 1); + object->d()->memberData->values.removeData(newClass->engine, idx + 1); } } @@ -318,7 +298,7 @@ void InternalClass::removeMember(Object *object, Identifier *id) Q_ASSERT(object->internalClass()->size == oldClass->size - (accessor ? 2 : 1)); // remove the entry in the property data - removeFromPropertyData(object, propIdx, accessor); + object->d()->memberData->values.removeData(oldClass->engine, propIdx, accessor ? 2 : 1); t.lookup = object->internalClass(); Q_ASSERT(t.lookup); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index bd677483b5..f322d5a001 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -59,7 +59,7 @@ ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttribu if (index != UINT_MAX) { level = i; *attrs = obj->internalClass->propertyData.at(index); - Value *v = obj->propertyData(index); + const Value *v = obj->propertyData(index); return !attrs->isAccessor() ? v->asReturnedValue() : Object::getValue(thisObject, *v, *attrs); } @@ -72,7 +72,7 @@ ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttribu index = obj->internalClass->find(name); if (index != UINT_MAX) { *attrs = obj->internalClass->propertyData.at(index); - Value *v = obj->propertyData(index); + const Value *v = obj->propertyData(index); return !attrs->isAccessor() ? v->asReturnedValue() : Object::getValue(thisObject, *v, *attrs); } @@ -94,7 +94,7 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs if (index != UINT_MAX) { level = i; *attrs = obj->internalClass->propertyData.at(index); - Value *v = obj->propertyData(index); + const Value *v = obj->propertyData(index); return !attrs->isAccessor() ? v->asReturnedValue() : thisObject->getValue(*v, *attrs); } @@ -107,7 +107,7 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs index = obj->internalClass->find(name); if (index != UINT_MAX) { *attrs = obj->internalClass->propertyData.at(index); - Value *v = obj->propertyData(index); + const Value *v = obj->propertyData(index); return !attrs->isAccessor() ? v->asReturnedValue() : thisObject->getValue(*v, *attrs); } @@ -772,7 +772,7 @@ void Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Va { Object *o = object.as<Object>(); if (o && o->internalClass() == l->classList[0]) { - *o->propertyData(l->index) = value; + o->setProperty(l->index, value); return; } @@ -785,7 +785,7 @@ void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, co if (o && o->internalClass() == l->classList[0]) { if (!o->prototype()) { o->setInternalClass(l->classList[3]); - *o->propertyData(l->index) = value; + o->setProperty(l->index, value); return; } } @@ -801,7 +801,7 @@ void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, co Heap::Object *p = o->prototype(); if (p && p->internalClass == l->classList[1]) { o->setInternalClass(l->classList[3]); - *o->propertyData(l->index) = value; + o->setProperty(l->index, value); return; } } @@ -819,7 +819,7 @@ void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, co p = p->prototype; if (p && p->internalClass == l->classList[2]) { o->setInternalClass(l->classList[3]); - *o->propertyData(l->index) = value; + o->setProperty(l->index, value); return; } } @@ -834,11 +834,11 @@ void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, c Object *o = object.as<Object>(); if (o) { if (o->internalClass() == l->classList[0]) { - *o->propertyData(l->index) = value; + o->setProperty(l->index, value); return; } if (o->internalClass() == l->classList[1]) { - *o->propertyData(l->index2) = value; + o->setProperty(l->index2, value); return; } } diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 302553464e..dff7c09a4c 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -60,7 +60,7 @@ namespace QV4 { namespace Heap { #define MemberDataMembers(class, Member) \ - Member(class, ValueArray, ValueArray, values) + Member(class, ValueArray, HeapValueArray, values) DECLARE_HEAP_OBJECT(MemberData, Base) { DECLARE_MARK_TABLE(MemberData); @@ -85,9 +85,11 @@ struct MemberData : Managed bool isNull() const { return !memberData; } }; - Value &operator[] (uint idx) { return d()->values[idx]; } - const Value *data() const { return d()->values.v; } - Value *data() { return d()->values.v; } + const Value &operator[] (uint idx) const { return d()->values[idx]; } + const Value *data() const { return d()->values.data(); } + void set(ExecutionEngine *e, uint index, Value v) { d()->values.set(e, index, v); } + void set(ExecutionEngine *e, uint index, Heap::Base *b) { d()->values.set(e, index, b); } + inline uint size() const { return d()->values.size; } static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = 0); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 3fe1ac71b4..ce8fdc6d6d 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -76,9 +76,9 @@ void Object::getProperty(uint index, Property *p, PropertyAttributes *attrs) con void Object::setProperty(uint index, const Property *p) { - *propertyData(index) = p->value; + setProperty(index, p->value); if (internalClass()->propertyData.at(index).isAccessor()) - *propertyData(index + SetterOffset) = p->set; + setProperty(index + SetterOffset, p->set); } bool Object::setPrototype(Object *proto) @@ -117,7 +117,7 @@ bool Object::putValue(uint memberIndex, const Value &value) PropertyAttributes attrs = ic->propertyData[memberIndex]; if (attrs.isAccessor()) { - FunctionObject *set = propertyData(memberIndex + SetterOffset)->as<FunctionObject>(); + const FunctionObject *set = propertyData(memberIndex + SetterOffset)->as<FunctionObject>(); if (set) { Scope scope(ic->engine); ScopedFunctionObject setter(scope, set); @@ -133,7 +133,7 @@ bool Object::putValue(uint memberIndex, const Value &value) if (!attrs.isWritable()) goto reject; - *propertyData(memberIndex) = value; + setProperty(memberIndex, value); return true; reject: @@ -264,10 +264,10 @@ void Object::insertMember(String *s, const Property *p, PropertyAttributes attri InternalClass::addMember(this, s, attributes, &idx); if (attributes.isAccessor()) { - *propertyData(idx + GetterOffset) = p->value; - *propertyData(idx + SetterOffset) = p->set; + setProperty(idx + GetterOffset, p->value); + setProperty(idx + SetterOffset, p->set); } else { - *propertyData(idx) = p->value; + setProperty(idx, p->value); } } @@ -526,7 +526,7 @@ void Object::setLookup(Managed *m, Lookup *l, const Value &value) l->classList[0] = o->internalClass(); l->index = idx; l->setter = Lookup::setter0; - *o->propertyData(idx) = value; + o->setProperty(idx, value); return; } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 3db52bf3d3..c0169ed035 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -78,8 +78,9 @@ DECLARE_HEAP_OBJECT(Object, Base) { void init() { Base::init(); } void destroy() { Base::destroy(); } - const Value *propertyData(uint index) const { return memberData->values.v + index; } - Value *propertyData(uint index) { return memberData->values.v + index; } + const Value *propertyData(uint index) const { return memberData->values.data() + index; } + void setProperty(ExecutionEngine *e, uint index, Value v) const { memberData->values.set(e, index, v); } + void setProperty(ExecutionEngine *e, uint index, Heap::Base *b) const { memberData->values.set(e, index, b); } }; Q_STATIC_ASSERT(Object::markTable == ((2 << 4) | (2 << 6) | (2 << 8))); @@ -195,13 +196,14 @@ struct Q_QML_EXPORT Object: Managed { void setInternalClass(InternalClass *ic); const Value *propertyData(uint index) const { return d()->propertyData(index); } - Value *propertyData(uint index) { return d()->propertyData(index); } Heap::ArrayData *arrayData() const { return d()->arrayData; } void setArrayData(ArrayData *a) { d()->arrayData.set(engine(), a->d()); } void getProperty(uint index, Property *p, PropertyAttributes *attrs) const; void setProperty(uint index, const Property *p); + void setProperty(uint index, Value v) const { d()->setProperty(engine(), index, v); } + void setProperty(uint index, Heap::Base *b) const { d()->setProperty(engine(), index, b); } const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable()); } Heap::Object *prototype() const { return d()->prototype; } @@ -469,7 +471,7 @@ struct ArrayObject : Object { private: void commonInit() - { *propertyData(LengthPropertyIndex) = Primitive::fromInt32(0); } + { setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(0)); } }; } @@ -509,7 +511,7 @@ struct ArrayObject: Object { inline void Object::setArrayLengthUnchecked(uint l) { if (isArrayObject()) - *propertyData(Heap::ArrayObject::LengthPropertyIndex) = Primitive::fromUInt32(l); + setProperty(Heap::ArrayObject::LengthPropertyIndex, Primitive::fromUInt32(l)); } inline void Object::push_back(const Value &v) diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 7b15494ea9..f8ad11fa98 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -145,7 +145,7 @@ void Heap::RegExpObject::init(const QRegExp &re) void RegExpObject::initProperties() { - *propertyData(Index_LastIndex) = Primitive::fromInt32(0); + setProperty(Index_LastIndex, Primitive::fromInt32(0)); Q_ASSERT(value()); @@ -157,16 +157,10 @@ void RegExpObject::initProperties() p.replace('/', QLatin1String("\\/")); } - *propertyData(Index_Source) = engine()->newString(p); - *propertyData(Index_Global) = Primitive::fromBoolean(global()); - *propertyData(Index_IgnoreCase) = Primitive::fromBoolean(value()->ignoreCase); - *propertyData(Index_Multiline) = Primitive::fromBoolean(value()->multiLine); -} - -Value *RegExpObject::lastIndexProperty() -{ - Q_ASSERT(0 == internalClass()->find(engine()->id_lastIndex())); - return propertyData(0); + setProperty(Index_Source, engine()->newString(p)); + setProperty(Index_Global, Primitive::fromBoolean(global())); + setProperty(Index_IgnoreCase, Primitive::fromBoolean(value()->ignoreCase)); + setProperty(Index_Multiline, Primitive::fromBoolean(value()->multiLine)); } // Converts a JS RegExp to a QRegExp. @@ -344,9 +338,9 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat RETURN_UNDEFINED(); QString s = str->toQString(); - int offset = r->global() ? r->lastIndexProperty()->toInt32() : 0; + int offset = r->global() ? r->lastIndex() : 0; if (offset < 0 || offset > s.length()) { - *r->lastIndexProperty() = Primitive::fromInt32(0); + r->setLastIndex(0); RETURN_RESULT(Encode::null()); } @@ -357,7 +351,7 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat regExpCtor->d()->clearLastMatch(); if (result == -1) { - *r->lastIndexProperty() = Primitive::fromInt32(0); + r->setLastIndex(0); RETURN_RESULT(Encode::null()); } @@ -373,8 +367,8 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat array->arrayPut(i, v); } array->setArrayLengthUnchecked(len); - *array->propertyData(Index_ArrayIndex) = Primitive::fromInt32(result); - *array->propertyData(Index_ArrayInput) = str; + array->setProperty(Index_ArrayIndex, Primitive::fromInt32(result)); + array->setProperty(Index_ArrayInput, str); RegExpCtor::Data *dd = regExpCtor->d(); dd->lastMatch.set(scope.engine, array); @@ -383,7 +377,7 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat dd->lastMatchEnd = matchOffsets[1]; if (r->global()) - *r->lastIndexProperty() = Primitive::fromInt32(matchOffsets[1]); + r->setLastIndex(matchOffsets[1]); scope.result = array; } diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index c2eeb32b88..0fcfe93135 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -128,7 +128,15 @@ struct RegExpObject: Object { void initProperties(); - Value *lastIndexProperty(); + int lastIndex() const { + Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex())); + return propertyData(Index_LastIndex)->toInt32(); + } + void setLastIndex(int index) { + Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex())); + return setProperty(Index_LastIndex, Primitive::fromInt32(index)); + } + QRegExp toQRegExp() const; QString toString() const; QString source() const; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 4459af0e66..7708b81d8a 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1311,7 +1311,7 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4:: } for (uint i = 0; i < klass->size; ++i) - *o->propertyData(i) = *args++; + o->setProperty(i, *args++); if (arrayValueCount > 0) { ScopedValue entry(scope); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 628c220bae..81f5c3566c 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -78,14 +78,14 @@ void Heap::StringObject::init() Object::init(); Q_ASSERT(vtable() == QV4::StringObject::staticVTable()); string.set(internalClass->engine, internalClass->engine->id_empty()->d()); - *propertyData(LengthPropertyIndex) = Primitive::fromInt32(0); + setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(0)); } void Heap::StringObject::init(const QV4::String *str) { Object::init(); string.set(internalClass->engine, str->d()); - *propertyData(LengthPropertyIndex) = Primitive::fromInt32(length()); + setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(length())); } Heap::String *Heap::StringObject::getIndex(uint index) const @@ -556,7 +556,7 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call offset = qMax(offset + 1, matchOffsets[oldSize + 1]); } if (regExp->global()) - *regExp->lastIndexProperty() = Primitive::fromUInt32(0); + regExp->setLastIndex(0); numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2); numCaptures = regExp->value()->captureCount(); } else { diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 93b0dfb6d4..4c46eccbd3 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -717,6 +717,44 @@ struct HeapValue : Value { }; template <size_t offset> +struct HeapValueArray { + uint size; + uint alloc; + Value values[1]; + + void set(ExecutionEngine *e, uint index, Value v) { + Q_UNUSED(e); + Q_ASSERT(index < alloc); + values[index] = v; + } + void set(ExecutionEngine *e, uint index, Heap::Base *b) { + Q_UNUSED(e); + Q_ASSERT(index < alloc); + values[index] = b; + } + inline const Value &operator[] (uint index) const { + Q_ASSERT(index < alloc); + return values[index]; + } + inline const Value *data() const { + return values; + } + + void insertData(ExecutionEngine *e, uint index, Value v) { + for (uint i = size - 1; i > index; --i) { + values[i] = values[i - 1]; + } + set(e, index, v); + } + void removeData(ExecutionEngine *e, uint index, int n = 1) { + Q_UNUSED(e); + for (uint i = index; i < size - n; ++i) { + values[i] = values[i + n]; + } + } +}; + +template <size_t offset> struct ValueArray { uint size; uint alloc; diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 5cab4c5386..f2ff5d307e 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -84,7 +84,7 @@ bool VariantObject::isEqualTo(Managed *m, Managed *other) return false; } -void VariantObject::addVmePropertyReference() +void VariantObject::addVmePropertyReference() const { if (d()->isScarce() && ++d()->vmePropertyReferenceCount == 1) { // remove from the ep->scarceResources list @@ -94,7 +94,7 @@ void VariantObject::addVmePropertyReference() } } -void VariantObject::removeVmePropertyReference() +void VariantObject::removeVmePropertyReference() const { if (d()->isScarce() && --d()->vmePropertyReferenceCount == 0) { // and add to the ep->scarceResources list diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h index ef51b6632d..e281602bb5 100644 --- a/src/qml/jsruntime/qv4variantobject_p.h +++ b/src/qml/jsruntime/qv4variantobject_p.h @@ -96,8 +96,8 @@ struct VariantObject : Object V4_PROTOTYPE(variantPrototype) V4_NEEDS_DESTROY - void addVmePropertyReference(); - void removeVmePropertyReference(); + void addVmePropertyReference() const; + void removeVmePropertyReference() const; static bool isEqualTo(Managed *m, Managed *other); }; |