aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-09-20 15:13:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-22 15:29:00 +0200
commit1fb3cd12c8cdc76d1986736fbd60b5810cc17045 (patch)
tree700e7e2d29231a57c945e53fe71e2ab2250e8f2a
parent47bf40dd49f90b52cc1b545b2be3035d48d6199e (diff)
Fix cases where mark() would access uninitialized memory
Change-Id: I4e07e20d30ba57759a0ece1c298a02b098718b33 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/compiler/qv4compileddata.cpp7
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp1
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp1
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp82
-rw-r--r--src/qml/jsruntime/qv4function.cpp2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp5
-rw-r--r--src/qml/jsruntime/qv4object.cpp10
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp5
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp2
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp5
-rw-r--r--src/qml/qml/qqmllocale.cpp6
-rw-r--r--src/qml/qml/v8/qv8engine.cpp20
15 files changed, 87 insertions, 78 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index cc1f27c064..4139a7ee0d 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -76,10 +76,14 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
assert(!runtimeStrings);
assert(data);
runtimeStrings = (QV4::SafeString *)malloc(data->stringTableSize * sizeof(QV4::SafeString));
+ // memset the strings to 0 in case a GC run happens while we're within the loop below
+ memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::SafeString));
for (int i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
+ // memset the regexps to 0 in case a GC run happens while we're within the loop below
+ memset(runtimeRegularExpressions, 0, data->regexpTableSize * sizeof(QV4::Value));
for (int i = 0; i < data->regexpTableSize; ++i) {
const CompiledData::RegExp *re = data->regexpAt(i);
int flags = 0;
@@ -166,7 +170,8 @@ void CompilationUnit::markObjects()
for (int i = 0; i < data->regexpTableSize; ++i)
runtimeRegularExpressions[i].mark();
for (int i = 0; i < runtimeFunctions.count(); ++i)
- runtimeFunctions[i]->mark();
+ if (runtimeFunctions[i])
+ runtimeFunctions[i]->mark();
}
QString Binding::valueAsString(const Unit *unit) const
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index c723471c9f..6d69e57113 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -75,6 +75,7 @@ CompilationUnit::~CompilationUnit()
void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
{
runtimeFunctions.resize(data->functionTableSize);
+ runtimeFunctions.fill(0);
for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
const CompiledData::Function *compiledFunction = data->functionAt(i);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index b3e837d158..90d261620a 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -1059,6 +1059,7 @@ CompilationUnit::~CompilationUnit()
void CompilationUnit::linkBackendToEngine(QV4::ExecutionEngine *engine)
{
runtimeFunctions.resize(data->functionTableSize);
+ runtimeFunctions.fill(0);
for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 492dfe139b..44687463e2 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -167,9 +167,11 @@ ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx)
result->arraySet(0, thisObject);
}
+ ScopedArrayObject elt(scope);
for (uint i = 0; i < ctx->argumentCount; ++i) {
- if (ArrayObject *elt = ctx->arguments[i].asArrayObject())
- result->arrayConcat(elt);
+ elt = ctx->arguments[i];
+ if (elt)
+ result->arrayConcat(elt.getPointer());
else
result->arraySet(getLength(ctx, result.getPointer()), ctx->arguments[i]);
}
@@ -188,17 +190,12 @@ ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx)
else
r4 = arg->toQString();
- Scoped<Object> self(scope, ctx->thisObject);
+ ScopedObject self(scope, ctx->thisObject);
ScopedValue length(scope, self->get(ctx->engine->id_length));
- const quint32 r2 = Value::toUInt32(length->isUndefined() ? 0 : length->toNumber());
+ const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
- static QSet<Object *> visitedArrayElements;
-
- if (! r2 || visitedArrayElements.contains(self.getPointer()))
- return Value::fromString(ctx, QString()).asReturnedValue();
-
- // avoid infinite recursion
- visitedArrayElements.insert(self.getPointer());
+ if (!r2)
+ return ctx->engine->newString(QString())->asReturnedValue();
QString R;
@@ -234,8 +231,7 @@ ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx)
}
}
- visitedArrayElements.remove(self.getPointer());
- return Value::fromString(ctx, R).asReturnedValue();
+ return ctx->engine->newString(R)->asReturnedValue();
}
ReturnedValue ArrayPrototype::method_pop(SimpleCallContext *ctx)
@@ -247,7 +243,7 @@ ReturnedValue ArrayPrototype::method_pop(SimpleCallContext *ctx)
if (!len) {
if (!instance->isArrayObject())
instance->put(ctx->engine->id_length, ScopedValue(scope, Value::fromInt32(0)));
- return Value::undefinedValue().asReturnedValue();
+ return Encode::undefined();
}
ScopedValue result(scope, instance->getIndexed(len - 1));
@@ -269,9 +265,9 @@ ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
if (len + ctx->argumentCount < len) {
// ughh...
double l = len;
+ ScopedString s(scope);
for (int i = 0; i < ctx->argumentCount; ++i) {
- Value idx = Value::fromDouble(l + i);
- ScopedString s(scope, idx.toString(ctx));
+ s = Value::fromDouble(l + i).toString(ctx);
instance->put(s, ctx->arguments[i]);
}
double newLen = l + ctx->argumentCount;
@@ -307,17 +303,14 @@ ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
else
instance->put(ctx->engine->id_length, ScopedValue(scope, Value::fromDouble(len)));
- if (len < INT_MAX)
- return Value::fromInt32(len).asReturnedValue();
- return Value::fromDouble((double)len).asReturnedValue();
-
+ return Encode(len);
}
ReturnedValue ArrayPrototype::method_reverse(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint length = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint length = getLength(ctx, instance.getPointer());
int lo = 0, hi = length - 1;
@@ -336,14 +329,14 @@ ReturnedValue ArrayPrototype::method_reverse(SimpleCallContext *ctx)
else
instance->deleteIndexedProperty(hi);
}
- return Value::fromObject(instance).asReturnedValue();
+ return instance.asReturnedValue();
}
ReturnedValue ArrayPrototype::method_shift(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint len = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint len = getLength(ctx, instance.getPointer());
if (!len) {
if (!instance->isArrayObject())
@@ -396,10 +389,10 @@ ReturnedValue ArrayPrototype::method_shift(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *o = ctx->thisObject.toObject(ctx);
+ ScopedObject o(scope, ctx->thisObject.toObject(ctx));
Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
- uint len = ArrayPrototype::getLength(ctx, o);
+ uint len = getLength(ctx, o.getPointer());
double s = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
if (s < 0)
@@ -447,8 +440,8 @@ ReturnedValue ArrayPrototype::method_sort(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint len = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint len = getLength(ctx, instance.getPointer());
Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject());
@@ -462,12 +455,10 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, ctx->argument(1))->toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
- Property *pd = newArray->arrayData;
for (uint i = 0; i < deleteCount; ++i) {
- pd->value = Value::fromReturnedValue(instance->getIndexed(start + i));
- ++pd;
+ newArray->arrayData[i].value = Value::fromReturnedValue(instance->getIndexed(start + i));
+ newArray->arrayDataLen = i + 1;
}
- newArray->arrayDataLen = deleteCount;
newArray->setArrayLengthUnchecked(deleteCount);
uint itemCount = ctx->argumentCount < 2 ? 0 : ctx->argumentCount - 2;
@@ -509,11 +500,11 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint len = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint len = getLength(ctx, instance.getPointer());
+ ScopedValue v(scope);
if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
- ScopedValue v(scope);
for (int i = ctx->argumentCount - 1; i >= 0; --i) {
v = ctx->argument(i);
@@ -535,7 +526,6 @@ ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
}
}
} else {
- ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
@@ -554,17 +544,15 @@ ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
else
instance->put(ctx->engine->id_length, ScopedValue(scope, Value::fromDouble(newLen)));
- if (newLen < INT_MAX)
- return Value::fromInt32(newLen).asReturnedValue();
- return Value::fromDouble((double)newLen).asReturnedValue();
+ return Encode(newLen);
}
ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint len = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint len = getLength(ctx, instance.getPointer());
if (!len)
return Value::fromInt32(-1).asReturnedValue();
@@ -596,15 +584,15 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
return Encode(-1);
}
- return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance);
+ return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance.getPointer());
}
ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
- uint len = getLength(ctx, instance);
+ ScopedObject instance(scope, ctx->thisObject.toObject(ctx));
+ uint len = getLength(ctx, instance.getPointer());
if (!len)
return Value::fromInt32(-1).asReturnedValue();
@@ -634,7 +622,7 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
bool exists;
v = instance->getIndexed(k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue))
- return Value::fromDouble(k).asReturnedValue();
+ return Encode(k);
}
return Value::fromInt32(-1).asReturnedValue();
}
@@ -668,7 +656,7 @@ ReturnedValue ArrayPrototype::method_every(SimpleCallContext *ctx)
r = callback->call(callData);
ok = r->toBoolean();
}
- return Value::fromBoolean(ok).asReturnedValue();
+ return Encode(ok);
}
ReturnedValue ArrayPrototype::method_some(SimpleCallContext *ctx)
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index a39050aaf2..89eb5baba2 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -62,12 +62,14 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
name = compilationUnit->runtimeStrings[compiledFunction->nameIndex].asString();
formals.resize(compiledFunction->nFormals);
+ formals.fill(0);
const quint32 *formalsIndices = compiledFunction->formalsTable();
for (int i = 0; i < compiledFunction->nFormals; ++i)
formals[i] = engine->newString(unit->data->stringAt(formalsIndices[i]));
locals.resize(compiledFunction->nLocals);
+ locals.fill(0);
const quint32 *localsIndices = compiledFunction->localsTable();
for (int i = 0; i < compiledFunction->nLocals; ++i)
locals[i] = engine->newString(unit->data->stringAt(localsIndices[i]));
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index a7332d65da..6c60a9964a 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -92,6 +92,9 @@ FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, boo
, varCount(0)
, function(0)
{
+ // set the name to something here, so that a gc run a few lines below doesn't crash on it
+ this->name = scope->engine->id_undefined;
+
Scope s(scope);
ScopedValue protectThis(s, this);
ScopedString n(s, s.engine->newString(name));
@@ -108,7 +111,7 @@ FunctionObject::FunctionObject(InternalClass *ic)
, function(0)
{
vtbl = &static_vtbl;
- name = (QV4::String *)0;
+ name = engine()->id_undefined;
type = Type_FunctionObject;
needsActivation = false;
@@ -125,6 +128,7 @@ FunctionObject::~FunctionObject()
void FunctionObject::init(const StringRef n, bool createProto)
{
vtbl = &static_vtbl;
+ name = n;
Scope s(engine());
ScopedValue protectThis(s, this);
@@ -143,13 +147,8 @@ void FunctionObject::init(const StringRef n, bool createProto)
memberData[Index_Prototype].value = proto.asValue();
}
- if (n) {
- name = n;
- ScopedValue v(s, n.asReturnedValue());
- defineReadonlyProperty(scope->engine->id_name, v);
- } else {
- name = (QV4::String *)0;
- }
+ ScopedValue v(s, n.asReturnedValue());
+ defineReadonlyProperty(scope->engine->id_name, v);
}
ReturnedValue FunctionObject::newInstance()
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index f311dfd420..5d1669dd8b 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -1036,9 +1036,10 @@ QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJso
int size = array.size();
Scoped<ArrayObject> a(scope, engine->newArrayObject());
a->arrayReserve(size);
- a->arrayDataLen = size;
- for (int i = 0; i < size; i++)
+ for (int i = 0; i < size; i++) {
a->arrayData[i].value = Value::fromReturnedValue(fromJsonValue(engine, array.at(i)));
+ a->arrayDataLen = i + 1;
+ }
a->setArrayLengthUnchecked(size);
return a.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index c2a120c7f3..78b963e12d 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1202,11 +1202,11 @@ void Object::arrayConcat(const ArrayObject *other)
ensureArrayAttributes();
std::fill(arrayAttributes + arrayDataLen, arrayAttributes + oldSize, PropertyAttributes());
}
- arrayDataLen = oldSize + other->arrayDataLen;
if (other->arrayAttributes) {
- for (int i = 0; i < arrayDataLen; ++i) {
+ for (int i = 0; i < other->arrayDataLen; ++i) {
bool exists;
arrayData[oldSize + i].value = Value::fromReturnedValue(const_cast<ArrayObject *>(other)->getIndexed(i, &exists));
+ arrayDataLen = oldSize + i + 1;
if (arrayAttributes)
arrayAttributes[oldSize + i] = Attr_Data;
if (!exists) {
@@ -1215,6 +1215,7 @@ void Object::arrayConcat(const ArrayObject *other)
}
}
} else {
+ arrayDataLen = oldSize + other->arrayDataLen;
memcpy(arrayData + oldSize, other->arrayData, other->arrayDataLen*sizeof(Property));
if (arrayAttributes)
std::fill(arrayAttributes + oldSize, arrayAttributes + oldSize + other->arrayDataLen, PropertyAttributes(Attr_Data));
@@ -1449,9 +1450,10 @@ ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
// elements converted to JS Strings.
int len = list.count();
arrayReserve(len);
- for (int ii = 0; ii < len; ++ii)
+ for (int ii = 0; ii < len; ++ii) {
arrayData[ii].value = Value::fromString(engine->newString(list.at(ii)));
- arrayDataLen = len;
+ arrayDataLen = ii + 1;
+ }
setArrayLengthUnchecked(len);
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index e982989a4d..7e31797627 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1611,9 +1611,10 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
QList<QObject *> &list = *qlistPtr;
QV4::Scoped<ArrayObject> array(scope, v4->newArrayObject());
array->arrayReserve(list.count());
- array->arrayDataLen = list.count();
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.count(); ++ii) {
array->arrayData[ii].value = Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, list.at(ii)));
+ array->arrayDataLen = ii + 1;
+ }
array->setArrayLengthUnchecked(list.count());
return array.asReturnedValue();
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 697d5e35d6..3f58f28b4b 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -333,8 +333,8 @@ ReturnedValue RegExpPrototype::method_exec(SimpleCallContext *ctx)
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
array->arrayData[i].value = (start != -1 && end != -1) ? Value::fromString(ctx, s.mid(start, end - start)) : Value::undefinedValue();
+ array->arrayDataLen = i + 1;
}
- array->arrayDataLen = len;
array->setArrayLengthUnchecked(len);
array->memberData[Index_ArrayIndex].value = Value::fromInt32(result);
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index cabe326d13..ae35d6c375 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -385,10 +385,10 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
int sequenceType = value->integerValue();
Scoped<ArrayObject> array(scope, v4->newArrayObject());
array->arrayReserve(seqLength);
- array->arrayDataLen = seqLength;
for (quint32 ii = 0; ii < seqLength; ++ii) {
value = deserialize(data, engine);
array->arrayData[ii].value = value;
+ array->arrayDataLen = ii + 1;
}
array->setArrayLengthUnchecked(seqLength);
QVariant seqVariant = QV4::SequencePrototype::toVariant(array.asValue(), sequenceType, &succeeded);
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index bfad395b3b..ad884b6380 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -90,6 +90,8 @@ inline ExecutionEngine *Value::engine() const {
}
inline void Value::mark() const {
+ if (!val)
+ return;
Managed *m = asManaged();
if (m)
m->mark();
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 483ae908b4..cf3493a590 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1244,12 +1244,13 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (!valuemap.isUndefined()) {
QQmlComponentExtension *e = componentExtension(v8engine);
- QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()));
+ QV4::ScopedValue f(scope, QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()));
+ Q_ASSERT(f->asFunctionObject());
QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4engine->globalObject);
callData->args[0] = object;
callData->args[1] = valuemap;
- f->call(callData);
+ f->asFunctionObject()->call(callData);
}
d->completeCreate();
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 85d200e8e6..c3c7d0282d 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -562,9 +562,11 @@ QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::SimpleCallContext
QStringList langs = locale.uiLanguages();
QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject());
result->arrayReserve(langs.size());
- result->arrayDataLen = langs.size();
- for (int i = 0; i < langs.size(); ++i)
+ for (int i = 0; i < langs.size(); ++i) {
result->arrayData[i].value = QV4::Value::fromString(ctx, langs.at(i));
+ result->arrayDataLen = i + 1;
+ }
+
result->setArrayLengthUnchecked(langs.size());
return result.asReturnedValue();
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 70c3104ffa..b62e2150af 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -187,9 +187,10 @@ static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringLi
QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
- a->arrayDataLen = len;
- for (int ii = 0; ii < len; ++ii)
+ for (int ii = 0; ii < len; ++ii) {
a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii)));
+ a->arrayDataLen = ii + 1;
+ }
a->setArrayLengthUnchecked(len);
return a.asReturnedValue();
}
@@ -201,9 +202,10 @@ static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariant
QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
- a->arrayDataLen = len;
- for (int ii = 0; ii < len; ++ii)
+ for (int ii = 0; ii < len; ++ii) {
a->arrayData[ii].value = QV4::Value::fromReturnedValue(engine->fromVariant(list.at(ii)));
+ a->arrayDataLen = ii + 1;
+ }
a->setArrayLengthUnchecked(len);
return a.asReturnedValue();
}
@@ -314,9 +316,10 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
const QList<QObject *> &list = *(QList<QObject *>*)ptr;
QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(list.count());
- a->arrayDataLen = list.count();
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.count(); ++ii) {
a->arrayData[ii].value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)));
+ a->arrayDataLen = ii + 1;
+ }
a->setArrayLengthUnchecked(list.count());
return a.asReturnedValue();
} else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
@@ -524,9 +527,10 @@ QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst)
QV4::Scope scope(m_v4Engine);
QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(lst.size());
- a->arrayDataLen = lst.size();
- for (int i = 0; i < lst.size(); i++)
+ for (int i = 0; i < lst.size(); i++) {
a->arrayData[i].value = QV4::Value::fromReturnedValue(variantToJS(lst.at(i)));
+ a->arrayDataLen = i + 1;
+ }
a->setArrayLengthUnchecked(lst.size());
return a.asReturnedValue();
}