diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-09-19 16:05:25 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-22 01:06:20 +0200 |
commit | 47bf40dd49f90b52cc1b545b2be3035d48d6199e (patch) | |
tree | 9e671c23d610822ac354e4a1399e2c805cbea599 /src/qml/jsruntime/qv4scopedvalue_p.h | |
parent | 78b49cf8361b1462cc94a061916a15f0b98e27e3 (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/jsruntime/qv4scopedvalue_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 28 |
1 files changed, 26 insertions, 2 deletions
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; |