aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp2
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4context.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp29
-rw-r--r--src/qml/jsruntime/qv4engine_p.h3
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4object.cpp14
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp4
-rw-r--r--src/qml/jsruntime/qv4property_p.h31
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp2
13 files changed, 68 insertions, 46 deletions
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
index e3358b29bd..9e02310815 100644
--- a/src/qml/jsapi/qjsvalueiterator.cpp
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -150,7 +150,7 @@ bool QJSValueIterator::next()
return false;
d_ptr->currentName = d_ptr->nextName;
d_ptr->currentIndex = d_ptr->nextIndex;
- d_ptr->currentProperty = d_ptr->nextProperty;
+ d_ptr->currentProperty.copy(d_ptr->nextProperty, d_ptr->nextAttributes);
d_ptr->currentAttributes = d_ptr->nextAttributes;
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 3a0aad2fcf..c8ba2c4037 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -58,11 +58,12 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
setArrayType(ArrayData::Complex);
if (context->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
Q_ASSERT(CallerPropertyIndex == internalClass->find(context->engine->id_caller));
- *propertyAt(CalleePropertyIndex) = pd;
- *propertyAt(CallerPropertyIndex) = pd;
+ propertyAt(CalleePropertyIndex)->value = v4->thrower;
+ propertyAt(CalleePropertyIndex)->set = v4->thrower;
+ propertyAt(CallerPropertyIndex)->value = v4->thrower;
+ propertyAt(CallerPropertyIndex)->set = v4->thrower;
arrayReserve(context->callData->argc);
arrayPut(0, context->callData->args, context->callData->argc);
@@ -94,7 +95,7 @@ void ArgumentsObject::fullyCreate()
context->engine->requireArgumentsAccessors(numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments.append(context->callData->args[i]);
- arraySet(i, context->engine->argumentsAccessors.at(i), Attr_Accessor);
+ arraySet(i, context->engine->argumentsAccessors[i], Attr_Accessor);
}
arrayPut(numAccessors, context->callData->args + numAccessors, argCount - numAccessors);
for (uint i = numAccessors; i < argCount; ++i)
@@ -113,11 +114,11 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
PropertyAttributes mapAttrs;
bool isMapped = false;
if (pd && index < (uint)mappedArguments.size())
- isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors.at(index).getter();
+ isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors[index].getter();
if (isMapped) {
- map = *pd;
mapAttrs = arrayData->attributes(index);
+ map.copy(*pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
pd = arrayData->getProperty(index);
pd->value = mappedArguments.at(index);
@@ -137,7 +138,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
if (attrs.isWritable()) {
setArrayAttributes(index, mapAttrs);
pd = arrayData->getProperty(index);
- *pd = map;
+ pd->copy(map, mapAttrs);
}
}
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 44727cba17..f03f5cd378 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -595,7 +595,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
} else {
for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode())
- obj->arraySet(oldSize + it->key(), other->data[it->value]);
+ obj->arraySet(oldSize + it->key(), ValueRef(other->data[it->value]));
}
} else {
obj->arrayPut(oldSize, other->data, n);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index efe1dff19c..3d710d2338 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -179,7 +179,7 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), ctx->callData->args[i]);
+ result->arraySet(result->getLength(), ValueRef(ctx->callData->args[i]));
}
}
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index fa5dc7285c..0d8e57bdd5 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -127,7 +127,7 @@ void ExecutionContext::createMutableBinding(const StringRef name, bool deletable
if (activation->hasProperty(name))
return;
- Property desc = Property::fromValue(Primitive::undefinedValue());
+ Property desc(Primitive::undefinedValue());
PropertyAttributes attrs(Attr_Data);
attrs.setConfigurable(deletable);
activation->__defineOwnProperty__(this, name, desc, attrs);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 18075139d2..5c7caca477 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -171,6 +171,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, globalObject(0)
, globalCode(0)
, v8Engine(0)
+ , argumentsAccessors(0)
+ , nArgumentsAccessors(0)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
, regExpCache(0)
, m_multiplyWrappedQObjects(0)
@@ -423,6 +425,7 @@ ExecutionEngine::~ExecutionEngine()
delete executableAllocator;
jsStack->deallocate();
delete jsStack;
+ delete [] argumentsAccessors;
}
void ExecutionEngine::enableDebugger()
@@ -784,20 +787,26 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
void ExecutionEngine::requireArgumentsAccessors(int n)
{
- if (n <= argumentsAccessors.size())
+ if (n <= nArgumentsAccessors)
return;
Scope scope(this);
ScopedFunctionObject get(scope);
ScopedFunctionObject set(scope);
- uint oldSize = argumentsAccessors.size();
- argumentsAccessors.resize(n);
- for (int i = oldSize; i < n; ++i) {
- get = new (memoryManager) ArgumentsGetterFunction(rootContext, i);
- set = new (memoryManager) ArgumentsSetterFunction(rootContext, i);
- Property pd = Property::fromAccessor(get.getPointer(), set.getPointer());
- argumentsAccessors[i] = pd;
+ if (n >= nArgumentsAccessors) {
+ Property *oldAccessors = argumentsAccessors;
+ int oldSize = nArgumentsAccessors;
+ nArgumentsAccessors = qMax(8, n);
+ argumentsAccessors = new Property[nArgumentsAccessors];
+ if (oldAccessors) {
+ memcpy(argumentsAccessors, oldAccessors, oldSize*sizeof(Property));
+ delete [] oldAccessors;
+ }
+ for (int i = oldSize; i < nArgumentsAccessors; ++i) {
+ argumentsAccessors[i].value = Value::fromManaged(new (memoryManager) ArgumentsGetterFunction(rootContext, i));
+ argumentsAccessors[i].set = Value::fromManaged(new (memoryManager) ArgumentsSetterFunction(rootContext, i));
+ }
}
}
@@ -807,8 +816,8 @@ void ExecutionEngine::markObjects()
globalObject->mark(this);
- for (int i = 0; i < argumentsAccessors.size(); ++i) {
- const Property &pd = argumentsAccessors.at(i);
+ for (int i = 0; i < nArgumentsAccessors; ++i) {
+ const Property &pd = argumentsAccessors[i];
if (FunctionObject *getter = pd.getter())
getter->mark(this);
if (FunctionObject *setter = pd.setter())
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 14358c1bb6..6bfdf1f5a1 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -231,7 +231,8 @@ public:
EvalFunction *evalFunction;
FunctionObject *thrower;
- QVector<Property> argumentsAccessors;
+ Property *argumentsAccessors;
+ int nArgumentsAccessors;
StringValue id_undefined;
StringValue id_null;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 9b502a0927..c53c528e39 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -374,7 +374,7 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
if (scope->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
@@ -457,7 +457,7 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
if (scope->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
@@ -631,7 +631,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target,
ExecutionEngine *v4 = scope->engine;
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 7ad3189dd1..f5c1be767f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -252,7 +252,9 @@ void Object::insertMember(const StringRef s, const Property &p, PropertyAttribut
if (attributes.isAccessor()) {
hasAccessorProperty = 1;
- *propertyAt(idx) = p;
+ Property *pp = propertyAt(idx);
+ pp->value = p.value;
+ pp->set = p.set;
} else {
memberData[idx] = p.value;
}
@@ -568,7 +570,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
it->arrayIndex = k + 1;
*index = k;
*attrs = a;
- *pd = *p;
+ pd->copy(*p, a);
return;
}
}
@@ -604,7 +606,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
name = n;
*attrs = a;
- *pd = *p;
+ pd->copy(*p, a);
return;
}
}
@@ -916,7 +918,8 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
if (!extensible)
goto reject;
// clause 4
- Property pd = p;
+ Property pd;
+ pd.copy(p, attrs);
pd.fullyPopulated(&attrs);
insertMember(name, pd, attrs);
return true;
@@ -961,7 +964,8 @@ bool Object::defineOwnProperty2(ExecutionContext *ctx, uint index, const Propert
if (!extensible)
goto reject;
// clause 4
- Property pp(p);
+ Property pp;
+ pp.copy(p, attrs);
pp.fullyPopulated(&attrs);
if (attrs == Attr_Data) {
Scope scope(ctx);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 5c8590f037..89dbde5c82 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -173,7 +173,7 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyProperty(const StringRef name, ValueRef value);
void insertMember(const StringRef s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
- insertMember(s, Property::fromValue(*v), attributes);
+ insertMember(s, Property(*v), attributes);
}
void insertMember(const StringRef s, const Property &p, PropertyAttributes attributes);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 51d6b8d414..8f55f3ea58 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -134,8 +134,8 @@ void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
Scoped<String> id_proto(scope, v4->id___proto__);
- Property p = Property::fromAccessor(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
- v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
+ Property p(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
+ v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
insertMember(StringRef(v4->id___proto__), p, Attr_Accessor|Attr_NotEnumerable);
}
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index aceb6022f8..4d59b6d1fe 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -70,18 +70,6 @@ struct Property {
attrs->resolve();
}
- static inline Property fromValue(Value v) {
- Property pd;
- pd.value = v;
- return pd;
- }
- static inline Property fromAccessor(FunctionObject *getter, FunctionObject *setter) {
- Property pd;
- pd.value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
- pd.set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
- return pd;
- }
-
static Property genericDescriptor() {
Property pd;
pd.value = Primitive::emptyValue();
@@ -95,6 +83,23 @@ struct Property {
inline FunctionObject *setter() const { return reinterpret_cast<FunctionObject *>(set.asManaged()); }
inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
inline void setSetter(FunctionObject *s) { set = Primitive::fromManaged(reinterpret_cast<Managed *>(s)); }
+
+ void copy(const Property &other, PropertyAttributes attrs) {
+ value = other.value;
+ if (attrs.isAccessor())
+ set = other.set;
+ }
+
+ explicit Property() { value = Encode::undefined(); set = Encode::undefined(); }
+ explicit Property(Value v) : value(v) { set = Encode::undefined(); }
+ Property(FunctionObject *getter, FunctionObject *setter) {
+ value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
+ set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
+ }
+ Property &operator=(Value v) { value = v; return *this; }
+private:
+ Property(const Property &);
+ Property &operator=(const Property &);
};
inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const
@@ -140,6 +145,8 @@ inline void Property::merge(PropertyAttributes &attrs, const Property &other, Pr
}
+Q_DECLARE_TYPEINFO(QV4::Property, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
#endif
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 07cdf31a03..5b0891ebe1 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -148,7 +148,7 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef nam
Property *pd = s->__getOwnProperty__(*index, &a);
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
*attrs = a;
- *p = *pd;
+ p->copy(*pd, a);
return;
}
}