summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-09-22 14:56:37 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-09-22 14:59:39 (GMT)
commit77b1f0ab8c8055835a3fc92d784d536efdc6acbf (patch)
treee844d05c320702802f5fd6b041d6085054c9d560
parent5c3c0d477104f6f4eafaceeacac8278c4b97f8cc (diff)
downloadQt-77b1f0ab8c8055835a3fc92d784d536efdc6acbf.zip
Qt-77b1f0ab8c8055835a3fc92d784d536efdc6acbf.tar.gz
Qt-77b1f0ab8c8055835a3fc92d784d536efdc6acbf.tar.bz2
make sure the engine's currentFrame is in sync when calling out to public API
The currentFrame pointer is used e.g. by QScriptValue::toString(). It needs to be in sync, otherwise we will crash. Reviewed-by: Olivier Goffart
-rw-r--r--src/script/api/qscriptengine.cpp2
-rw-r--r--src/script/api/qscriptengine_p.h23
-rw-r--r--src/script/bridge/qscriptclassobject.cpp8
3 files changed, 32 insertions, 1 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 7a910d2..71194d3 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -508,6 +508,7 @@ JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObjec
slot = arg1;
else {
// ### don't go via QScriptValue
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
QString propertyName(arg1.toString(exec));
slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
@@ -591,6 +592,7 @@ JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject *
slot = arg1;
else {
// ### don't go via QScriptValue
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
QString propertyName = arg1.toString(exec);
slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index c7db276..ec41cc9 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -265,6 +265,29 @@ public:
#endif
};
+namespace QScript
+{
+
+class SaveFrameHelper
+{
+public:
+ SaveFrameHelper(QScriptEnginePrivate *eng,
+ JSC::ExecState *newFrame)
+ : engine(eng), oldFrame(eng->currentFrame)
+ {
+ eng->currentFrame = newFrame;
+ }
+ ~SaveFrameHelper()
+ {
+ engine->currentFrame = oldFrame;
+ }
+private:
+ QScriptEnginePrivate *engine;
+ JSC::ExecState *oldFrame;
+};
+
+} // namespace QScript
+
inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
{
if (freeScriptValues) {
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index a5dc670..b57909f 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -90,12 +90,13 @@ bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
const JSC::Identifier &propertyName,
JSC::PropertySlot &slot)
{
+ QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
// for compatibility with the old back-end, normal JS properties
// are queried first.
if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot))
return true;
- QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
QScriptString scriptName;
QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
@@ -116,6 +117,7 @@ void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
JSC::JSValue value, JSC::PutPropertySlot &slot)
{
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
QScriptString scriptName;
QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
@@ -136,6 +138,7 @@ bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *
{
// ### avoid duplication of put()
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
QScriptString scriptName;
QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
@@ -157,6 +160,7 @@ bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC
unsigned &attribs) const
{
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
QScriptString scriptName;
QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
@@ -188,6 +192,7 @@ void ClassObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState
unsigned listedAttributes)
{
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject);
if (it != 0) {
@@ -267,6 +272,7 @@ bool ClassObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exe
return QScriptObjectDelegate::hasInstance(object, exec, value, proto);
QScriptValueList args;
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(eng_p, exec);
args << eng_p->scriptValueFromJSCValue(object) << eng_p->scriptValueFromJSCValue(value);
QVariant result = scriptClass()->extension(QScriptClass::HasInstance, qVariantFromValue(args));
return result.toBool();