aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-09-19 16:05:25 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-22 01:06:20 +0200
commit47bf40dd49f90b52cc1b545b2be3035d48d6199e (patch)
tree9e671c23d610822ac354e4a1399e2c805cbea599 /src/qml
parent78b49cf8361b1462cc94a061916a15f0b98e27e3 (diff)
Prevent objects from being collected while in their constructor
While objects are being constructed, we don't have a reference to them on the JS stack yet. So the constructor needs to protect itself against being collected by putting the this object onto the JS stack. Added an environment switch MM_EXACT_GC to test exact garbage collection. Change-Id: Ie37665a954de800359c272ffbebbe1488e7a8ace Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp29
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4function.cpp7
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp89
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h11
-rw-r--r--src/qml/jsruntime/qv4mm.cpp17
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h28
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4value_def_p.h1
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp6
19 files changed, 150 insertions, 62 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index aa9b6af728..492dfe139b 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -49,7 +49,7 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(ArrayCtor);
ArrayCtor::ArrayCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Array")))
+ : FunctionObject(scope, QStringLiteral("Array"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 44188e535c..be801a67c2 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -46,7 +46,7 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(BooleanCtor);
BooleanCtor::BooleanCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier("Boolean"))
+ : FunctionObject(scope, QStringLiteral("Boolean"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 72dc5433e5..8bc92c6c4e 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -652,7 +652,7 @@ QDateTime DateObject::toQDateTime() const
DEFINE_MANAGED_VTABLE(DateCtor);
DateCtor::DateCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Date")))
+ : FunctionObject(scope, QStringLiteral("Date"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8d85ffd4fc..821e88ee61 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -358,7 +358,7 @@ ExecutionContext *ExecutionEngine::pushGlobalContext()
Returned<FunctionObject> *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *))
{
- BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name.getPointer(), code);
+ BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name, code);
return f->asReturned<FunctionObject>();
}
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 700e17c664..7ffc4feb9e 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -78,6 +78,10 @@ ErrorObject::ErrorObject(InternalClass *ic)
{
type = Type_ErrorObject;
vtbl = &static_vtbl;
+
+ Scope scope(engine());
+ ScopedValue protectThis(scope, this);
+
defineDefaultProperty(QStringLiteral("name"), Value::fromString(ic->engine, "Error"));
}
@@ -88,6 +92,10 @@ ErrorObject::ErrorObject(InternalClass *ic, const Value &message, ErrorType t)
type = Type_ErrorObject;
vtbl = &static_vtbl;
subtype = t;
+
+ Scope scope(engine());
+ ScopedValue protectThis(scope, this);
+
defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
if (!message.isUndefined())
@@ -108,8 +116,11 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin
type = Type_ErrorObject;
vtbl = &static_vtbl;
subtype = t;
- defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
+ Scope scope(engine());
+ ScopedValue protectThis(scope, this);
+
+ defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0);
defineDefaultProperty(QStringLiteral("name"), Value::fromString(ic->engine, className()));
stackTrace = ic->engine->stackTrace();
@@ -229,12 +240,12 @@ DEFINE_MANAGED_VTABLE(TypeErrorCtor);
DEFINE_MANAGED_VTABLE(URIErrorCtor);
ErrorCtor::ErrorCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Error")))
+ : FunctionObject(scope, QStringLiteral("Error"))
{
vtbl = &static_vtbl;
}
-ErrorCtor::ErrorCtor(ExecutionContext *scope, String *name)
+ErrorCtor::ErrorCtor(ExecutionContext *scope, const QString &name)
: FunctionObject(scope, name)
{
vtbl = &static_vtbl;
@@ -251,7 +262,7 @@ ReturnedValue ErrorCtor::call(Managed *that, CallData *callData)
}
EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("EvalError"))
+ : ErrorCtor(scope, QStringLiteral("EvalError"))
{
vtbl = &static_vtbl;
}
@@ -263,7 +274,7 @@ ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
}
RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("RangeError"))
+ : ErrorCtor(scope, QStringLiteral("RangeError"))
{
vtbl = &static_vtbl;
}
@@ -274,7 +285,7 @@ ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
}
ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("ReferenceError"))
+ : ErrorCtor(scope, QStringLiteral("ReferenceError"))
{
vtbl = &static_vtbl;
}
@@ -285,7 +296,7 @@ ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
}
SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("SyntaxError"))
+ : ErrorCtor(scope, QStringLiteral("SyntaxError"))
{
vtbl = &static_vtbl;
}
@@ -296,7 +307,7 @@ ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
}
TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("TypeError"))
+ : ErrorCtor(scope, QStringLiteral("TypeError"))
{
vtbl = &static_vtbl;
}
@@ -307,7 +318,7 @@ ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
}
URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
- : ErrorCtor(scope, scope->engine->newIdentifier("URIError"))
+ : ErrorCtor(scope, QStringLiteral("URIError"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index fb526e9b1e..1592ec791e 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -116,7 +116,7 @@ struct ErrorCtor: FunctionObject
{
Q_MANAGED
ErrorCtor(ExecutionContext *scope);
- ErrorCtor(ExecutionContext *scope, String *name);
+ ErrorCtor(ExecutionContext *scope, const QString &name);
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index f69a095991..a39050aaf2 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -53,8 +53,7 @@ using namespace QV4;
Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
ReturnedValue (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize)
- : name(0)
- , compiledFunction(function)
+ : compiledFunction(function)
, compilationUnit(unit)
, codePtr(codePtr)
, codeData(0)
@@ -81,8 +80,8 @@ Function::~Function()
void Function::mark()
{
- if (name)
- name->mark();
+ if (name.asManaged())
+ name.asManaged()->mark();
for (int i = 0; i < formals.size(); ++i)
formals.at(i)->mark();
for (int i = 0; i < locals.size(); ++i)
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index b93eded3f3..746abe910d 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -81,7 +81,7 @@ struct InternalClass;
struct Lookup;
struct Function {
- String *name;
+ SafeString name;
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 69c749f92f..a7332d65da 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -71,41 +71,36 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(FunctionObject);
-FunctionObject::FunctionObject(ExecutionContext *scope, String *name, bool createProto)
+FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
: Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
, scope(scope)
- , name(name)
, formalParameterList(0)
, varList(0)
, formalParameterCount(0)
, varCount(0)
, function(0)
{
- vtbl = &static_vtbl;
-
- type = Type_FunctionObject;
- needsActivation = true;
- usesArgumentsObject = false;
- strictMode = false;
-#ifndef QT_NO_DEBUG
- assert(scope->next != (ExecutionContext *)0x1);
-#endif
-
- if (createProto) {
- Scope s(scope);
- Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
- proto->memberData[Index_ProtoConstructor].value = Value::fromObject(this);
- memberData[Index_Prototype].value = proto.asValue();
- }
+ init(name, createProto);
+}
- if (name)
- defineReadonlyProperty(scope->engine->id_name, Value::fromString(name));
+FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
+ : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
+ , scope(scope)
+ , formalParameterList(0)
+ , varList(0)
+ , formalParameterCount(0)
+ , varCount(0)
+ , function(0)
+{
+ Scope s(scope);
+ ScopedValue protectThis(s, this);
+ ScopedString n(s, s.engine->newString(name));
+ init(n, createProto);
}
FunctionObject::FunctionObject(InternalClass *ic)
: Object(ic)
, scope(ic->engine->rootContext)
- , name(name)
, formalParameterList(0)
, varList(0)
, formalParameterCount(0)
@@ -113,8 +108,12 @@ FunctionObject::FunctionObject(InternalClass *ic)
, function(0)
{
vtbl = &static_vtbl;
+ name = (QV4::String *)0;
type = Type_FunctionObject;
+ needsActivation = false;
+ usesArgumentsObject = false;
+ strictMode = false;
}
FunctionObject::~FunctionObject()
@@ -123,6 +122,36 @@ FunctionObject::~FunctionObject()
function->compilationUnit->deref();
}
+void FunctionObject::init(const StringRef n, bool createProto)
+{
+ vtbl = &static_vtbl;
+
+ Scope s(engine());
+ ScopedValue protectThis(s, this);
+
+ type = Type_FunctionObject;
+ needsActivation = true;
+ usesArgumentsObject = false;
+ strictMode = false;
+#ifndef QT_NO_DEBUG
+ assert(scope->next != (ExecutionContext *)0x1);
+#endif
+
+ if (createProto) {
+ Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
+ proto->memberData[Index_ProtoConstructor].value = Value::fromObject(this);
+ 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;
+ }
+}
+
ReturnedValue FunctionObject::newInstance()
{
Scope scope(engine());
@@ -177,7 +206,7 @@ ReturnedValue FunctionObject::call(Managed *, CallData *)
void FunctionObject::markObjects(Managed *that)
{
FunctionObject *o = static_cast<FunctionObject *>(that);
- if (o->name)
+ if (o->name.managed())
o->name->mark();
// these are marked in VM::Function:
// for (uint i = 0; i < formalParameterCount; ++i)
@@ -202,7 +231,7 @@ FunctionObject *FunctionObject::creatScriptFunction(ExecutionContext *scope, Fun
DEFINE_MANAGED_VTABLE(FunctionCtor);
FunctionCtor::FunctionCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Function")))
+ : FunctionObject(scope, QStringLiteral("Function"))
{
vtbl = &static_vtbl;
}
@@ -367,6 +396,10 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
: FunctionObject(scope, function->name, true)
{
vtbl = &static_vtbl;
+
+ Scope s(scope);
+ ScopedValue protectThis(s, this);
+
this->function = function;
this->function->compilationUnit->ref();
Q_ASSERT(function);
@@ -462,6 +495,10 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
: FunctionObject(scope, function->name, true)
{
vtbl = &static_vtbl;
+
+ Scope s(scope);
+ ScopedValue protectThis(s, this);
+
this->function = function;
this->function->compilationUnit->ref();
Q_ASSERT(function);
@@ -554,7 +591,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
DEFINE_MANAGED_VTABLE(BuiltinFunction);
-BuiltinFunction::BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *))
+BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *))
: FunctionObject(scope, name)
, code(code)
{
@@ -635,6 +672,10 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
, boundArgs(boundArgs)
{
vtbl = &static_vtbl;
+
+ Scope s(scope);
+ ScopedValue protectThis(s, this);
+
int len = Value::fromReturnedValue(target->get(scope->engine->id_length)).toUInt32();
len -= boundArgs.size();
if (len < 0)
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index dfd160dbc0..d01a989ae1 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -106,16 +106,19 @@ struct Q_QML_EXPORT FunctionObject: Object {
};
ExecutionContext *scope;
- String *name;
+ SafeString name;
String * const *formalParameterList;
String * const *varList;
unsigned int formalParameterCount;
unsigned int varCount;
Function *function;
- FunctionObject(ExecutionContext *scope, String *name = 0, bool createProto = false);
+ FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto = false);
+ FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
~FunctionObject();
+ void init(const StringRef name, bool createProto);
+
ReturnedValue newInstance();
static ReturnedValue construct(Managed *that, CallData *);
@@ -171,7 +174,7 @@ struct BuiltinFunction: FunctionObject {
Q_MANAGED
ReturnedValue (*code)(SimpleCallContext *);
- BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *));
+ BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *));
static ReturnedValue construct(Managed *, CallData *);
static ReturnedValue call(Managed *that, CallData *callData);
@@ -185,7 +188,7 @@ struct IndexedBuiltinFunction: FunctionObject
uint index;
IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(SimpleCallContext *ctx, uint index))
- : FunctionObject(scope, /*name*/0)
+ : FunctionObject(scope)
, code(code)
, index(index)
{
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index a7e485a2a2..0233af29b9 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -80,6 +80,7 @@ struct MemoryManager::Data
bool gcBlocked;
bool scribble;
bool aggressiveGC;
+ bool exactGC;
ExecutionEngine *engine;
quintptr *stackTop;
@@ -113,6 +114,11 @@ struct MemoryManager::Data
memset(allocCount, 0, sizeof(allocCount));
scribble = !qgetenv("MM_SCRIBBLE").isEmpty();
aggressiveGC = !qgetenv("MM_AGGRESSIVE_GC").isEmpty();
+ exactGC = !qgetenv("MM_EXACT_GC").isEmpty();
+ if (aggressiveGC)
+ qDebug() << "Using aggressive garbage collection";
+ if (exactGC)
+ qDebug() << "Using exact garbage collection";
}
~Data()
@@ -293,9 +299,11 @@ void MemoryManager::mark()
# endif // CPU
#endif // COMPILER
- collectFromStack();
collectFromJSStack();
+ if (!m_d->exactGC)
+ collectFromStack();
+
// Preserve QObject ownership rules within JavaScript: A parent with c++ ownership
// keeps all of its children alive in JavaScript.
@@ -573,12 +581,7 @@ void MemoryManager::collectFromStack() const
assert(i == m_d->heapChunks.count() * 2);
for (; current < m_d->stackTop; ++current) {
- char* genericPtr =
-#if QT_POINTER_SIZE == 8
- reinterpret_cast<char *>((*current) & ~(quint64(Value::Type_Mask) << Value::Tag_Shift));
-#else
- reinterpret_cast<char *>(*current);
-#endif
+ char* genericPtr = reinterpret_cast<char *>(*current);
if (genericPtr < *heapChunkBoundaries || genericPtr > *(heapChunkBoundariesEnd - 1))
continue;
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 8fbc2f4d11..f946b3180a 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -51,7 +51,7 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(NumberCtor);
NumberCtor::NumberCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Number")))
+ : FunctionObject(scope, QStringLiteral("Number"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index e356b653e6..c2a120c7f3 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1440,6 +1440,8 @@ ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
: Object(engine->arrayClass)
{
init(engine);
+ Scope scope(engine);
+ ScopedValue protectThis(scope, this);
// Converts a QStringList to JS.
// The result is a new Array object with length equal to the length
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index d0845735ce..0da2bf60b3 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -74,7 +74,7 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(ObjectCtor);
ObjectCtor::ObjectCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Object")))
+ : FunctionObject(scope, QStringLiteral("Object"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index efe3c1fe71..697d5e35d6 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -143,6 +143,8 @@ void RegExpObject::init(ExecutionEngine *engine)
type = Type_RegExpObject;
Scope scope(engine);
+ ScopedObject protectThis(scope, this);
+
ScopedString lastIndex(scope, engine->newIdentifier(QStringLiteral("lastIndex")));
Property *lastIndexProperty = insertMember(lastIndex, Attr_NotEnumerable|Attr_NotConfigurable);
lastIndexProperty->value = Value::fromInt32(0);
@@ -228,7 +230,7 @@ uint RegExpObject::flags() const
DEFINE_MANAGED_VTABLE(RegExpCtor);
RegExpCtor::RegExpCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("RegExp")))
+ : FunctionObject(scope, QStringLiteral("RegExp"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 5ec0497f15..09851af091 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -54,7 +54,7 @@ namespace QV4 {
struct ScopedValue;
struct Scope {
- Scope(ExecutionContext *ctx)
+ explicit Scope(ExecutionContext *ctx)
: engine(ctx->engine)
#ifndef QT_NO_DEBUG
, size(0)
@@ -63,14 +63,17 @@ struct Scope {
mark = ctx->engine->jsStackTop;
}
- Scope(ExecutionEngine *e)
+ explicit Scope(ExecutionEngine *e)
: engine(e)
{
mark = e->jsStackTop;
}
~Scope() {
+#ifndef QT_NO_DEBUG
Q_ASSERT(engine->jsStackTop >= mark);
+ memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
+#endif
engine->jsStackTop = mark;
}
@@ -103,6 +106,15 @@ struct ScopedValue
#endif
}
+ ScopedValue(const Scope &scope, Managed *m)
+ {
+ ptr = scope.engine->jsStackTop++;
+ ptr->val = m->asReturnedValue();
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
ScopedValue(const Scope &scope, const ReturnedValue &v)
{
ptr = scope.engine->jsStackTop++;
@@ -127,6 +139,11 @@ struct ScopedValue
return *this;
}
+ ScopedValue &operator=(Managed *m) {
+ ptr->val = m->asReturnedValue();
+ return *this;
+ }
+
ScopedValue &operator=(const ReturnedValue &v) {
ptr->val = v;
return *this;
@@ -599,6 +616,13 @@ inline Safe<T> &Safe<T>::operator=(Returned<T> *t)
}
template<typename T>
+inline Safe<T> &Safe<T>::operator =(const Referenced<T> &v)
+{
+ val = v.asReturnedValue();
+ return *this;
+}
+
+template<typename T>
inline Safe<T> &Safe<T>::operator=(const Safe<T> &t)
{
val = t.val;
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index feee229668..5e1f9161e8 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -155,7 +155,7 @@ void StringObject::markObjects(Managed *that)
DEFINE_MANAGED_VTABLE(StringCtor);
StringCtor::StringCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("String")))
+ : FunctionObject(scope, QStringLiteral("String"))
{
vtbl = &static_vtbl;
}
diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h
index 3e0728bcc2..bf344a7f3d 100644
--- a/src/qml/jsruntime/qv4value_def_p.h
+++ b/src/qml/jsruntime/qv4value_def_p.h
@@ -366,6 +366,7 @@ struct Safe : public Value
{
Safe &operator =(T *t);
Safe &operator =(const Scoped<T> &v);
+ Safe &operator =(const Referenced<T> &v);
Safe &operator =(Returned<T> *t);
Safe &operator =(const Safe<T> &t);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 79b9344994..48072f53c8 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1585,9 +1585,12 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
{
Q_MANAGED
QQmlXMLHttpRequestCtor(ExecutionEngine *engine)
- : FunctionObject(engine->rootContext, engine->newString(QStringLiteral("XMLHttpRequest")))
+ : FunctionObject(engine->rootContext, QStringLiteral("XMLHttpRequest"))
{
vtbl = &static_vtbl;
+ Scope scope(engine);
+ ScopedValue protectThis(scope, this);
+
defineReadonlyProperty(QStringLiteral("UNSENT"), Value::fromInt32(0));
defineReadonlyProperty(QStringLiteral("OPENED"), Value::fromInt32(1));
defineReadonlyProperty(QStringLiteral("HEADERS_RECEIVED"), Value::fromInt32(2));
@@ -1595,7 +1598,6 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
defineReadonlyProperty(QStringLiteral("DONE"), Value::fromInt32(4));
if (!proto)
setupProto();
- Scope scope(engine);
ScopedString s(scope, engine->id_prototype);
defineDefaultProperty(s, Value::fromObject(proto));
}