summaryrefslogtreecommitdiffstats
path: root/src/script/api/qscriptengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/api/qscriptengine.cpp')
-rw-r--r--src/script/api/qscriptengine.cpp332
1 files changed, 90 insertions, 242 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 357254b..f695a77 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -51,6 +51,8 @@
#include "qscriptvalue_p.h"
#include "qscriptvalueiterator.h"
#include "qscriptclass.h"
+#include "qscriptprogram.h"
+#include "qscriptprogram_p.h"
#include "qdebug.h"
#include <QtCore/qstringlist.h>
@@ -340,25 +342,6 @@ public:
JSC::JSValue prototype;
};
-class QScriptProgramPrivate
-{
-public:
- QScriptProgramPrivate() : refcount(1), hasException(false) { }
- ~QScriptProgramPrivate() { if (evalNode) evalNode->destroyData(); }
-
- void addref() { ++refcount; }
- void release() { if (--refcount) delete this; }
-
- int refcount;
-
- bool hasException;
- QScriptValue exception;
-
- JSC::SourceCode source;
- WTF::RefPtr<JSC::EvalNode> evalNode;
-};
-
-
namespace QScript
{
@@ -1192,6 +1175,72 @@ void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent)
}
}
+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);
+ JSC::JSValue exceptionValue;
+ timeoutChecker()->setShouldAbort(false);
+ if (processEventsInterval > 0)
+ timeoutChecker()->reset();
+
+ JSC::JSValue result = exec->interpreter()->execute(executable, exec, thisObject, exec->scopeChain(), &exceptionValue);
+
+ if (timeoutChecker()->shouldAbort()) {
+ if (abortResult.isError())
+ exec->setException(scriptValueToJSCValue(abortResult));
+
+ if (debugger)
+ debugger->evaluateStop(scriptValueToJSCValue(abortResult), sourceId);
+
+ return scriptValueToJSCValue(abortResult);
+ }
+
+ if (exceptionValue) {
+ exec->setException(exceptionValue);
+
+ if (debugger)
+ debugger->evaluateStop(exceptionValue, sourceId);
+
+ return exceptionValue;
+ }
+
+ if (debugger)
+ debugger->evaluateStop(result, sourceId);
+
+ Q_ASSERT(!exec->hadException());
+ return result;
+}
+
#ifndef QT_NO_QOBJECT
JSC::JSValue QScriptEnginePrivate::newQObject(
@@ -2119,121 +2168,7 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra
return QScriptSyntaxCheckResult(p);
}
-QScriptProgram QScriptEngine::compile(const QString &program, const QString &fileName, int lineNumber)
-{
- Q_D(QScriptEngine);
-
- QScriptProgram rv;
- rv.d = new QScriptProgramPrivate;
-
- JSC::JSLock lock(false); // ### hmmm
- 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;
- WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
- = QScript::UStringSourceProviderWithFeedback::create(jscProgram, jscFileName, lineNumber, d);
- intptr_t sourceId = provider->asID();
- JSC::SourceCode &source = rv.d->source;
- source = JSC::SourceCode(provider, lineNumber); //after construction of SourceCode provider variable will be null.
-
- if (debugger)
- debugger->evaluateStart(sourceId);
-
- exec->clearException();
- JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
-
- int errorLine;
- JSC::UString errorMessage;
- WTF::RefPtr<JSC::EvalNode> &evalNode = rv.d->evalNode;
- evalNode = exec->globalData().parser->parse<JSC::EvalNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, source, &errorLine, &errorMessage);
- if (!evalNode) {
- JSC::JSValue exceptionValue = JSC::Error::create(exec, JSC::SyntaxError, errorMessage, errorLine, source.provider()->asID(), source.provider()->url());
- exec->setException(exceptionValue);
-
- if (debugger) {
- debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, exceptionValue), sourceId, false);
- debugger->evaluateStop(exceptionValue, sourceId);
- }
-
- rv.d->hasException = true;
- rv.d->exception = d->scriptValueFromJSCValue(exceptionValue);
- } else if (debugger) {
- debugger->evaluateStop(JSC::JSValue(), sourceId);
- }
-
- return rv;
-}
-
-QScriptValue QScriptEngine::evaluate(const QScriptProgram &program)
-{
- Q_D(QScriptEngine);
-
- if (0 == program.d)
- return QScriptValue();
- else if (program.d->hasException)
- return program.d->exception;
- else if (!program.d->evalNode)
- return QScriptValue();
-
- JSC::JSLock lock(false); // ### hmmm
- QBoolBlocker inEval(d->inEval, true);
- currentContext()->activationObject(); //force the creation of a context for native function;
-
- JSC::Debugger* debugger = d->originalGlobalObject()->debugger();
-
- JSC::ExecState* exec = d->currentFrame;
-
- intptr_t sourceId = program.d->source.provider()->asID();
-
- if (debugger)
- debugger->evaluateStart(sourceId);
-
- exec->clearException();
- JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
-
- WTF::RefPtr<JSC::EvalNode> &evalNode = program.d->evalNode;
-
- JSC::EvalExecutable executable(exec, program.d->source);
- executable.compile(exec, evalNode, exec->scopeChain());
- JSC::JSValue thisValue = d->thisForContext(exec);
- JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSC::JSValue exceptionValue;
- d->timeoutChecker()->setShouldAbort(false);
- if (d->processEventsInterval > 0)
- d->timeoutChecker()->reset();
- JSC::JSValue result = exec->interpreter()->execute(&executable, exec, thisObject, exec->scopeChain(), &exceptionValue);
-
- if (d->timeoutChecker()->shouldAbort()) {
- if (d->abortResult.isError())
- exec->setException(d->scriptValueToJSCValue(d->abortResult));
-
- if (debugger)
- debugger->evaluateStop(d->scriptValueToJSCValue(d->abortResult), sourceId);
-
- return d->abortResult;
- }
-
- if (exceptionValue) {
- exec->setException(exceptionValue);
-
- if (debugger)
- debugger->evaluateStop(exceptionValue, sourceId);
-
- return d->scriptValueFromJSCValue(exceptionValue);
- }
-
- if (debugger)
- debugger->evaluateStop(result, sourceId);
-
- Q_ASSERT(!exec->hadException());
- return d->scriptValueFromJSCValue(result);
-}
/*!
Evaluates \a program, using \a lineNumber as the base line number,
@@ -2266,75 +2201,38 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram &program)
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::Debugger* debugger = d->originalGlobalObject()->debugger();
-
- 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.
- if (debugger)
- debugger->evaluateStart(sourceId);
-
- clearExceptions();
- JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
-
+ JSC::ExecState* exec = d->currentFrame;
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);
- }
-
- JSC::JSValue thisValue = d->thisForContext(exec);
- JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSC::JSValue exceptionValue;
- d->timeoutChecker()->setShouldAbort(false);
- if (d->processEventsInterval > 0)
- d->timeoutChecker()->reset();
- JSC::JSValue result = exec->interpreter()->execute(&executable, exec, thisObject, exec->scopeChain(), &exceptionValue);
-
- if (d->timeoutChecker()->shouldAbort()) {
- if (d->abortResult.isError())
- exec->setException(d->scriptValueToJSCValue(d->abortResult));
-
- if (debugger)
- debugger->evaluateStop(d->scriptValueToJSCValue(d->abortResult), sourceId);
-
- return d->abortResult;
- }
-
- if (exceptionValue) {
- exec->setException(exceptionValue);
-
- if (debugger)
- debugger->evaluateStop(exceptionValue, sourceId);
-
- return d->scriptValueFromJSCValue(exceptionValue);
- }
+ bool compile = true;
+ return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile));
+}
- if (debugger)
- debugger->evaluateStop(result, sourceId);
+/*!
+ \internal
+ \since 4.6
+*/
+QScriptValue QScriptEngine::evaluate(const QScriptProgram &program)
+{
+ Q_D(QScriptEngine);
+ QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program);
+ if (!program_d)
+ return QScriptValue();
- Q_ASSERT(!exec->hadException());
+ JSC::ExecState* exec = d->currentFrame;
+ 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);
}
-
/*!
Returns the current context.
@@ -3857,9 +3755,6 @@ QScriptValue QScriptEngine::objectById(qint64 id) const
return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue((JSC::JSCell*)id);
}
-
-
-
/*!
\since 4.5
\class QScriptSyntaxCheckResult
@@ -3988,51 +3883,4 @@ Q_AUTOTEST_EXPORT bool qt_script_isJITEnabled()
}
#endif
-QScriptProgram::QScriptProgram()
-: d(0)
-{
-}
-
-QScriptProgram::~QScriptProgram()
-{
- if (d) d->release();
-}
-
-QScriptProgram::QScriptProgram(const QScriptProgram &c)
-: d(c.d)
-{
- if (d) d->addref();
-}
-
-QScriptProgram &QScriptProgram::operator=(const QScriptProgram &c)
-{
- if (c.d) c.d->addref();
- if (d) d->release();
- d = c.d;
- return *this;
-}
-
-bool QScriptProgram::isNull() const
-{
- return d == 0;
-}
-
-bool QScriptProgram::hasSyntaxError() const
-{
- if (d) return d->hasException;
- else return false;
-}
-
-QScriptValue QScriptProgram::syntaxError() const
-{
- if (d) return d->exception;
- else return QScriptValue();
-}
-
-QString QScriptProgram::programSource() const
-{
- if (d) return d->source.toString();
- else return QString();
-}
-
QT_END_NAMESPACE