summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-02-26 03:57:11 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-02-26 03:57:11 (GMT)
commit344b4ab658a03d81bbdb7bb5f74b2b5c8bd517e8 (patch)
treecc2ca52a14429ad37e566489e5448ef06335203e
parentfc47baa44aba2cbf8e0e5db58b7c7205ead9e427 (diff)
parentaa1e47a5a1a0978979e98f503cb44c85fc88dece (diff)
downloadQt-344b4ab658a03d81bbdb7bb5f74b2b5c8bd517e8.zip
Qt-344b4ab658a03d81bbdb7bb5f74b2b5c8bd517e8.tar.gz
Qt-344b4ab658a03d81bbdb7bb5f74b2b5c8bd517e8.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: Make QtScript support COLLECT_ON_EVERY_ALLOCATION define Add missing API shims to QScriptValue constructors Don't crash when marking arguments object of native context
-rw-r--r--src/script/api/qscriptcontext.cpp10
-rw-r--r--src/script/api/qscriptengine.cpp31
-rw-r--r--src/script/api/qscriptvalue.cpp5
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp11
4 files changed, 44 insertions, 13 deletions
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index 2468a46..5454df5 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -268,8 +268,14 @@ QScriptValue QScriptContext::argument(int index) const
QScriptValue QScriptContext::callee() const
{
const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
- QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
- return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee());
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame);
+ QScript::APIShim shim(eng);
+ if (frame->callee() == eng->originalGlobalObject()) {
+ // This is a pushContext()-created context; the callee is a lie.
+ Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext);
+ return QScriptValue();
+ }
+ return eng->scriptValueFromJSCValue(frame->callee());
}
/*!
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index d3e5f2f..160058e 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -955,8 +955,11 @@ static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng)
} // namespace QScript
QScriptEnginePrivate::QScriptEnginePrivate()
- : registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
- registeredScriptStrings(0), inEval(false)
+ : originalGlobalObjectProxy(0), currentFrame(0),
+ qobjectPrototype(0), qmetaobjectPrototype(0), variantPrototype(0),
+ activeAgent(0), agentLineNumber(-1),
+ registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
+ registeredScriptStrings(0), processEventsInterval(-1), inEval(false)
{
qMetaTypeId<QScriptValue>();
qMetaTypeId<QList<int> >();
@@ -1002,10 +1005,6 @@ QScriptEnginePrivate::QScriptEnginePrivate()
currentFrame = exec;
- originalGlobalObjectProxy = 0;
- activeAgent = 0;
- agentLineNumber = -1;
- processEventsInterval = -1;
cachedTranslationUrl = JSC::UString();
cachedTranslationContext = JSC::UString();
JSC::setCurrentIdentifierTable(oldTable);
@@ -1253,10 +1252,12 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
{
Q_Q(QScriptEngine);
- markStack.append(originalGlobalObject());
- markStack.append(globalObject());
- if (originalGlobalObjectProxy)
- markStack.append(originalGlobalObjectProxy);
+ if (originalGlobalObject()) {
+ markStack.append(originalGlobalObject());
+ markStack.append(globalObject());
+ if (originalGlobalObjectProxy)
+ markStack.append(originalGlobalObjectProxy);
+ }
if (qobjectPrototype)
markStack.append(qobjectPrototype);
@@ -1281,7 +1282,7 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
}
}
- {
+ if (q) {
QScriptContext *context = q->currentContext();
while (context) {
@@ -2727,6 +2728,14 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV
bool clearScopeChain)
{
JSC::JSValue thisObject = _thisObject;
+ if (!callee) {
+ // callee can't be zero, as this can cause JSC to crash during GC
+ // marking phase if the context's Arguments object has been created.
+ // Fake it by using the global object. Note that this is also handled
+ // in QScriptContext::callee(), as that function should still return
+ // an invalid value.
+ callee = originalGlobalObject();
+ }
if (calledAsConstructor) {
//JSC doesn't create default created object for native functions. so we do it
JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype);
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index ac57918..e289636 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -254,6 +254,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, int val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -271,6 +272,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, uint val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -288,6 +290,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -305,6 +308,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
@@ -325,6 +329,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const char *val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index 8de6fbc..6c89bcb 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -169,6 +169,7 @@ private slots:
void nativeFunctionScopes();
void evaluateProgram();
void collectGarbageAfterConnect();
+ void collectGarbageAfterNativeArguments();
void promoteThisObjectToQObjectInConstructor();
void qRegExpInport_data();
@@ -5040,6 +5041,16 @@ void tst_QScriptEngine::collectGarbageAfterConnect()
QVERIFY(widget == 0);
}
+void tst_QScriptEngine::collectGarbageAfterNativeArguments()
+{
+ // QTBUG-17788
+ QScriptEngine eng;
+ QScriptContext *ctx = eng.pushContext();
+ QScriptValue arguments = ctx->argumentsObject();
+ // Shouldn't crash when marking the arguments object.
+ collectGarbage_helper(eng);
+}
+
static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng)
{
Q_ASSERT(ctx->isCalledAsConstructor());