summaryrefslogtreecommitdiffstats
path: root/src/script/api
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-09-24 14:35:49 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-09-24 15:36:17 (GMT)
commitaabd12223bda6260756ab19430082477d5669c0a (patch)
tree6ca7a12e627915992cfd0038f6ddd8ee244711f4 /src/script/api
parent270c374c178ec5a532d37168b018cd7ebc844558 (diff)
downloadQt-aabd12223bda6260756ab19430082477d5669c0a.zip
Qt-aabd12223bda6260756ab19430082477d5669c0a.tar.gz
Qt-aabd12223bda6260756ab19430082477d5669c0a.tar.bz2
Update src/3rdparty/javascriptcore and adapt src/script to the changes.
Reviewed-by: Simon Hausmann
Diffstat (limited to 'src/script/api')
-rw-r--r--src/script/api/qscriptcontextinfo.cpp7
-rw-r--r--src/script/api/qscriptengine.cpp136
-rw-r--r--src/script/api/qscriptengine_p.h6
-rw-r--r--src/script/api/qscriptvalue.cpp34
-rw-r--r--src/script/api/qscriptvalueiterator.cpp2
5 files changed, 124 insertions, 61 deletions
diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp
index ba295cf..6c34c5e 100644
--- a/src/script/api/qscriptcontextinfo.cpp
+++ b/src/script/api/qscriptcontextinfo.cpp
@@ -202,12 +202,11 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte
functionName = JSC::asInternalFunction(callee)->name(&frame->globalData());
if (callee && callee->inherits(&JSC::JSFunction::info)) {
functionType = QScriptContextInfo::ScriptFunction;
- JSC::FunctionBodyNode *body = JSC::asFunction(callee)->body();
- functionStartLineNumber = body->firstLine();
+ JSC::FunctionExecutable *body = JSC::asFunction(callee)->jsExecutable();
+ functionStartLineNumber = body->lineNo();
functionEndLineNumber = body->lastLine();
- const JSC::Identifier* params = body->parameters();
for (size_t i = 0; i < body->parameterCount(); ++i)
- parameterNames.append(params[i].ustring());
+ parameterNames.append(body->parameterName(i));
// ### get the function name from the AST
} else if (callee && callee->inherits(&QScript::QtFunction::info)) {
functionType = QScriptContextInfo::QtFunction;
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 71194d3..78bbf5f 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -348,7 +348,7 @@ struct GlobalClientData : public JSC::JSGlobalData::ClientData
GlobalClientData(QScriptEnginePrivate *e)
: engine(e) {}
virtual ~GlobalClientData() {}
- virtual void mark() { engine->mark(); }
+ virtual void mark(JSC::MarkStack& markStack) { engine->mark(markStack); }
QScriptEnginePrivate *engine;
};
@@ -382,6 +382,65 @@ private:
bool m_shouldAbortEvaluation;
};
+/*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
+ It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update
+ this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/
+class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider
+{
+public:
+
+ static PassRefPtr<UStringSourceProviderWithFeedback> create(const JSC::UString& source, const JSC::UString& url, int lineNumber, QScriptEnginePrivate* engine)
+ {
+ return adoptRef(new UStringSourceProviderWithFeedback(source, url, lineNumber, engine));
+ }
+
+ /* Destruction means that there is no more copies of script so create scriptUnload event
+ and unregister script in QScriptEnginePrivate::loadedScripts */
+ virtual ~UStringSourceProviderWithFeedback()
+ {
+ if (m_ptr) {
+ if (JSC::Debugger* debugger = this->debugger())
+ debugger->scriptUnload(asID());
+ m_ptr->loadedScripts.remove(this);
+ }
+ }
+
+ /* set internal QScriptEnginePrivate pointer to null and create unloadScript event, should be called
+ only if QScriptEnginePrivate is about to be destroyed.*/
+ void disconnectFromEngine()
+ {
+ if (JSC::Debugger* debugger = this->debugger())
+ debugger->scriptUnload(asID());
+ m_ptr = 0;
+ }
+
+protected:
+ UStringSourceProviderWithFeedback(const JSC::UString& source, const JSC::UString& url, int lineNumber, QScriptEnginePrivate* engine)
+ : UStringSourceProvider(source, url),
+ m_ptr(engine)
+ {
+ if (JSC::Debugger* debugger = this->debugger())
+ debugger->scriptLoad(asID(), source, url, lineNumber);
+ if (m_ptr)
+ m_ptr->loadedScripts.insert(this);
+ }
+
+ JSC::Debugger* debugger()
+ {
+ //if m_ptr is null it mean that QScriptEnginePrivate was destroyed and scriptUnload was called
+ //else m_ptr is stable and we can use it as normal pointer without hesitation
+ if(!m_ptr)
+ return 0; //we are in ~QScriptEnginePrivate
+ else
+ return m_ptr->originalGlobalObject()->debugger(); //QScriptEnginePrivate is still alive
+ }
+
+ //trace global object and debugger instance
+ QScriptEnginePrivate* m_ptr;
+};
+
+
+
static int toDigit(char c)
{
if ((c >= '0') && (c <= '9'))
@@ -840,8 +899,16 @@ QScriptEnginePrivate::QScriptEnginePrivate()
QScriptEnginePrivate::~QScriptEnginePrivate()
{
+ //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
+ QSet<QScript::UStringSourceProviderWithFeedback*>::const_iterator i = loadedScripts.constBegin();
+ while(i!=loadedScripts.constEnd()) {
+ (*i)->disconnectFromEngine();
+ i++;
+ }
+
while (!ownedAgents.isEmpty())
delete ownedAgents.takeFirst();
+
detachAllRegisteredScriptValues();
detachAllRegisteredScriptStrings();
qDeleteAll(m_qobjectData);
@@ -1115,27 +1182,25 @@ void QScriptEnginePrivate::setContextFlags(JSC::ExecState *exec, uint flags)
}
-void QScriptEnginePrivate::mark()
+void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
{
- if (!originalGlobalObject()->marked())
- originalGlobalObject()->mark();
- if (!globalObject()->marked())
- globalObject()->mark();
- if (originalGlobalObjectProxy && !originalGlobalObjectProxy->marked())
- originalGlobalObjectProxy->mark();
+ markStack.append(originalGlobalObject());
+ markStack.append(globalObject());
+ if (originalGlobalObjectProxy)
+ markStack.append(originalGlobalObjectProxy);
- if (qobjectPrototype && !qobjectPrototype->marked())
- qobjectPrototype->mark();
- if (qmetaobjectPrototype && !qmetaobjectPrototype->marked())
- qmetaobjectPrototype->mark();
- if (variantPrototype && !variantPrototype->marked())
- variantPrototype->mark();
+ if (qobjectPrototype)
+ markStack.append(qobjectPrototype);
+ if (qmetaobjectPrototype)
+ markStack.append(qmetaobjectPrototype);
+ if (variantPrototype)
+ markStack.append(variantPrototype);
{
QScriptValuePrivate *it;
for (it = registeredScriptValues; it != 0; it = it->next) {
- if (it->isJSC() && !it->jscValue.marked())
- it->jscValue.mark();
+ if (it->isJSC())
+ markStack.append(it->jscValue);
}
}
@@ -1144,7 +1209,7 @@ void QScriptEnginePrivate::mark()
QHash<QObject*, QScript::QObjectData*>::const_iterator it;
for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
QScript::QObjectData *qdata = it.value();
- qdata->mark();
+ qdata->mark(markStack);
}
}
#endif
@@ -1152,8 +1217,8 @@ void QScriptEnginePrivate::mark()
{
QHash<int, QScriptTypeInfo*>::const_iterator it;
for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) {
- if ((*it)->prototype && !(*it)->prototype.marked())
- (*it)->prototype.mark();
+ if ((*it)->prototype)
+ markStack.append((*it)->prototype);
}
}
}
@@ -2137,6 +2202,7 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra
\sa canEvaluate(), hasUncaughtException(), isEvaluating(), abortEvaluation()
*/
+
QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
{
Q_D(QScriptEngine);
@@ -2145,41 +2211,40 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file
QBoolBlocker inEval(d->inEval, true);
currentContext()->activationObject(); //force the creation of a context for native function;
+ JSC::Debugger* debugger = d->originalGlobalObject()->debugger();
+
JSC::UString jscProgram = program;
JSC::UString jscFileName = fileName;
JSC::ExecState* exec = d->currentFrame;
- JSC::SourceCode source = JSC::makeSource(jscProgram, jscFileName, lineNumber);
+ WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
+ = QScript::UStringSourceProviderWithFeedback::create(jscProgram, jscFileName, lineNumber, d);
+ intptr_t sourceId = provider->asID();
+ JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null.
- intptr_t sourceId = source.provider()->asID();
- JSC::Debugger* debugger = d->originalGlobalObject()->debugger();
- exec->globalData().scriptpool->startEvaluating(source);
if (debugger)
debugger->evaluateStart(sourceId);
exec->clearException();
JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
- int errorLine;
- JSC::UString errorMessage;
- WTF::RefPtr<JSC::EvalNode> evalNode = exec->globalData().parser->parse<JSC::EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage);
- if (!evalNode) {
- JSC::JSValue exceptionValue = JSC::Error::create(exec, JSC::SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0);
- exec->setException(exceptionValue);
+ JSC::EvalExecutable executable(source);
+ JSC::JSObject* error = executable.compile(exec, exec->scopeChain());
+ if (error) {
+ exec->setException(error);
if (debugger) {
- debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, exceptionValue), sourceId, false);
- debugger->evaluateStop(exceptionValue, sourceId);
+ debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false);
+ debugger->evaluateStop(error, sourceId);
}
- exec->globalData().scriptpool->stopEvaluating(source);
- return d->scriptValueFromJSCValue(exceptionValue);
+ return d->scriptValueFromJSCValue(error);
}
JSC::JSValue thisValue = d->thisForContext(exec);
JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
JSC::JSValue exceptionValue;
d->timeoutChecker()->setShouldAbort(false);
- JSC::JSValue result = exec->interpreter()->execute(evalNode.get(), exec, thisObject, exec->scopeChain(), &exceptionValue);
+ JSC::JSValue result = exec->interpreter()->execute(&executable, exec, thisObject, exec->scopeChain(), &exceptionValue);
if (d->timeoutChecker()->shouldAbort()) {
if (d->abortResult.isError())
@@ -2187,7 +2252,6 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file
if (debugger)
debugger->evaluateStop(d->scriptValueToJSCValue(d->abortResult), sourceId);
- exec->globalData().scriptpool->stopEvaluating(source);
return d->abortResult;
}
@@ -2197,14 +2261,12 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file
if (debugger)
debugger->evaluateStop(exceptionValue, sourceId);
- exec->globalData().scriptpool->stopEvaluating(source);
return d->scriptValueFromJSCValue(exceptionValue);
}
if (debugger)
debugger->evaluateStop(result, sourceId);
- exec->globalData().scriptpool->stopEvaluating(source);
Q_ASSERT(!exec->hadException());
return d->scriptValueFromJSCValue(result);
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index ec41cc9..c43ca61 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -100,6 +100,8 @@ namespace QScript
//some conversion helper functions
QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
bool isFunction(JSC::JSValue value);
+
+ class UStringSourceProviderWithFeedback;
}
class QScriptEnginePrivate
@@ -160,7 +162,7 @@ public:
JSC::JSObject *callee, bool calledAsConstructor = false);
void popContext();
- void mark();
+ void mark(JSC::MarkStack& markStack);
bool isCollecting() const;
void collectGarbage();
@@ -255,6 +257,8 @@ public:
QSet<QString> importedExtensions;
QSet<QString> extensionsBeingImported;
+
+ QSet<QScript::UStringSourceProviderWithFeedback*> loadedScripts;
#ifndef QT_NO_QOBJECT
QHash<QObject*, QScript::QObjectData*> m_qobjectData;
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 2a33aea..f2716e4 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -399,7 +399,10 @@ QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identi
JSC::ExecState *exec = engine->currentFrame;
JSC::JSObject *object = JSC::asObject(jscValue);
unsigned attribs = 0;
- if (!object->getPropertyAttributes(exec, id, attribs)) {
+ JSC::PropertyDescriptor descriptor;
+ if (object->getOwnPropertyDescriptor(exec, id, descriptor))
+ attribs = descriptor.attributes();
+ else if (!object->getPropertyAttributes(exec, id, attribs)) {
if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype());
return QScriptValuePrivate::get(proto)->propertyFlags(id, mode);
@@ -426,7 +429,7 @@ QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identi
QVariant &QScriptValuePrivate::variantValue() const
{
- Q_ASSERT(jscValue.isObject(&QScriptObject::info));
+ Q_ASSERT(jscValue.inherits(&QScriptObject::info));
QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
return static_cast<QScript::QVariantDelegate*>(delegate)->value();
@@ -434,7 +437,7 @@ QVariant &QScriptValuePrivate::variantValue() const
void QScriptValuePrivate::setVariantValue(const QVariant &value)
{
- Q_ASSERT(jscValue.isObject(&QScriptObject::info));
+ Q_ASSERT(jscValue.inherits(&QScriptObject::info));
QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
@@ -759,7 +762,7 @@ bool QScriptValue::isError() const
Q_D(const QScriptValue);
if (!d || !d->isObject())
return false;
- return d->jscValue.isObject(&JSC::ErrorInstance::info);
+ return d->jscValue.inherits(&JSC::ErrorInstance::info);
}
/*!
@@ -773,7 +776,7 @@ bool QScriptValue::isArray() const
Q_D(const QScriptValue);
if (!d || !d->isObject())
return false;
- return d->jscValue.isObject(&JSC::JSArray::info);
+ return d->jscValue.inherits(&JSC::JSArray::info);
}
/*!
@@ -787,7 +790,7 @@ bool QScriptValue::isDate() const
Q_D(const QScriptValue);
if (!d || !d->isObject())
return false;
- return d->jscValue.isObject(&JSC::DateInstance::info);
+ return d->jscValue.inherits(&JSC::DateInstance::info);
}
/*!
@@ -801,7 +804,7 @@ bool QScriptValue::isRegExp() const
Q_D(const QScriptValue);
if (!d || !d->isObject())
return false;
- return d->jscValue.isObject(&JSC::RegExpObject::info);
+ return d->jscValue.inherits(&JSC::RegExpObject::info);
}
/*!
@@ -1153,11 +1156,6 @@ bool QScriptValue::equals(const QScriptValue &other) const
QScriptValuePrivate::saveException(exec, &savedException);
bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue);
QScriptValuePrivate::restoreException(exec, savedException);
- // special QtScript rules
- if (!result && isQObject() && other.isQObject())
- result = (toQObject() == other.toQObject());
- else if (!result && isVariant() && other.isVariant())
- result = (toVariant() == other.toVariant());
return result;
}
}
@@ -2264,7 +2262,7 @@ bool QScriptValue::isObject() const
bool QScriptValue::isVariant() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info))
+ if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
return false;
QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
QScriptObjectDelegate *delegate = object->delegate();
@@ -2283,7 +2281,7 @@ bool QScriptValue::isVariant() const
bool QScriptValue::isQObject() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info))
+ if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
return false;
QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
QScriptObjectDelegate *delegate = object->delegate();
@@ -2327,7 +2325,7 @@ QScriptValue QScriptValue::data() const
Q_D(const QScriptValue);
if (!d || !d->isObject())
return QScriptValue();
- if (d->jscValue.isObject(&QScriptObject::info)) {
+ if (d->jscValue.inherits(&QScriptObject::info)) {
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
return d->engine->scriptValueFromJSCValue(scriptObject->data());
} else {
@@ -2350,7 +2348,7 @@ void QScriptValue::setData(const QScriptValue &data)
if (!d || !d->isObject())
return;
JSC::JSValue other = d->engine->scriptValueToJSCValue(data);
- if (d->jscValue.isObject(&QScriptObject::info)) {
+ if (d->jscValue.inherits(&QScriptObject::info)) {
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
scriptObject->setData(other);
} else {
@@ -2376,7 +2374,7 @@ void QScriptValue::setData(const QScriptValue &data)
QScriptClass *QScriptValue::scriptClass() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info))
+ if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
return 0;
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
QScriptObjectDelegate *delegate = scriptObject->delegate();
@@ -2403,7 +2401,7 @@ void QScriptValue::setScriptClass(QScriptClass *scriptClass)
Q_D(QScriptValue);
if (!d || !d->isObject())
return;
- if (!d->jscValue.isObject(&QScriptObject::info)) {
+ if (!d->jscValue.inherits(&QScriptObject::info)) {
qWarning("QScriptValue::setScriptClass() failed: "
"cannot change class of non-QScriptObject");
return;
diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp
index 5bba327..cf27af6 100644
--- a/src/script/api/qscriptvalueiterator.cpp
+++ b/src/script/api/qscriptvalueiterator.cpp
@@ -110,7 +110,7 @@ public:
JSC::ExecState *exec = eng_p->globalExec();
JSC::PropertyNameArray propertyNamesArray(exec);
propertyNamesArray.setShouldCache(false);
- JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getPropertyNames(exec, propertyNamesArray, JSC::Structure::NonEnumerable);
+ JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, /*includeNonEnumerable=*/true);
JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin();
for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) {