diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-09-24 14:35:49 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-09-24 15:36:17 (GMT) |
commit | aabd12223bda6260756ab19430082477d5669c0a (patch) | |
tree | 6ca7a12e627915992cfd0038f6ddd8ee244711f4 /src/script/api | |
parent | 270c374c178ec5a532d37168b018cd7ebc844558 (diff) | |
download | Qt-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.cpp | 7 | ||||
-rw-r--r-- | src/script/api/qscriptengine.cpp | 136 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 6 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 34 | ||||
-rw-r--r-- | src/script/api/qscriptvalueiterator.cpp | 2 |
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) { |