aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4script.cpp')
-rw-r--r--src/qml/jsruntime/qv4script.cpp164
1 files changed, 54 insertions, 110 deletions
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 4fde0e2445..7f2f22780e 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -32,11 +32,12 @@
****************************************************************************/
#include "qv4script_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4functionobject_p.h"
#include "qv4function_p.h"
#include "qv4context_p.h"
#include "qv4debugging_p.h"
+#include "qv4profiling_p.h"
#include "qv4scopedvalue_p.h"
#include <private/qqmljsengine_p.h>
@@ -44,6 +45,7 @@
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qv4profiling_p.h>
#include <qv4jsir_p.h>
#include <qv4codegen_p.h>
#include <private/qqmlcontextwrapper_p.h>
@@ -57,11 +59,15 @@ namespace QV4 {
namespace Heap {
struct CompilationUnitHolder : Object {
- inline CompilationUnitHolder(ExecutionEngine *engine, CompiledData::CompilationUnit *unit);
+ inline CompilationUnitHolder(CompiledData::CompilationUnit *unit);
QQmlRefPointer<CompiledData::CompilationUnit> unit;
};
+struct QmlBindingWrapper : FunctionObject {
+ QmlBindingWrapper(QV4::QmlContext *scope, Function *f);
+};
+
}
struct CompilationUnitHolder : public Object
@@ -71,12 +77,17 @@ struct CompilationUnitHolder : public Object
};
inline
-Heap::CompilationUnitHolder::CompilationUnitHolder(ExecutionEngine *engine, CompiledData::CompilationUnit *unit)
- : Heap::Object(engine)
- , unit(unit)
+Heap::CompilationUnitHolder::CompilationUnitHolder(CompiledData::CompilationUnit *unit)
+ : unit(unit)
{
}
+struct QmlBindingWrapper : FunctionObject {
+ V4_OBJECT2(QmlBindingWrapper, FunctionObject)
+
+ static ReturnedValue call(const Managed *that, CallData *callData);
+};
+
}
QT_END_NAMESPACE
@@ -86,117 +97,52 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QmlBindingWrapper);
DEFINE_OBJECT_VTABLE(CompilationUnitHolder);
-Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, Function *f, QV4::Object *qml)
- : Heap::FunctionObject(scope, scope->d()->engine->id_eval, /*createProto = */ false)
- , qml(qml->d())
+Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::QmlContext *scope, Function *f)
+ : Heap::FunctionObject(scope, scope->d()->engine->id_eval(), /*createProto = */ false)
{
Q_ASSERT(scope->inUse());
function = f;
if (function)
function->compilationUnit->addref();
-
- Scope s(scope);
- Scoped<QV4::QmlBindingWrapper> o(s, this);
-
- o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
-
- ScopedContext ctx(s, s.engine->currentContext());
- o->d()->qmlContext = ctx->newQmlContext(o, qml);
- s.engine->popContext();
}
-Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::Object *qml)
- : Heap::FunctionObject(scope, scope->d()->engine->id_eval, /*createProto = */ false)
- , qml(qml->d())
+ReturnedValue QmlBindingWrapper::call(const Managed *that, CallData *callData)
{
- Q_ASSERT(scope->inUse());
-
- Scope s(scope);
- Scoped<QV4::QmlBindingWrapper> o(s, this);
-
- o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
-
- ScopedContext ctx(s, s.engine->currentContext());
- o->d()->qmlContext = ctx->newQmlContext(o, qml);
- s.engine->popContext();
-}
+ const QmlBindingWrapper *This = static_cast<const QmlBindingWrapper *>(that);
+ ExecutionEngine *v4 = static_cast<const Object *>(that)->engine();
+ if (v4->hasException)
+ return Encode::undefined();
+ CHECK_STACK_LIMITS(v4);
-ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
-{
- ExecutionEngine *engine = static_cast<Object *>(that)->engine();
- CHECK_STACK_LIMITS(engine);
+ Scope scope(v4);
+ ExecutionContextSaver ctxSaver(scope);
- Scope scope(engine);
- QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that);
- if (!This->function())
+ QV4::Function *f = This->function();
+ if (!f)
return QV4::Encode::undefined();
- Scoped<CallContext> ctx(scope, This->d()->qmlContext);
- std::fill(ctx->d()->locals, ctx->d()->locals + ctx->d()->function->varCount(), Primitive::undefinedValue());
- engine->pushContext(ctx);
- ScopedValue result(scope, This->function()->code(engine, This->function()->codeData));
- engine->popContext();
+ Scoped<CallContext> ctx(scope, v4->currentContext->newCallContext(This, callData));
+ v4->pushContext(ctx);
- return result->asReturnedValue();
-}
-
-void QmlBindingWrapper::markObjects(Heap::Base *m, ExecutionEngine *e)
-{
- QmlBindingWrapper::Data *wrapper = static_cast<QmlBindingWrapper::Data *>(m);
- if (wrapper->qml)
- wrapper->qml->mark(e);
- FunctionObject::markObjects(m, e);
- if (wrapper->qmlContext)
- wrapper->qmlContext->mark(e);
-}
-
-static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
-{
- QV4::Scope scope(ctx);
- QV4::Scoped<CallContext> signalEmittingContext(scope, static_cast<Heap::CallContext *>(ctx->d()->parent));
- Q_ASSERT(signalEmittingContext && signalEmittingContext->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext);
- return signalEmittingContext->argument(parameterIndex);
-}
+ ScopedValue result(scope, Q_V4_PROFILE(v4, f));
-Heap::FunctionObject *QmlBindingWrapper::createQmlCallableForFunction(QQmlContextData *qmlContext, QObject *scopeObject, Function *runtimeFunction, const QList<QByteArray> &signalParameters, QString *error)
-{
- ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(qmlContext->engine);
- QV4::Scope valueScope(engine);
- QV4::ScopedObject qmlScopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(engine, qmlContext, scopeObject));
- ScopedContext global(valueScope, valueScope.engine->rootContext());
- QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, engine->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScopeObject));
- QV4::Scoped<CallContext> wrapperContext(valueScope, wrapper->context());
-
- if (!signalParameters.isEmpty()) {
- if (error)
- QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, error);
- QV4::ScopedProperty p(valueScope);
- QV4::ScopedString s(valueScope);
- int index = 0;
- foreach (const QByteArray &param, signalParameters) {
- QV4::ScopedFunctionObject g(valueScope, engine->memoryManager->alloc<QV4::IndexedBuiltinFunction>(wrapperContext, index++, signalParameterGetter));
- p->setGetter(g);
- p->setSetter(0);
- s = engine->newString(QString::fromUtf8(param));
- qmlScopeObject->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
- }
- }
-
- QV4::ScopedFunctionObject function(valueScope, QV4::FunctionObject::createScriptFunction(wrapperContext, runtimeFunction));
- return function->d();
+ return result->asReturnedValue();
}
-Script::Script(ExecutionEngine *v4, Object *qml, CompiledData::CompilationUnit *compilationUnit)
+Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit)
: line(0), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
- , qml(v4, qml), vmFunction(0), parseAsBinding(true)
+ , vmFunction(0), parseAsBinding(true)
{
+ if (qml)
+ qmlContext.set(v4, *qml);
+
parsed = true;
vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : 0;
if (vmFunction) {
Scope valueScope(v4);
- ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
+ ScopedObject holder(valueScope, v4->memoryManager->allocObject<CompilationUnitHolder>(compilationUnit));
compilationUnitHolder.set(v4, holder);
}
}
@@ -214,7 +160,7 @@ void Script::parse()
parsed = true;
- ExecutionEngine *v4 = scope->engine;
+ ExecutionEngine *v4 = scope->engine();
Scope valueScope(v4);
MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
@@ -267,7 +213,7 @@ void Script::parse()
isel->setUseFastLookups(false);
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = isel->compile();
vmFunction = compilationUnit->linkToEngine(v4);
- ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
+ ScopedObject holder(valueScope, v4->memoryManager->allocObject<CompilationUnitHolder>(compilationUnit));
compilationUnitHolder.set(v4, holder);
}
@@ -285,23 +231,22 @@ ReturnedValue Script::run()
if (!vmFunction)
return Encode::undefined();
- QV4::ExecutionEngine *engine = scope->engine;
+ QV4::ExecutionEngine *engine = scope->engine();
QV4::Scope valueScope(engine);
- if (qml.isUndefined()) {
+ if (qmlContext.isUndefined()) {
TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
- ExecutionContextSaver ctxSaver(valueScope, scope);
+ ExecutionContextSaver ctxSaver(valueScope);
ContextStateSaver stateSaver(valueScope, scope);
- scope->strictMode = vmFunction->isStrict();
- scope->lookups = vmFunction->compilationUnit->runtimeLookups;
- scope->compilationUnit = vmFunction->compilationUnit;
+ scope->d()->strictMode = vmFunction->isStrict();
+ scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups;
+ scope->d()->compilationUnit = vmFunction->compilationUnit;
- return vmFunction->code(engine, vmFunction->codeData);
+ return Q_V4_PROFILE(engine, vmFunction);
} else {
- ScopedObject qmlObj(valueScope, qml.value());
- ScopedContext ctx(valueScope, scope);
- ScopedFunctionObject f(valueScope, engine->memoryManager->alloc<QmlBindingWrapper>(ctx, vmFunction, qmlObj));
+ Scoped<QmlContext> qml(valueScope, qmlContext.value());
+ ScopedFunctionObject f(valueScope, engine->memoryManager->allocObject<QmlBindingWrapper>(qml, vmFunction));
ScopedCallData callData(valueScope);
callData->thisObject = Primitive::undefinedValue();
return f->call(callData);
@@ -376,18 +321,17 @@ ReturnedValue Script::qmlBinding()
{
if (!parsed)
parse();
- ExecutionEngine *v4 = scope->engine;
+ ExecutionEngine *v4 = scope->engine();
Scope valueScope(v4);
- ScopedObject qmlObj(valueScope, qml.value());
- ScopedContext ctx(valueScope, scope);
- ScopedObject v(valueScope, v4->memoryManager->alloc<QmlBindingWrapper>(ctx, vmFunction, qmlObj));
+ Scoped<QmlContext> qml(valueScope, qmlContext.value());
+ ScopedObject v(valueScope, v4->memoryManager->allocObject<QmlBindingWrapper>(qml, vmFunction));
return v.asReturnedValue();
}
-QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
+QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext)
{
QV4::Scope scope(engine);
- QV4::Script qmlScript(engine, scopeObject, script, QString());
+ QV4::Script qmlScript(engine, qmlContext, script, QString());
qmlScript.parse();
QV4::ScopedValue result(scope);