diff options
Diffstat (limited to 'src/script')
-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 | ||||
-rw-r--r-- | src/script/bridge/qscriptactivationobject.cpp | 6 | ||||
-rw-r--r-- | src/script/bridge/qscriptactivationobject_p.h | 2 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject.cpp | 8 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject_p.h | 5 | ||||
-rw-r--r-- | src/script/bridge/qscriptglobalobject.cpp | 28 | ||||
-rw-r--r-- | src/script/bridge/qscriptglobalobject_p.h | 31 | ||||
-rw-r--r-- | src/script/bridge/qscriptobject.cpp | 33 | ||||
-rw-r--r-- | src/script/bridge/qscriptobject_p.h | 15 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 109 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject_p.h | 20 | ||||
-rw-r--r-- | src/script/bridge/qscriptvariant.cpp | 5 | ||||
-rw-r--r-- | src/script/bridge/qscriptvariant_p.h | 4 | ||||
-rw-r--r-- | src/script/script.pro | 31 |
18 files changed, 265 insertions, 217 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) { diff --git a/src/script/bridge/qscriptactivationobject.cpp b/src/script/bridge/qscriptactivationobject.cpp index fea8f44..7982982 100644 --- a/src/script/bridge/qscriptactivationobject.cpp +++ b/src/script/bridge/qscriptactivationobject.cpp @@ -88,13 +88,13 @@ bool QScriptActivationObject::getPropertyAttributes(JSC::ExecState* exec, const return JSC::JSVariableObject::getPropertyAttributes(exec, propertyName, attributes); } -void QScriptActivationObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +void QScriptActivationObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable) { if (d_ptr()->delegate != 0) { - d_ptr()->delegate->getPropertyNames(exec, propertyNames, listedAttributes); + d_ptr()->delegate->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); return; } - return JSC::JSVariableObject::getPropertyNames(exec, propertyNames, listedAttributes); + return JSC::JSVariableObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } void QScriptActivationObject::putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes) diff --git a/src/script/bridge/qscriptactivationobject_p.h b/src/script/bridge/qscriptactivationobject_p.h index f45845d..f313f90 100644 --- a/src/script/bridge/qscriptactivationobject_p.h +++ b/src/script/bridge/qscriptactivationobject_p.h @@ -70,7 +70,7 @@ public: virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, bool includeNonEnumerable = false); virtual void putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes); virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&); diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index c1e386b..0d88532 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -188,9 +188,9 @@ bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs); } -void ClassObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState *exec, - JSC::PropertyNameArray &propertyNames, - unsigned listedAttributes) +void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, + JSC::PropertyNameArray &propertyNames, + bool includeNonEnumerable) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); @@ -204,7 +204,7 @@ void ClassObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState } delete it; } - QScriptObjectDelegate::getPropertyNames(object, exec, propertyNames, listedAttributes); + QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); } JSC::CallType ClassObjectDelegate::getCallData(QScriptObject*, JSC::CallData &callData) diff --git a/src/script/bridge/qscriptclassobject_p.h b/src/script/bridge/qscriptclassobject_p.h index 253e406..f5cce76 100644 --- a/src/script/bridge/qscriptclassobject_p.h +++ b/src/script/bridge/qscriptclassobject_p.h @@ -87,8 +87,9 @@ public: virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, - JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); + virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, + JSC::PropertyNameArray&, + bool includeNonEnumerable = false); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, diff --git a/src/script/bridge/qscriptglobalobject.cpp b/src/script/bridge/qscriptglobalobject.cpp index 17a96c3..c624a31 100644 --- a/src/script/bridge/qscriptglobalobject.cpp +++ b/src/script/bridge/qscriptglobalobject.cpp @@ -68,12 +68,11 @@ GlobalObject::~GlobalObject() { } -void GlobalObject::mark() +void GlobalObject::markChildren(JSC::MarkStack& markStack) { - Q_ASSERT(!marked()); - JSC::JSGlobalObject::mark(); - if (customGlobalObject && !customGlobalObject->marked()) - customGlobalObject->mark(); + JSC::JSGlobalObject::markChildren(markStack); + if (customGlobalObject) + markStack.append(customGlobalObject); } bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec, @@ -125,28 +124,29 @@ bool GlobalObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identi return JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); } -void GlobalObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +void GlobalObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, + bool includeNonEnumerable) { if (customGlobalObject) - customGlobalObject->getPropertyNames(exec, propertyNames, listedAttributes); + customGlobalObject->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); else - JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } -void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) +void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes) { if (customGlobalObject) - customGlobalObject->defineGetter(exec, propertyName, getterFunction); + customGlobalObject->defineGetter(exec, propertyName, getterFunction, attributes); else - JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); + JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction, attributes); } -void GlobalObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) +void GlobalObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes) { if (customGlobalObject) - customGlobalObject->defineSetter(exec, propertyName, setterFunction); + customGlobalObject->defineSetter(exec, propertyName, setterFunction, attributes); else - JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); + JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction, attributes); } JSC::JSValue GlobalObject::lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) diff --git a/src/script/bridge/qscriptglobalobject_p.h b/src/script/bridge/qscriptglobalobject_p.h index 70458a7..01784c2 100644 --- a/src/script/bridge/qscriptglobalobject_p.h +++ b/src/script/bridge/qscriptglobalobject_p.h @@ -68,7 +68,7 @@ public: GlobalObject(); virtual ~GlobalObject(); virtual JSC::UString className() const { return "global"; } - virtual void mark(); + virtual void markChildren(JSC::MarkStack&); virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); @@ -81,10 +81,10 @@ public: bool checkDontDelete = true); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, - unsigned listedAttributes = JSC::Structure::Prototype); - virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); - virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, + bool includeNonEnumerable = false); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes = 0); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes = 0); virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); @@ -103,12 +103,10 @@ public: {} virtual JSC::UString className() const { return originalGlobalObject->className(); } - virtual void mark() + virtual void markChildren(JSC::MarkStack& markStack) { - Q_ASSERT(!marked()); - if (!originalGlobalObject->marked()) - originalGlobalObject->JSC::JSGlobalObject::mark(); - JSC::JSObject::mark(); + markStack.append(originalGlobalObject); + JSC::JSObject::markChildren(markStack); } virtual bool getOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, @@ -125,13 +123,12 @@ public: virtual bool getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, unsigned& attributes) const { return originalGlobalObject->JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); } - virtual void getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, - unsigned listedAttributes = JSC::Structure::Prototype) - { originalGlobalObject->JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); } - virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) - { originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); } - virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) - { originalGlobalObject->JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); } + virtual void getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable = false) + { originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } + virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes) + { originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction, attributes); } + virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes) + { originalGlobalObject->JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction, attributes); } virtual JSC::JSValue lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) { return originalGlobalObject->JSC::JSGlobalObject::lookupGetter(exec, propertyName); } virtual JSC::JSValue lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) diff --git a/src/script/bridge/qscriptobject.cpp b/src/script/bridge/qscriptobject.cpp index 0807dc2..0d899f8 100644 --- a/src/script/bridge/qscriptobject.cpp +++ b/src/script/bridge/qscriptobject.cpp @@ -136,13 +136,14 @@ bool QScriptObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Ident return d->delegate->getPropertyAttributes(this, exec, propertyName, attributes); } -void QScriptObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +void QScriptObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, + bool includeNonEnumerable) { if (!d || !d->delegate) { - JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); return; } - d->delegate->getPropertyNames(this, exec, propertyNames, listedAttributes); + d->delegate->getOwnPropertyNames(this, exec, propertyNames, includeNonEnumerable); } bool QScriptObject::compareToObject(JSC::ExecState* exec, JSC::JSObject *other) @@ -153,22 +154,20 @@ bool QScriptObject::compareToObject(JSC::ExecState* exec, JSC::JSObject *other) return d->delegate->compareToObject(this, exec, other); } - -void QScriptObject::mark() +void QScriptObject::markChildren(JSC::MarkStack& markStack) { - Q_ASSERT(!marked()); if (!d) d = new Data(); if (d->isMarking) return; QBoolBlocker markBlocker(d->isMarking, true); - if (d && d->data && !d->data.marked()) - d->data.mark(); + if (d && d->data) + markStack.append(d->data); if (!d || !d->delegate) { - JSC::JSObject::mark(); + JSC::JSObject::markChildren(markStack); return; } - d->delegate->mark(this); + d->delegate->markChildren(this, markStack); } JSC::CallType QScriptObject::getCallData(JSC::CallData &data) @@ -235,17 +234,17 @@ bool QScriptObjectDelegate::getPropertyAttributes(const QScriptObject* object, return object->JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); } -void QScriptObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState* exec, - JSC::PropertyNameArray& propertyNames, - unsigned listedAttributes) +void QScriptObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState* exec, + JSC::PropertyNameArray& propertyNames, + bool includeNonEnumerable) { - object->JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + object->JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } -void QScriptObjectDelegate::mark(QScriptObject* object) +void QScriptObjectDelegate::markChildren(QScriptObject* object, JSC::MarkStack& markStack) { - if (!object->marked()) - object->JSC::JSObject::mark(); + // ### should this call the virtual function instead?? + object->JSC::JSObject::markChildren(markStack); } JSC::CallType QScriptObjectDelegate::getCallData(QScriptObject* object, JSC::CallData& data) diff --git a/src/script/bridge/qscriptobject_p.h b/src/script/bridge/qscriptobject_p.h index 8060914..c1cee31 100644 --- a/src/script/bridge/qscriptobject_p.h +++ b/src/script/bridge/qscriptobject_p.h @@ -88,11 +88,13 @@ public: bool checkDontDelete = true); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); - virtual void mark(); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, + bool includeNonEnumerable = false); + virtual void markChildren(JSC::MarkStack& markStack); virtual JSC::CallType getCallData(JSC::CallData&); virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual bool hasInstance(JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); + virtual bool compareToObject(JSC::ExecState*, JSC::JSObject*); virtual const JSC::ClassInfo* classInfo() const { return &info; } static const JSC::ClassInfo info; @@ -108,8 +110,6 @@ public: QScriptObjectDelegate *delegate() const; void setDelegate(QScriptObjectDelegate *delegate); - virtual bool compareToObject(JSC::ExecState*, JSC::JSObject*); - protected: Data *d; }; @@ -145,14 +145,13 @@ public: bool checkDontDelete = true); virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - unsigned listedAttributes = JSC::Structure::Prototype); - virtual void mark(QScriptObject*); + virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, + bool includeNonEnumerable = false); + virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&); virtual bool hasInstance(QScriptObject*, JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); - virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); private: diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 236f899..345489f 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -99,11 +99,12 @@ struct QObjectConnection return (s == slot); } - void mark() + void mark(JSC::MarkStack& markStack) { - if (senderWrapper && !senderWrapper.marked()) { + // ### need to find out if senderWrapper is marked + if (senderWrapper) { // see if the sender should be marked or not - Q_ASSERT(senderWrapper.isObject(&QScriptObject::info)); + Q_ASSERT(senderWrapper.inherits(&QScriptObject::info)); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper)); QScriptObjectDelegate *delegate = scriptObject->delegate(); Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); @@ -111,15 +112,17 @@ struct QObjectConnection if ((inst->ownership() == QScriptEngine::ScriptOwnership) || ((inst->ownership() == QScriptEngine::AutoOwnership) && inst->value() && !inst->value()->parent())) { - senderWrapper = JSC::JSValue(); + // #### don't mark if not marked otherwise + //senderWrapper = JSC::JSValue(); + markStack.append(senderWrapper); } else { - senderWrapper.mark(); + markStack.append(senderWrapper); } } - if (receiver && !receiver.marked()) - receiver.mark(); - if (slot && !slot.marked()) - slot.mark(); + if (receiver) + markStack.append(receiver); + if (slot) + markStack.append(slot); } }; @@ -154,7 +157,7 @@ public: void execute(int slotIndex, void **argv); - void mark(); + void mark(JSC::MarkStack&); private: QScriptEnginePrivate *engine; @@ -264,12 +267,11 @@ JSC::CallType QtFunction::getCallData(JSC::CallData &callData) return JSC::CallTypeHost; } -void QtFunction::mark() +void QtFunction::markChildren(JSC::MarkStack& markStack) { - Q_ASSERT(!marked()); - if (data->object && !data->object.marked()) - data->object.mark(); - JSC::InternalFunction::mark(); + if (data->object) + markStack.append(data->object); + JSC::InternalFunction::markChildren(markStack); } QScriptObject *QtFunction::wrapperObject() const @@ -988,7 +990,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, const JSC::ArgList &scriptArgs) { - Q_ASSERT(data->object.isObject(&QScriptObject::info)); + Q_ASSERT(data->object.inherits(&QScriptObject::info)); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(data->object)); QScriptObjectDelegate *delegate = scriptObject->delegate(); Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); @@ -999,7 +1001,7 @@ JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, const QMetaObject *meta = qobj->metaObject(); QObject *thisQObject = 0; thisValue = engine->toUsableValue(thisValue); - if (thisValue.isObject(&QScriptObject::info)) { + if (thisValue.inherits(&QScriptObject::info)) { delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); if (delegate && (delegate->type() == QScriptObjectDelegate::QtObject)) thisQObject = static_cast<QScript::QObjectDelegate*>(delegate)->value(); @@ -1511,9 +1513,9 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes); } -void QObjectDelegate::getPropertyNames(QScriptObject *object, JSC::ExecState *exec, - JSC::PropertyNameArray &propertyNames, - unsigned listedAttributes) +void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec, + JSC::PropertyNameArray &propertyNames, + bool includeNonEnumerable) { QObject *qobject = data->value; if (!qobject) { @@ -1557,24 +1559,24 @@ void QObjectDelegate::getPropertyNames(QScriptObject *object, JSC::ExecState *ex } } - QScriptObjectDelegate::getPropertyNames(object, exec, propertyNames, listedAttributes); + QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); } -void QObjectDelegate::mark(QScriptObject *object) +void QObjectDelegate::markChildren(QScriptObject *object, JSC::MarkStack& markStack) { QHash<QByteArray, JSC::JSValue>::const_iterator it; for (it = data->cachedMembers.constBegin(); it != data->cachedMembers.constEnd(); ++it) { JSC::JSValue val = it.value(); - if (val && !val.marked()) - val.mark(); + if (val) + markStack.append(val); } - QScriptObjectDelegate::mark(object); + QScriptObjectDelegate::markChildren(object, markStack); } bool QObjectDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JSC::JSObject *o2) { - if(!o2->inherits(&QScriptObject::info)) + if (!o2->inherits(&QScriptObject::info)) return false; QScriptObject *object = static_cast<QScriptObject*>(o2); QScriptObjectDelegate *delegate = object->delegate(); @@ -1583,13 +1585,12 @@ bool QObjectDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JSC return value() == static_cast<QObjectDelegate *>(delegate)->value(); } - static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue thisValue, const JSC::ArgList &args) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - if (!thisValue.isObject(&QScriptObject::info)) + if (!thisValue.inherits(&QScriptObject::info)) return throwError(exec, JSC::TypeError, "this object is not a QObject"); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); QScriptObjectDelegate *delegate = scriptObject->delegate(); @@ -1610,7 +1611,7 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *e QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); // extract the QObject - if (!thisValue.isObject(&QScriptObject::info)) + if (!thisValue.inherits(&QScriptObject::info)) return throwError(exec, JSC::TypeError, "this object is not a QObject"); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); QScriptObjectDelegate *delegate = scriptObject->delegate(); @@ -1622,7 +1623,7 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *e QList<QObject *> children; if (args.size() != 0) { const JSC::JSValue arg = args.at(0); - if (arg.isObject(&JSC::RegExpObject::info)) { + if (arg.inherits(&JSC::RegExpObject::info)) { const QObjectList allChildren= obj->children(); JSC::RegExpObject *const regexp = JSC::asRegExpObject(arg); @@ -1662,7 +1663,7 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncToString(JSC::ExecState *exec, { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - if (!thisValue.isObject(&QScriptObject::info)) + if (!thisValue.inherits(&QScriptObject::info)) return JSC::jsUndefined(); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); QScriptObjectDelegate *delegate = scriptObject->delegate(); @@ -1807,7 +1808,9 @@ bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); } -void QMetaObjectWrapperObject::getPropertyNames(JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, unsigned listedAttributes) +void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec, + JSC::PropertyNameArray &propertyNames, + bool includeNonEnumerable) { const QMetaObject *meta = data->value; if (!meta) @@ -1817,17 +1820,16 @@ void QMetaObjectWrapperObject::getPropertyNames(JSC::ExecState *exec, JSC::Prope for (int j = 0; j < e.keyCount(); ++j) propertyNames.add(JSC::Identifier(exec, e.key(j))); } - JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } -void QMetaObjectWrapperObject::mark() +void QMetaObjectWrapperObject::markChildren(JSC::MarkStack& markStack) { - Q_ASSERT(!marked()); - if (data->ctor && !data->ctor.marked()) - data->ctor.mark(); - if (data->prototype && !data->prototype.marked()) - data->prototype.mark(); - JSC::JSObject::mark(); + if (data->ctor) + markStack.append(data->ctor); + if (data->prototype) + markStack.append(data->prototype); + JSC::JSObject::markChildren(markStack); } JSC::CallType QMetaObjectWrapperObject::getCallData(JSC::CallData& callData) @@ -1883,12 +1885,12 @@ JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec, JSC::CallType callType = data->ctor.getCallData(callData); Q_UNUSED(callType); Q_ASSERT_X(callType == JSC::CallTypeHost, Q_FUNC_INFO, "script constructors not supported"); - if (data->ctor.isObject(&FunctionWithArgWrapper::info)) { + if (data->ctor.inherits(&FunctionWithArgWrapper::info)) { FunctionWithArgWrapper *wrapper = static_cast<FunctionWithArgWrapper*>(JSC::asObject(data->ctor)); QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p), wrapper->arg()); return eng_p->scriptValueToJSCValue(result); } else { - Q_ASSERT(data->ctor.isObject(&FunctionWrapper::info)); + Q_ASSERT(data->ctor.inherits(&FunctionWrapper::info)); FunctionWrapper *wrapper = static_cast<FunctionWrapper*>(JSC::asObject(data->ctor)); QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p)); return eng_p->scriptValueToJSCValue(result); @@ -1899,7 +1901,7 @@ JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec, JSC::JSValue result = callQtMethod(exec, QMetaMethod::Constructor, /*thisQObject=*/0, args, meta, meta->constructorCount()-1, /*maybeOverloaded=*/true); if (!exec->hadException()) { - Q_ASSERT(result && result.isObject(&QScriptObject::info)); + Q_ASSERT(result && result.inherits(&QScriptObject::info)); QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(result)); QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(object->delegate()); delegate->setOwnership(QScriptEngine::AutoOwnership); @@ -1926,7 +1928,7 @@ static JSC::JSValue JSC_HOST_CALL qmetaobjectProtoFuncClassName( { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - if (!thisValue.isObject(&QMetaObjectWrapperObject::info)) + if (!thisValue.inherits(&QMetaObjectWrapperObject::info)) return throwError(exec, JSC::TypeError, "this object is not a QMetaObject"); const QMetaObject *meta = static_cast<QMetaObjectWrapperObject*>(JSC::asObject(thisValue))->value(); return JSC::jsString(exec, meta->className()); @@ -2060,7 +2062,7 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue senderObject; - if (senderWrapper && senderWrapper.isObject(&QScriptObject::info)) // ### check if it's actually a QObject wrapper + if (senderWrapper && senderWrapper.inherits(&QScriptObject::info)) // ### check if it's actually a QObject wrapper senderObject = senderWrapper; else { QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; @@ -2093,12 +2095,12 @@ QObjectConnectionManager::~QObjectConnectionManager() { } -void QObjectConnectionManager::mark() +void QObjectConnectionManager::mark(JSC::MarkStack& markStack) { for (int i = 0; i < connections.size(); ++i) { QVector<QObjectConnection> &cs = connections[i]; for (int j = 0; j < cs.size(); ++j) - cs[j].mark(); + cs[j].mark(markStack); } } @@ -2162,19 +2164,18 @@ QObjectData::~QObjectData() } } -void QObjectData::mark() +void QObjectData::mark(JSC::MarkStack& markStack) { if (connectionManager) - connectionManager->mark(); + connectionManager->mark(markStack); { QList<QScript::QObjectWrapperInfo>::iterator it; for (it = wrappers.begin(); it != wrappers.end(); ) { const QScript::QObjectWrapperInfo &info = *it; - if (info.object->marked()) { - ++it; - } else { - it = wrappers.erase(it); - } + // ### don't mark if there are no other references. + // we need something like isMarked() + markStack.append(info.object); + ++it; } } } diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h index 72d066d..2d482cc 100644 --- a/src/script/bridge/qscriptqobject_p.h +++ b/src/script/bridge/qscriptqobject_p.h @@ -105,9 +105,11 @@ public: virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - unsigned listedAttributes = JSC::Structure::Prototype); - virtual void mark(QScriptObject*); + virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, + JSC::PropertyNameArray&, + bool includeNonEnumerable = false); + virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack); + virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); inline QObject *value() const { return data->value; } inline void setValue(QObject* value) { data->value = value; } @@ -122,8 +124,6 @@ public: inline void setOptions(QScriptEngine::QObjectWrapOptions options) { data->options = options; } - virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); - protected: Data *data; }; @@ -181,7 +181,7 @@ public: QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options); - void mark(); + void mark(JSC::MarkStack&); private: QScriptEnginePrivate *engine; @@ -208,7 +208,7 @@ public: virtual ~QtFunction(); virtual JSC::CallType getCallData(JSC::CallData&); - virtual void mark(); + virtual void markChildren(JSC::MarkStack&); virtual const JSC::ClassInfo* classInfo() const { return &info; } static const JSC::ClassInfo info; @@ -297,9 +297,9 @@ public: bool checkDontDelete = true); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, - unsigned listedAttributes = JSC::Structure::Prototype); - virtual void mark(); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, + bool includeNonEnumerable = false); + virtual void markChildren(JSC::MarkStack& markStack); virtual JSC::CallType getCallData(JSC::CallData&); virtual JSC::ConstructType getConstructData(JSC::ConstructData&); diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp index aa7ad94..725f4e0 100644 --- a/src/script/bridge/qscriptvariant.cpp +++ b/src/script/bridge/qscriptvariant.cpp @@ -89,7 +89,7 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncValueOf(JSC::ExecState *exec, { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - if (!thisValue.isObject(&QScriptObject::info)) + if (!thisValue.inherits(&QScriptObject::info)) return throwError(exec, JSC::TypeError); QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); if (!delegate || (delegate->type() != QScriptObjectDelegate::Variant)) @@ -127,7 +127,7 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec, { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - if (!thisValue.isObject(&QScriptObject::info)) + if (!thisValue.inherits(&QScriptObject::info)) return throwError(exec, JSC::TypeError, "This object is not a QVariant"); QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); if (!delegate || (delegate->type() != QScriptObjectDelegate::Variant)) @@ -154,7 +154,6 @@ bool QVariantDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JS return variant1 == scriptEngineFromExec(exec)->scriptValueFromJSCValue(o2).toVariant(); } - QVariantPrototype::QVariantPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure, JSC::Structure* prototypeFunctionStructure) : QScriptObject(structure) diff --git a/src/script/bridge/qscriptvariant_p.h b/src/script/bridge/qscriptvariant_p.h index 4ce0aa6..445ca69 100644 --- a/src/script/bridge/qscriptvariant_p.h +++ b/src/script/bridge/qscriptvariant_p.h @@ -68,13 +68,13 @@ public: QVariantDelegate(const QVariant &value); ~QVariantDelegate(); + virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); + QVariant &value(); void setValue(const QVariant &value); Type type() const; - bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); - private: QVariant m_value; }; diff --git a/src/script/script.pro b/src/script/script.pro index c844d89..6c6b701 100644 --- a/src/script/script.pro +++ b/src/script/script.pro @@ -11,8 +11,7 @@ unix:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) -# Disable a few warnings on Windows. -win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4503 -wd4800 -wd4819 -wd4996 -wd4396 -wd4099 +CONFIG += building-libs # FIXME: shared the statically built JavaScriptCore @@ -21,25 +20,16 @@ win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4503 -wd4800 -wd4819 -wd4996 - WEBKITDIR = $$(WEBKITDIR) isEmpty(WEBKITDIR) { WEBKITDIR = $$PWD/../3rdparty/javascriptcore - - # FIXME: not needed once JSCBISON works - # TODO: or leave it like this since the generated file is available anyway? - SOURCES += $$WEBKITDIR/JavaScriptCore/generated/Grammar.cpp - - # avoid warnings when parsing JavaScriptCore.pri - # (we don't care about generating files, we already have them generated) - defineTest(addExtraCompiler) { - return(true) - } - defineTest(addExtraCompilerWithHeader) { - return(true) - } + GENERATED_SOURCES_DIR = generated } else { message(using external WebKit from $$WEBKITDIR) - CONFIG += building-libs CONFIG -= QTDIR_build - include($$WEBKITDIR/WebKit.pri) } +include($$WEBKITDIR/WebKit.pri) + +# Disable a few warnings on Windows. +# These are in addition to the ones disabled in WebKit.pri +win32-msvc*: QMAKE_CXXFLAGS += -wd4396 -wd4099 # Windows CE-specific stuff copied from WebCore.pro # ### Should rather be in JavaScriptCore.pri? @@ -67,10 +57,9 @@ INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/bytecode INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/assembler INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/generated -DEFINES += BUILDING_QT__=1 -DEFINES += USE_SYSTEM_MALLOC -DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 -DEFINES += WTF_CHANGES=1 +# This line copied from WebCore.pro +DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1 + DEFINES += NDEBUG INCLUDEPATH += $$PWD |