diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-10-23 12:45:13 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-10-23 12:45:13 (GMT) |
commit | c21d3a0094b0692f2f888b04e258229234200e3c (patch) | |
tree | f34338ec27f2c4ef5d7294f04d4ab7dac6283f02 /src/script | |
parent | b824fc37d618e55bd128bacebb78dc3770c73264 (diff) | |
download | Qt-c21d3a0094b0692f2f888b04e258229234200e3c.zip Qt-c21d3a0094b0692f2f888b04e258229234200e3c.tar.gz Qt-c21d3a0094b0692f2f888b04e258229234200e3c.tar.bz2 |
Refactor QScriptProgram and related API
Get rid of QScriptEngine::compile(); you pass arguments to
the QScriptProgram constructor instead. evaluate() will lazily
compile the program the first time it is evaluated, then use the
cached, compiled form on subsequent calls.
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 118 | ||||
-rw-r--r-- | src/script/api/qscriptengine.h | 1 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 5 | ||||
-rw-r--r-- | src/script/api/qscriptprogram.cpp | 61 | ||||
-rw-r--r-- | src/script/api/qscriptprogram.h | 7 | ||||
-rw-r--r-- | src/script/api/qscriptprogram_p.h | 21 |
6 files changed, 109 insertions, 104 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 25f815f..9bc4d6b 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1188,9 +1188,36 @@ void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent) } } -QScriptValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, JSC::Debugger* debugger, - intptr_t sourceId, JSC::EvalExecutable *executable) +JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t sourceId, + JSC::EvalExecutable *executable, + bool &compile) { + JSC::JSLock lock(false); // ### hmmm + QBoolBlocker inEvalBlocker(inEval, true); + q_func()->currentContext()->activationObject(); //force the creation of a context for native function; + + JSC::Debugger* debugger = originalGlobalObject()->debugger(); + if (debugger) + debugger->evaluateStart(sourceId); + + exec->clearException(); + JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); + + if (compile) { + JSC::JSObject* error = executable->compile(exec, exec->scopeChain()); + if (error) { + compile = false; + exec->setException(error); + + if (debugger) { + debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false); + debugger->evaluateStop(error, sourceId); + } + + return error; + } + } + JSC::JSValue thisValue = thisForContext(exec); JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec); @@ -1208,7 +1235,7 @@ QScriptValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, JSC::Deb if (debugger) debugger->evaluateStop(scriptValueToJSCValue(abortResult), sourceId); - return abortResult; + return scriptValueToJSCValue(abortResult); } if (exceptionValue) { @@ -1217,14 +1244,14 @@ QScriptValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, JSC::Deb if (debugger) debugger->evaluateStop(exceptionValue, sourceId); - return scriptValueFromJSCValue(exceptionValue); + return exceptionValue; } if (debugger) debugger->evaluateStop(result, sourceId); Q_ASSERT(!exec->hadException()); - return scriptValueFromJSCValue(result); + return result; } #ifndef QT_NO_QOBJECT @@ -2187,66 +2214,15 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber) { Q_D(QScriptEngine); - - JSC::JSLock lock(false); // ### hmmm - QBoolBlocker inEval(d->inEval, true); - currentContext()->activationObject(); //force the creation of a context for native function; - - JSC::UString jscProgram = program; - JSC::UString jscFileName = fileName; - JSC::ExecState* exec = d->currentFrame; WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider - = QScript::UStringSourceProviderWithFeedback::create(jscProgram, jscFileName, lineNumber, d); + = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d); intptr_t sourceId = provider->asID(); JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null. - JSC::Debugger* debugger = d->originalGlobalObject()->debugger(); - if (debugger) - debugger->evaluateStart(sourceId); - - exec->clearException(); - JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); - - JSC::EvalExecutable executable(exec, source); - JSC::JSObject* error = executable.compile(exec, exec->scopeChain()); - if (error) { - exec->setException(error); - - if (debugger) { - debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false); - debugger->evaluateStop(error, sourceId); - } - - return d->scriptValueFromJSCValue(error); - } - - return d->evaluateHelper(exec, debugger, sourceId, &executable); -} - -/*! - \internal - \since 4.6 -*/ -QScriptProgram QScriptEngine::compile(const QString &program, const QString &fileName, int lineNumber) -{ - Q_D(QScriptEngine); - JSC::UString jscProgram = program; - JSC::UString jscFileName = fileName; - WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider - = QScript::UStringSourceProviderWithFeedback::create(jscProgram, jscFileName, lineNumber, d); - JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null. - JSC::ExecState* exec = d->currentFrame; - exec->clearException(); - JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); - - JSC::EvalExecutable *executable = new JSC::EvalExecutable(exec, source); - JSC::JSObject* error = executable->compile(exec, exec->scopeChain()); - if (error != 0) { - delete executable; - return QScriptProgram(); - } - return QScriptProgramPrivate::create(d, executable, provider->asID()); + JSC::EvalExecutable executable(exec, source); + bool compile = true; + return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile)); } /*! @@ -2257,23 +2233,17 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram &program) { Q_D(QScriptEngine); QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program); - if (!program_d || !program_d->engine || !program_d->executable) + if (!program_d) return QScriptValue(); - JSC::JSLock lock(false); - QBoolBlocker inEval(d->inEval, true); - currentContext()->activationObject(); //force the creation of a context for native function; - - intptr_t sourceId = program_d->sourceId; - JSC::Debugger* debugger = d->originalGlobalObject()->debugger(); - if (debugger) - debugger->evaluateStart(sourceId); - JSC::ExecState* exec = d->currentFrame; - exec->clearException(); - JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); - - return d->evaluateHelper(exec, debugger, sourceId, program_d->executable); + JSC::EvalExecutable *executable = program_d->executable(exec, d); + bool compile = !program_d->isCompiled; + JSC::JSValue result = d->evaluateHelper(exec, program_d->sourceId, + executable, compile); + if (compile) + program_d->isCompiled = true; + return d->scriptValueFromJSCValue(result); } /*! diff --git a/src/script/api/qscriptengine.h b/src/script/api/qscriptengine.h index c58bb7c..3f438da 100644 --- a/src/script/api/qscriptengine.h +++ b/src/script/api/qscriptengine.h @@ -167,7 +167,6 @@ public: QScriptValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1); - QScriptProgram compile(const QString &program, const QString &fileName = QString(), int lineNumber = 1); QScriptValue evaluate(const QScriptProgram &program); bool isEvaluating() const; diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index c7e9f2a..22de29c 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -197,8 +197,9 @@ public: const QByteArray &targetType, void **result); - QScriptValue evaluateHelper(JSC::ExecState *exec, JSC::Debugger* debugger, - intptr_t sourceId, JSC::EvalExecutable *executable); + JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId, + JSC::EvalExecutable *executable, + bool &compile); QScript::QObjectData *qobjectData(QObject *object); void disposeQObject(QObject *object); diff --git a/src/script/api/qscriptprogram.cpp b/src/script/api/qscriptprogram.cpp index 9f88363..3ea4fa7 100644 --- a/src/script/api/qscriptprogram.cpp +++ b/src/script/api/qscriptprogram.cpp @@ -58,17 +58,18 @@ QT_BEGIN_NAMESPACE */ -QScriptProgramPrivate::QScriptProgramPrivate(QScriptEnginePrivate *e, - JSC::EvalExecutable *x, - intptr_t id) - : engine(e), executable(x), sourceId(id) +QScriptProgramPrivate::QScriptProgramPrivate(const QString &src, + const QString &fn, + int ln) + : sourceCode(src), fileName(fn), lineNumber(ln), + engine(0), _executable(0), sourceId(-1), isCompiled(false) { ref = 0; } QScriptProgramPrivate::~QScriptProgramPrivate() { - delete executable; + delete _executable; } QScriptProgramPrivate *QScriptProgramPrivate::get(const QScriptProgram &q) @@ -76,18 +77,26 @@ QScriptProgramPrivate *QScriptProgramPrivate::get(const QScriptProgram &q) return const_cast<QScriptProgramPrivate*>(q.d_func()); } -QScriptProgram QScriptProgramPrivate::create(QScriptEnginePrivate *engine, - JSC::EvalExecutable *executable, - intptr_t sourceId) +JSC::EvalExecutable *QScriptProgramPrivate::executable(JSC::ExecState *exec, + QScriptEnginePrivate *eng) { - QScriptProgramPrivate *d = new QScriptProgramPrivate(engine, executable, sourceId); - QScriptProgram result; - result.d_ptr = d; - return result; + if (_executable) { + if (eng == engine) + return _executable; + delete _executable; + } + WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider + = QScript::UStringSourceProviderWithFeedback::create(sourceCode, fileName, lineNumber, eng); + sourceId = provider->asID(); + JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null. + _executable = new JSC::EvalExecutable(exec, source); + engine = eng; + isCompiled = false; + return _executable; } /*! - Constructs an invalid QScriptProgram. + Constructs a null QScriptProgram. */ QScriptProgram::QScriptProgram() : d_ptr(0) @@ -95,6 +104,17 @@ QScriptProgram::QScriptProgram() } /*! + Constructs a new QScriptProgram with the given \a sourceCode, \a + fileName and \a lineNumber. +*/ +QScriptProgram::QScriptProgram(const QString &sourceCode, + const QString fileName, + int lineNumber) + : d_ptr(new QScriptProgramPrivate(sourceCode, fileName, lineNumber)) +{ +} + +/*! Constructs a new QScriptProgram that is a copy of \a other. */ QScriptProgram::QScriptProgram(const QScriptProgram &other) @@ -125,13 +145,13 @@ QScriptProgram &QScriptProgram::operator=(const QScriptProgram &other) } /*! - Returns true if this QScriptProgram is valid; otherwise + Returns true if this QScriptProgram is null; otherwise returns false. */ -bool QScriptProgram::isValid() const +bool QScriptProgram::isNull() const { Q_D(const QScriptProgram); - return (d && d->engine); + return (d == 0); } /*! @@ -142,7 +162,7 @@ QString QScriptProgram::sourceCode() const Q_D(const QScriptProgram); if (!d) return QString(); - return d->executable->source().toString(); + return d->sourceCode; } /*! @@ -153,7 +173,7 @@ QString QScriptProgram::fileName() const Q_D(const QScriptProgram); if (!d) return QString(); - return d->executable->sourceURL(); + return d->fileName; } /*! @@ -164,7 +184,7 @@ int QScriptProgram::lineNumber() const Q_D(const QScriptProgram); if (!d) return -1; - return d->executable->lineNo(); + return d->lineNumber; } /*! @@ -173,6 +193,9 @@ int QScriptProgram::lineNumber() const */ bool QScriptProgram::operator==(const QScriptProgram &other) const { + Q_D(const QScriptProgram); + if (d == other.d_func()) + return true; return (sourceCode() == other.sourceCode()) && (fileName() == other.fileName()) && (lineNumber() == other.lineNumber()); diff --git a/src/script/api/qscriptprogram.h b/src/script/api/qscriptprogram.h index b6782b8..6ab56dc 100644 --- a/src/script/api/qscriptprogram.h +++ b/src/script/api/qscriptprogram.h @@ -44,6 +44,8 @@ #include <QtCore/qsharedpointer.h> +#include <QtCore/qstring.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -55,12 +57,15 @@ class Q_SCRIPT_EXPORT QScriptProgram { public: QScriptProgram(); + QScriptProgram(const QString &sourceCode, + const QString fileName = QString(), + int lineNumber = 1); QScriptProgram(const QScriptProgram &other); ~QScriptProgram(); QScriptProgram &operator=(const QScriptProgram &other); - bool isValid() const; + bool isNull() const; QString sourceCode() const; QString fileName() const; diff --git a/src/script/api/qscriptprogram_p.h b/src/script/api/qscriptprogram_p.h index fe06b38..861ef32 100644 --- a/src/script/api/qscriptprogram_p.h +++ b/src/script/api/qscriptprogram_p.h @@ -58,6 +58,7 @@ namespace JSC { class EvalExecutable; + class ExecState; } QT_BEGIN_NAMESPACE @@ -67,20 +68,26 @@ class QScriptEnginePrivate; class QScriptProgramPrivate { public: - QScriptProgramPrivate(QScriptEnginePrivate*, - JSC::EvalExecutable*, - intptr_t); + QScriptProgramPrivate(const QString &sourceCode, + const QString &fileName, + int lineNumber); ~QScriptProgramPrivate(); static QScriptProgramPrivate *get(const QScriptProgram &q); - static QScriptProgram create(QScriptEnginePrivate*, - JSC::EvalExecutable*, - intptr_t); + + JSC::EvalExecutable *executable(JSC::ExecState *exec, + QScriptEnginePrivate *engine); QBasicAtomicInt ref; + + QString sourceCode; + QString fileName; + int lineNumber; + QScriptEnginePrivate *engine; - JSC::EvalExecutable *executable; + JSC::EvalExecutable *_executable; intptr_t sourceId; + bool isCompiled; }; QT_END_NAMESPACE |