aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-05-22 13:49:27 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-05-22 15:47:40 +0200
commit54d8facf66d668d8cea1184f7f24928e97497ae1 (patch)
treec28b591ea8b632234107c6650585b4f4bc7bca28
parente57285b323b0c669841e9be7b2af427958a8c9b6 (diff)
Add a QV4::Script class
The class is a replacement for v8::Script. Start using it in various places. Change-Id: Ie5537639e44fa1ee23aea8605eae3c736819ef52 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/qml/v4/qv4context.cpp25
-rw-r--r--src/qml/qml/v4/qv4context_p.h3
-rw-r--r--src/qml/qml/v4/qv4engine.cpp31
-rw-r--r--src/qml/qml/v4/qv4engine_p.h3
-rw-r--r--src/qml/qml/v4/qv4globalobject.cpp114
-rw-r--r--src/qml/qml/v4/qv4globalobject_p.h11
-rw-r--r--src/qml/qml/v4/qv4script.cpp187
-rw-r--r--src/qml/qml/v4/qv4script_p.h78
-rw-r--r--src/qml/qml/v4/qv4v8.cpp30
-rw-r--r--src/qml/qml/v4/v4.pri2
-rw-r--r--src/qml/qml/v8/qjsengine.cpp11
-rw-r--r--src/qml/qml/v8/qv8engine.cpp10
12 files changed, 340 insertions, 165 deletions
diff --git a/src/qml/qml/v4/qv4context.cpp b/src/qml/qml/v4/qv4context.cpp
index 928a57877f..0535f86275 100644
--- a/src/qml/qml/v4/qv4context.cpp
+++ b/src/qml/qml/v4/qv4context.cpp
@@ -201,6 +201,31 @@ void CallContext::initCallContext(ExecutionEngine *engine, FunctionObject *funct
}
}
+void CallContext::initQmlContext(ExecutionEngine *engine, Object *qml, FunctionObject *function)
+{
+ initBaseContext(Type_QmlContext, engine);
+
+ this->function = function;
+ this->arguments = 0;
+ this->argumentCount = 0;
+ this->thisObject = Value::undefinedValue();
+
+ strictMode = true;
+ marked = false;
+ this->outer = function->scope;
+#ifndef QT_NO_DEBUG
+ assert(outer->next != (ExecutionContext *)0x1);
+#endif
+
+ activation = qml;
+
+ lookups = function->function->lookups;
+
+ locals = (Value *)(this + 1);
+ if (function->varCount)
+ std::fill(locals, locals + function->varCount, Value::undefinedValue());
+}
+
bool ExecutionContext::deleteProperty(String *name)
{
diff --git a/src/qml/qml/v4/qv4context_p.h b/src/qml/qml/v4/qv4context_p.h
index 0cd4a21baa..a96db3433b 100644
--- a/src/qml/qml/v4/qv4context_p.h
+++ b/src/qml/qml/v4/qv4context_p.h
@@ -169,6 +169,7 @@ struct CallContext : public SimpleCallContext
{
void initCallContext(QV4::ExecutionEngine *engine, FunctionObject *function, Value *args, int argc,
const Value &thisObject);
+ void initQmlContext(QV4::ExecutionEngine *engine, Object *qml, QV4::FunctionObject *function);
bool needsOwnArguments() const;
Value *locals;
@@ -220,6 +221,8 @@ inline const CallContext *ExecutionContext::asCallContext() const
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount))
+#define requiredMemoryForQmlExecutionContect(f) \
+ sizeof(CallContext) + sizeof(Value) * (f->locals.size())
#define stackContextSize (sizeof(CallContext) + 32*sizeof(Value))
} // namespace QV4
diff --git a/src/qml/qml/v4/qv4engine.cpp b/src/qml/qml/v4/qv4engine.cpp
index 8fafddf182..cdcb12f88c 100644
--- a/src/qml/qml/v4/qv4engine.cpp
+++ b/src/qml/qml/v4/qv4engine.cpp
@@ -315,6 +315,17 @@ CallContext *ExecutionEngine::newCallContext(FunctionObject *f, const Value &thi
return c;
}
+CallContext *ExecutionEngine::newQmlContext(FunctionObject *f, Object *qml)
+{
+ CallContext *c = static_cast<CallContext *>(memoryManager->allocContext(requiredMemoryForExecutionContect(f, 0)));
+
+ c->initQmlContext(this, qml, f);
+ c->parent = current;
+ current = c;
+
+ return c;
+}
+
CallContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f, const Value &thisObject, Value *args, int argc)
{
CallContext *c;
@@ -671,23 +682,3 @@ void ExecutionEngine::markObjects()
variantPrototype->mark();
sequencePrototype->mark();
}
-
-Value ExecutionEngine::run(Function *function, ExecutionContext *ctx)
-{
- if (!ctx)
- ctx = rootContext;
-
- TemporaryAssignment<Function*> savedGlobalCode(globalCode, function);
-
- // ### Would be better to have a SavedExecutionState object that
- // saves this and restores it in the destructor (to survive an exception).
- ctx->strictMode = function->isStrict;
- ctx->lookups = function->lookups;
-
- if (debugger)
- debugger->aboutToCall(0, ctx);
- QV4::Value result = function->code(ctx, function->codeData);
- if (debugger)
- debugger->justLeft(ctx);
- return result;
-}
diff --git a/src/qml/qml/v4/qv4engine_p.h b/src/qml/qml/v4/qv4engine_p.h
index 6d1ae60da2..96188d44a2 100644
--- a/src/qml/qml/v4/qv4engine_p.h
+++ b/src/qml/qml/v4/qv4engine_p.h
@@ -227,6 +227,7 @@ struct Q_QML_EXPORT ExecutionEngine
CatchContext *newCatchContext(String* exceptionVarName, const QV4::Value &exceptionValue);
CallContext *newCallContext(FunctionObject *f, const QV4::Value &thisObject, QV4::Value *args, int argc);
CallContext *newCallContext(void *stackSpace, FunctionObject *f, const QV4::Value &thisObject, QV4::Value *args, int argc);
+ CallContext *newQmlContext(FunctionObject *f, Object *qml);
ExecutionContext *pushGlobalContext();
void pushContext(SimpleCallContext *context);
ExecutionContext *popContext();
@@ -284,8 +285,6 @@ struct Q_QML_EXPORT ExecutionEngine
void markObjects();
- Value run(Function *function, ExecutionContext *ctx = 0);
-
void initRootContext();
InternalClass *newClass(const InternalClass &other);
diff --git a/src/qml/qml/v4/qv4globalobject.cpp b/src/qml/qml/v4/qv4globalobject.cpp
index cae1d715e7..e56b396b6b 100644
--- a/src/qml/qml/v4/qv4globalobject.cpp
+++ b/src/qml/qml/v4/qv4globalobject.cpp
@@ -44,6 +44,8 @@
#include "qv4value_p.h"
#include "qv4context_p.h"
#include "qv4function_p.h"
+#include "qv4debugging_p.h"
+#include "qv4script_p.h"
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
@@ -62,6 +64,7 @@
using namespace QV4;
+
static inline char toHex(char c)
{
static const char hexnumbers[] = "0123456789ABCDEF";
@@ -344,18 +347,9 @@ DEFINE_MANAGED_VTABLE(EvalFunction);
EvalFunction::EvalFunction(ExecutionContext *scope)
: FunctionObject(scope, scope->engine->id_eval)
- , qmlActivation(0)
-{
- vtbl = &static_vtbl;
- defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
-}
-
-EvalFunction::EvalFunction(ExecutionContext *scope, Object *qmlActivation)
- : FunctionObject(scope, scope->engine->id_eval)
{
vtbl = &static_vtbl;
defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
- this->qmlActivation = qmlActivation;
}
Value EvalFunction::evalCall(ExecutionContext *parentContext, Value /*thisObject*/, Value *args, int argc, bool directCall)
@@ -378,31 +372,26 @@ Value EvalFunction::evalCall(ExecutionContext *parentContext, Value /*thisObject
const QString code = args[0].stringValue()->toQString();
bool inheritContext = !ctx->strictMode;
- QV4::Function *f = parseSource(ctx, QStringLiteral("eval code"),
- code, QQmlJS::Codegen::EvalCode,
- (directCall && parentContext->strictMode), inheritContext);
+ Script script(ctx, code, QString("eval code"));
+ script.strictMode = (directCall && parentContext->strictMode);
+ script.inheritContext = inheritContext;
+ script.parse();
- if (!f)
+ if (!script.function)
return Value::undefinedValue();
- strictMode = f->isStrict || (ctx->strictMode);
- if (qmlActivation)
- strictMode = true;
+ strictMode = script.function->isStrict || (ctx->strictMode);
- usesArgumentsObject = f->usesArgumentsObject;
- needsActivation = f->needsActivation();
+ usesArgumentsObject = script.function->usesArgumentsObject;
+ needsActivation = script.function->needsActivation();
if (strictMode) {
CallContext *k = ctx->engine->newCallContext(this, ctx->thisObject, 0, 0);
- if (qmlActivation) {
- k->activation = qmlActivation;
- k->type = ExecutionContext::Type_QmlContext;
- }
ctx = k;
}
ExecutionContext::EvalCode evalCode;
- evalCode.function = f;
+ evalCode.function = script.function;
evalCode.next = ctx->currentEvalCode;
ctx->currentEvalCode = &evalCode;
@@ -412,7 +401,7 @@ Value EvalFunction::evalCall(ExecutionContext *parentContext, Value /*thisObject
Value result = Value::undefinedValue();
try {
- result = f->code(ctx, f->codeData);
+ result = script.function->code(ctx, script.function->codeData);
} catch (Exception &ex) {
ctx->strictMode = cstrict;
ctx->currentEvalCode = evalCode.next;
@@ -437,83 +426,6 @@ Value EvalFunction::call(Managed *that, ExecutionContext *context, const Value &
return static_cast<EvalFunction *>(that)->evalCall(context, thisObject, args, argc, false);
}
-//Value EvalFunction::construct(ExecutionContext *ctx, Value *, int)
-//{
-// ctx->throwTypeError();
-// return Value::undefinedValue();
-//}
-
-QV4::Function *EvalFunction::parseSource(QV4::ExecutionContext *ctx,
- const QString &fileName, const QString &source,
- QQmlJS::Codegen::Mode mode,
- bool strictMode, bool inheritContext)
-{
- using namespace QQmlJS;
-
- MemoryManager::GCBlocker gcBlocker(ctx->engine->memoryManager);
-
- ExecutionEngine *vm = ctx->engine;
- V4IR::Module module;
- Function *globalCode = 0;
-
- {
- QQmlJS::Engine ee, *engine = &ee;
- Lexer lexer(engine);
- lexer.setCode(source, 1, false);
- Parser parser(engine);
-
- const bool parsed = parser.parseProgram();
-
- DiagnosticMessage *error = 0, **errIt = &error;
- foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
- if (m.isError()) {
- *errIt = new DiagnosticMessage;
- (*errIt)->fileName = fileName;
- (*errIt)->offset = m.loc.offset;
- (*errIt)->length = m.loc.length;
- (*errIt)->startLine = m.loc.startLine;
- (*errIt)->startColumn = m.loc.startColumn;
- (*errIt)->type = DiagnosticMessage::Error;
- (*errIt)->message = m.message;
- errIt = &(*errIt)->next;
- } else {
- std::cerr << qPrintable(fileName) << ':' << m.loc.startLine << ':' << m.loc.startColumn
- << ": warning: " << qPrintable(m.message) << std::endl;
- }
- }
- if (error)
- ctx->throwSyntaxError(error);
-
- if (parsed) {
- using namespace AST;
- Program *program = AST::cast<Program *>(parser.rootNode());
- if (!program) {
- // if parsing was successful, and we have no program, then
- // we're done...:
- return 0;
- }
-
- QStringList inheritedLocals;
- if (inheritContext)
- for (String * const *i = ctx->variables(), * const *ei = i + ctx->variableCount(); i < ei; ++i)
- inheritedLocals.append(*i ? (*i)->toQString() : QString());
-
- Codegen cg(ctx, strictMode);
- V4IR::Function *globalIRCode = cg(fileName, source, program, &module, mode, inheritedLocals);
- QScopedPointer<EvalInstructionSelection> isel(ctx->engine->iselFactory->create(vm, &module));
- if (inheritContext)
- isel->setUseFastLookups(false);
- if (globalIRCode)
- globalCode = isel->vmFunction(globalIRCode);
- }
-
- if (! globalCode)
- // ### should be a syntax error
- ctx->throwTypeError();
- }
-
- return globalCode;
-}
static inline int toInt(const QChar &qc, int R)
{
diff --git a/src/qml/qml/v4/qv4globalobject_p.h b/src/qml/qml/v4/qv4globalobject_p.h
index 97a8b705f5..b1abc212e6 100644
--- a/src/qml/qml/v4/qv4globalobject_p.h
+++ b/src/qml/qml/v4/qv4globalobject_p.h
@@ -44,28 +44,19 @@
#include "qv4global_p.h"
#include "qv4functionobject_p.h"
-QT_END_NAMESPACE
+QT_BEGIN_NAMESPACE
namespace QV4 {
struct Q_QML_EXPORT EvalFunction : FunctionObject
{
EvalFunction(ExecutionContext *scope);
- EvalFunction(ExecutionContext *scope, Object *qmlActivation);
-
- static QV4::Function *parseSource(QV4::ExecutionContext *ctx,
- const QString &fileName,
- const QString &source,
- QQmlJS::Codegen::Mode mode, bool strictMode,
- bool inheritContext);
Value evalCall(ExecutionContext *context, Value thisObject, Value *args, int argc, bool directCall);
using Managed::construct;
static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
- Object *qmlActivation;
-
protected:
static const ManagedVTable static_vtbl;
};
diff --git a/src/qml/qml/v4/qv4script.cpp b/src/qml/qml/v4/qv4script.cpp
new file mode 100644
index 0000000000..3b4456055c
--- /dev/null
+++ b/src/qml/qml/v4/qv4script.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4script_p.h"
+#include "qv4mm_p.h"
+#include "qv4functionobject_p.h"
+#include "qv4function_p.h"
+#include "qv4context_p.h"
+#include "qv4debugging_p.h"
+
+#include <private/qqmljsengine_p.h>
+#include <private/qqmljslexer_p.h>
+#include <private/qqmljsparser_p.h>
+#include <private/qqmljsast_p.h>
+#include <qv4jsir_p.h>
+#include <qv4codegen_p.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+
+using namespace QV4;
+
+
+void Script::parse()
+{
+ using namespace QQmlJS;
+
+ MemoryManager::GCBlocker gcBlocker(scope->engine->memoryManager);
+
+ ExecutionEngine *vm = scope->engine;
+ V4IR::Module module;
+ Function *globalCode = 0;
+
+ {
+ QQmlJS::Engine ee, *engine = &ee;
+ Lexer lexer(engine);
+ lexer.setCode(sourceCode, 1, false);
+ Parser parser(engine);
+
+ const bool parsed = parser.parseProgram();
+
+ DiagnosticMessage *error = 0, **errIt = &error;
+ foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
+ if (m.isError()) {
+ *errIt = new DiagnosticMessage;
+ (*errIt)->fileName = sourceFile;
+ (*errIt)->offset = m.loc.offset;
+ (*errIt)->length = m.loc.length;
+ (*errIt)->startLine = m.loc.startLine;
+ (*errIt)->startColumn = m.loc.startColumn;
+ (*errIt)->type = DiagnosticMessage::Error;
+ (*errIt)->message = m.message;
+ errIt = &(*errIt)->next;
+ } else {
+ qWarning() << sourceFile << ':' << m.loc.startLine << ':' << m.loc.startColumn
+ << ": warning: " << m.message;
+ }
+ }
+ if (error)
+ scope->throwSyntaxError(error);
+
+ if (parsed) {
+ using namespace AST;
+ Program *program = AST::cast<Program *>(parser.rootNode());
+ if (!program) {
+ // if parsing was successful, and we have no program, then
+ // we're done...:
+ return;
+ }
+
+ QStringList inheritedLocals;
+ if (inheritContext)
+ for (String * const *i = scope->variables(), * const *ei = i + scope->variableCount(); i < ei; ++i)
+ inheritedLocals.append(*i ? (*i)->toQString() : QString());
+
+ Codegen cg(scope, strictMode);
+ V4IR::Function *globalIRCode = cg(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals);
+ QScopedPointer<EvalInstructionSelection> isel(scope->engine->iselFactory->create(vm, &module));
+ if (inheritContext)
+ isel->setUseFastLookups(false);
+ if (globalIRCode)
+ globalCode = isel->vmFunction(globalIRCode);
+ }
+
+ if (! globalCode)
+ // ### should be a syntax error
+ scope->throwTypeError();
+ }
+
+ function = globalCode;
+}
+
+struct QmlFunction : FunctionObject
+{
+ QmlFunction(ExecutionContext *scope)
+ : FunctionObject(scope, scope->engine->id_eval)
+ {
+ defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
+ }
+};
+
+Value Script::run()
+{
+ QV4::ExecutionEngine *engine = scope->engine;
+
+ if (!function)
+ // ### FIX file/line number
+ __qmljs_throw(engine->current, QV4::Value::fromObject(engine->newSyntaxErrorObject(engine->current, 0)), -1);
+
+ if (!qml) {
+ TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, function);
+
+ bool strict = scope->strictMode;
+ Lookup *lookups = scope->lookups;
+
+ scope->strictMode = function->isStrict;
+ scope->lookups = function->lookups;
+
+ if (engine->debugger)
+ engine->debugger->aboutToCall(0, scope);
+
+ QV4::Value result;
+ try {
+ result = function->code(scope, function->codeData);
+ } catch (Exception &e) {
+ scope->strictMode = strict;
+ scope->lookups = lookups;
+ throw;
+ }
+
+ if (engine->debugger)
+ engine->debugger->justLeft(scope);
+ return result;
+ } else {
+ QmlFunction *f = new (engine->memoryManager) QmlFunction(scope);
+ f->function = function;
+ f->usesArgumentsObject = function->usesArgumentsObject;
+ f->needsActivation = function->needsActivation();
+
+ CallContext *ctx = engine->newQmlContext(f, qml);
+
+ Value result = function->code(ctx, function->codeData);
+
+ engine->popContext();
+
+ return result;
+ }
+}
+
diff --git a/src/qml/qml/v4/qv4script_p.h b/src/qml/qml/v4/qv4script_p.h
new file mode 100644
index 0000000000..442b4fd071
--- /dev/null
+++ b/src/qml/qml/v4/qv4script_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4SCRIPT_H
+#define QV4SCRIPT_H
+
+#include "qv4global_p.h"
+#include "qv4engine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct ExecutionContext;
+
+struct Script {
+ Script(ExecutionContext *scope, const QString &sourceCode, const QString &source, int line = 0, int column = 0)
+ : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
+ , scope(scope), strictMode(false), inheritContext(false), qml(0), function(0) {}
+ Script(ExecutionEngine *engine, Object *qml, const QString &sourceCode, const QString &source, int line = 0, int column = 0)
+ : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
+ , scope(engine->rootContext), strictMode(true), inheritContext(true), qml(qml), function(0) {}
+ QString sourceFile;
+ int line;
+ int column;
+ QString sourceCode;
+ ExecutionContext *scope;
+ bool strictMode;
+ bool inheritContext;
+ Object *qml;
+ Function *function;
+
+ void parse();
+ Value run();
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/v4/qv4v8.cpp b/src/qml/qml/v4/qv4v8.cpp
index e730eb1a17..e0ca7ee5a8 100644
--- a/src/qml/qml/v4/qv4v8.cpp
+++ b/src/qml/qml/v4/qv4v8.cpp
@@ -55,6 +55,7 @@
#include "qv4booleanobject_p.h"
#include "qv4stringobject_p.h"
#include "qv4objectproto_p.h"
+#include "qv4script_p.h"
#include <QThreadStorage>
using namespace QQmlJS;
@@ -240,34 +241,17 @@ Handle<Value> Script::Run()
QV4::ExecutionEngine *engine = Isolate::GetCurrent()->GetEngine();
QV4::ExecutionContext *ctx = engine->current;
- QV4::Function *f = QV4::EvalFunction::parseSource(engine->rootContext, m_origin.m_fileName, m_script, QQmlJS::Codegen::EvalCode,
- /*strictMode =*/ false, /*inheritContext =*/ false);
- if (!f)
- // ### FIX file/line number
- __qmljs_throw(engine->current, QV4::Value::fromObject(engine->newSyntaxErrorObject(engine->current, 0)), -1);
-
- return engine->run(f);
+ QV4::Script script(ctx, m_script, m_origin.m_fileName, m_origin.m_lineNumber, m_origin.m_columnNumber);
+ script.parse();
+ return script.run();
}
Handle<Value> Script::Run(Handle<Object> qml)
{
QV4::ExecutionEngine *engine = Isolate::GetCurrent()->GetEngine();
- QV4::ExecutionContext *ctx = engine->current;
-
- QV4::Value result = QV4::Value::undefinedValue();
-
- try {
-
- QV4::EvalFunction *eval = new (engine->memoryManager) QV4::EvalFunction(engine->rootContext, qml->v4Value().asObject());
-
- QV4::Value arg = QV4::Value::fromString(engine->current, m_script);
-
- result = eval->evalCall(engine->current, QV4::Value::undefinedValue(), &arg, 1, /*directCall*/ false);
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- return Handle<Value>();
- }
- return result;
+ QV4::Script script(engine, qml->v4Value().asObject(), m_script, m_origin.m_fileName, m_origin.m_lineNumber, m_origin.m_columnNumber);
+ script.parse();
+ return script.run();
}
Handle<Value> Script::Id()
diff --git a/src/qml/qml/v4/v4.pri b/src/qml/qml/v4/v4.pri
index ccfb723f8f..b6f27c540f 100644
--- a/src/qml/qml/v4/v4.pri
+++ b/src/qml/qml/v4/v4.pri
@@ -48,6 +48,7 @@ SOURCES += \
$$PWD/qv4regexp.cpp \
$$PWD/qv4unwindhelper.cpp \
$$PWD/qv4serialize.cpp \
+ $$PWD/qv4script.cpp \
$$PWD/qv4v8.cpp \
$$PWD/qv4executableallocator.cpp \
$$PWD/qv4sequenceobject.cpp
@@ -96,6 +97,7 @@ HEADERS += \
$$PWD/qv4unwindhelper_p-dw2.h \
$$PWD/qv4unwindhelper_p-arm.h \
$$PWD/qv4serialize_p.h \
+ $$PWD/qv4script_p.h \
$$PWD/qv4v8_p.h \
$$PWD/qv4util_p.h \
$$PWD/qv4executableallocator_p.h \
diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp
index 754a67ebe0..1e3713e5e0 100644
--- a/src/qml/qml/v8/qjsengine.cpp
+++ b/src/qml/qml/v8/qjsengine.cpp
@@ -48,6 +48,7 @@
#include "private/qv4engine_p.h"
#include "private/qv4mm_p.h"
#include "private/qv4globalobject_p.h"
+#include "private/qv4script_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qmetaobject.h>
@@ -256,12 +257,14 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
{
QV4::ExecutionContext *ctx = d->m_v4Engine->current;
try {
- QV4::Function *f = QV4::EvalFunction::parseSource(ctx, fileName, program, QQmlJS::Codegen::EvalCode,
- d->m_v4Engine->current->strictMode, true);
- if (!f)
+ QV4::Script script(ctx, program, fileName, lineNumber);
+ script.strictMode = ctx->strictMode;
+ script.inheritContext = true;
+ script.parse();
+ if (!script.function)
return QJSValue();
- QV4::Value result = d->m_v4Engine->run(f);
+ QV4::Value result = script.run();
return new QJSValuePrivate(d->m_v4Engine, result);
} catch (QV4::Exception& ex) {
ex.accept(ctx);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index b6431b7fad..267dea58ce 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -73,6 +73,7 @@
#include <private/qv4globalobject_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4variantobject_p.h>
+#include <private/qv4script_p.h>
Q_DECLARE_METATYPE(QList<int>)
@@ -1479,14 +1480,13 @@ QV4::Value QV8Engine::toString(const QString &string)
QV4::Value QV8Engine::evaluateScript(const QString &script, QV4::Object *scopeObject)
{
- QV4::ExecutionContext *ctx = m_v4Engine->current;
+ QV4::Script qmlScript(m_v4Engine, scopeObject, script, QString());
+ QV4::ExecutionContext *ctx = m_v4Engine->current;
QV4::Value result = QV4::Value::undefinedValue();
-
try {
- QV4::EvalFunction *eval = new (m_v4Engine->memoryManager) QV4::EvalFunction(m_v4Engine->rootContext, scopeObject);
- QV4::Value arg = QV4::Value::fromString(m_v4Engine->current, script);
- result = eval->evalCall(m_v4Engine->current, QV4::Value::undefinedValue(), &arg, 1, /*directCall*/ false);
+ qmlScript.parse();
+ result = qmlScript.run();
} catch (QV4::Exception &e) {
e.accept(ctx);
}