aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/v8/qv8contextwrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/v8/qv8contextwrapper.cpp')
-rw-r--r--src/declarative/qml/v8/qv8contextwrapper.cpp455
1 files changed, 0 insertions, 455 deletions
diff --git a/src/declarative/qml/v8/qv8contextwrapper.cpp b/src/declarative/qml/v8/qv8contextwrapper.cpp
deleted file mode 100644
index 8b7fbe8941..0000000000
--- a/src/declarative/qml/v8/qv8contextwrapper.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8contextwrapper_p.h"
-#include "qv8engine_p.h"
-
-#include <private/qdeclarativeengine_p.h>
-#include <private/qdeclarativecontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static QString internal(QLatin1String("You've stumbled onto an internal implementation detail "
- "that should never have been exposed."));
-
-class QV8ContextResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(ContextType);
-
-public:
- QV8ContextResource(QV8Engine *engine, QDeclarativeContextData *context, QObject *scopeObject);
- ~QV8ContextResource();
-
- inline QDeclarativeContextData *getContext() const;
- inline QObject *getScopeObject() const;
-
- quint32 isSharedContext:1;
- quint32 hasSubContexts:1;
- quint32 readOnly:1;
- quint32 dummy:29;
-
- QObject *secondaryScope;
-
- // This is a pretty horrible hack, and an abuse of external strings. When we create a
- // sub-context (a context created by a Qt.include() in an external javascript file),
- // we pass a specially crafted SubContext external string as the v8::Script::Data() to
- // the script, which contains a pointer to the context. We can then access the
- // v8::Script::Data() later on to resolve names and URLs against the sub-context instead
- // of the main outer context.
- struct SubContext : public v8::String::ExternalStringResource {
- SubContext(QDeclarativeContextData *context) : context(context) {}
- QDeclarativeGuardedContextData context;
-
- virtual const uint16_t* data() const { return (const uint16_t *)internal.constData(); }
- virtual size_t length() const { return internal.length(); }
- };
-
-private:
- QDeclarativeGuardedContextData context;
- QDeclarativeGuard<QObject> scopeObject;
-
-};
-
-QV8ContextResource::QV8ContextResource(QV8Engine *engine, QDeclarativeContextData *context, QObject *scopeObject)
-: QV8ObjectResource(engine), isSharedContext(false), hasSubContexts(false), readOnly(true),
- secondaryScope(0), context(context), scopeObject(scopeObject)
-{
-}
-
-QV8ContextResource::~QV8ContextResource()
-{
- if (context && context->isJSContext)
- context->destroy();
-}
-
-// Returns the scope object
-QObject *QV8ContextResource::getScopeObject() const
-{
- if (isSharedContext)
- return QDeclarativeEnginePrivate::get(engine->engine())->sharedScope;
- else
- return scopeObject;
-}
-
-// Returns the context, including resolving a subcontext
-QDeclarativeContextData *QV8ContextResource::getContext() const
-{
- if (isSharedContext)
- return QDeclarativeEnginePrivate::get(engine->engine())->sharedContext;
-
- if (!hasSubContexts)
- return context;
-
- v8::Local<v8::Value> callingdata = v8::Context::GetCallingScriptData();
- if (callingdata.IsEmpty() || !callingdata->IsString())
- return context;
-
- v8::Local<v8::String> callingstring = callingdata->ToString();
- Q_ASSERT(callingstring->IsExternal());
- Q_ASSERT(callingstring->GetExternalStringResource());
-
- SubContext *sc = static_cast<SubContext *>(callingstring->GetExternalStringResource());
- return sc->context;
-}
-
-QV8ContextWrapper::QV8ContextWrapper()
-: m_engine(0)
-{
-}
-
-QV8ContextWrapper::~QV8ContextWrapper()
-{
-}
-
-void QV8ContextWrapper::destroy()
-{
- qPersistentDispose(m_sharedContext);
- qPersistentDispose(m_urlConstructor);
- qPersistentDispose(m_constructor);
-}
-
-void QV8ContextWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->SetFallbackPropertyHandler(NullGetter, NullSetter);
- m_urlConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- v8::Local<v8::Object> sharedContext = m_constructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(engine, 0, 0);
- r->isSharedContext = true;
- sharedContext->SetExternalResource(r);
- m_sharedContext = qPersistentNew<v8::Object>(sharedContext);
- }
-}
-
-v8::Local<v8::Object> QV8ContextWrapper::qmlScope(QDeclarativeContextData *ctxt, QObject *scope)
-{
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(m_engine, ctxt, scope);
- rv->SetExternalResource(r);
- return rv;
-}
-
-v8::Local<v8::Object> QV8ContextWrapper::urlScope(const QUrl &url)
-{
- QDeclarativeContextData *context = new QDeclarativeContextData;
- context->url = url;
- context->isInternal = true;
- context->isJSContext = true;
-
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_urlConstructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(m_engine, context, 0);
- rv->SetExternalResource(r);
- return rv;
-}
-
-void QV8ContextWrapper::setReadOnly(v8::Handle<v8::Object> qmlglobal, bool readOnly)
-{
- QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal);
- Q_ASSERT(resource);
- resource->readOnly = readOnly;
-}
-
-void QV8ContextWrapper::addSubContext(v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Script> script,
- QDeclarativeContextData *ctxt)
-{
- QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal);
- Q_ASSERT(resource);
- resource->hasSubContexts = true;
- script->SetData(v8::String::NewExternal(new QV8ContextResource::SubContext(ctxt)));
-}
-
-QObject *QV8ContextWrapper::setSecondaryScope(v8::Handle<v8::Object> ctxt, QObject *scope)
-{
- QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(ctxt);
- if (!resource) return 0;
-
- QObject *rv = resource->secondaryScope;
- resource->secondaryScope = scope;
- return rv;
-}
-
-QDeclarativeContextData *QV8ContextWrapper::callingContext()
-{
- v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal();
- if (qmlglobal.IsEmpty()) return 0;
-
- QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal);
- return r?r->getContext():0;
-}
-
-QDeclarativeContextData *QV8ContextWrapper::context(v8::Handle<v8::Value> value)
-{
- if (!value->IsObject())
- return 0;
-
- v8::Handle<v8::Object> qmlglobal = v8::Handle<v8::Object>::Cast(value);
- QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal);
- return r?r->getContext():0;
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::NullGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- QV8Engine *engine = resource->engine;
-
- QString error = QLatin1String("Can't find variable: ") + engine->toString(property);
- v8::ThrowException(v8::Exception::ReferenceError(engine->toString(error)));
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
- QDeclarativeContextData *context = resource->getContext();
- QDeclarativeContextData *expressionContext = context;
-
- if (!context)
- return v8::Undefined();
-
- if (v8::Context::GetCallingQmlGlobal() != info.This())
- return v8::Handle<v8::Value>();
-
- // Search type (attached property/enum/imported scripts) names
- // Secondary scope object
- // while (context) {
- // Search context properties
- // Search scope object
- // Search context object
- // context = context->parent
- // }
-
- QV8Engine *engine = resource->engine;
-
- QObject *scopeObject = resource->getScopeObject();
-
- QHashedV8String propertystring(property);
-
- if (context->imports && QV8Engine::startsWithUpper(property)) {
- // Search for attached properties, enums and imported scripts
- QDeclarativeTypeNameCache::Result r = context->imports->query(propertystring);
-
- if (r.isValid()) {
- if (r.scriptIndex != -1) {
- int index = r.scriptIndex;
- if (index < context->importedScripts.count())
- return context->importedScripts.at(index);
- else
- return v8::Undefined();
- } else if (r.type) {
- return engine->typeWrapper()->newObject(scopeObject, r.type);
- } else if (r.importNamespace) {
- return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace);
- }
- Q_ASSERT(!"Unreachable");
- }
-
- // Fall through
- }
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine->engine());
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
-
- if (resource->secondaryScope) {
- v8::Handle<v8::Value> result = qobjectWrapper->getProperty(resource->secondaryScope, propertystring,
- QV8QObjectWrapper::IgnoreRevision);
- if (!result.IsEmpty()) return result;
- }
-
- while (context) {
- // Search context properties
- if (context->propertyNames) {
- int propertyIdx = context->propertyNames->value(propertystring);
-
- if (propertyIdx != -1) {
-
- if (propertyIdx < context->idValueCount) {
-
- ep->captureProperty(&context->idValues[propertyIdx].bindings);
- return engine->newQObject(context->idValues[propertyIdx]);
- } else {
-
- QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate();
-
- ep->captureProperty(context->asQDeclarativeContext(), -1,
- propertyIdx + cp->notifyIndex);
-
- const QVariant &value = cp->propertyValues.at(propertyIdx);
- if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
- QDeclarativeListProperty<QObject> prop(context->asQDeclarativeContext(), (void*)propertyIdx,
- 0,
- QDeclarativeContextPrivate::context_count,
- QDeclarativeContextPrivate::context_at);
- return engine->listWrapper()->newList(prop, qMetaTypeId<QDeclarativeListProperty<QObject> >());
- } else {
- return engine->fromVariant(cp->propertyValues.at(propertyIdx));
- }
- }
- }
- }
-
- // Search scope object
- if (scopeObject) {
- v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, propertystring,
- QV8QObjectWrapper::CheckRevision);
- if (!result.IsEmpty()) return result;
- }
- scopeObject = 0;
-
-
- // Search context object
- if (context->contextObject) {
- v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, propertystring,
- QV8QObjectWrapper::CheckRevision);
- if (!result.IsEmpty()) return result;
- }
-
- context = context->parent;
- }
-
- expressionContext->unresolvedNames = true;
-
- QString error = QLatin1String("Can't find variable: ") + engine->toString(property);
- v8::ThrowException(v8::Exception::ReferenceError(engine->toString(error)));
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::NullSetter(v8::Local<v8::String> property,
- v8::Local<v8::Value>,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- QV8Engine *engine = resource->engine;
-
- if (!resource->readOnly) {
- return v8::Handle<v8::Value>();
- } else {
- QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) +
- QLatin1String("\"");
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
- QDeclarativeContextData *context = resource->getContext();
- QDeclarativeContextData *expressionContext = context;
-
- if (!context)
- return v8::Undefined();
-
- if (v8::Context::GetCallingQmlGlobal() != info.This())
- return v8::Handle<v8::Value>();
-
- // See QV8ContextWrapper::Getter for resolution order
-
- QV8Engine *engine = resource->engine;
- QObject *scopeObject = resource->getScopeObject();
-
- QHashedV8String propertystring(property);
-
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
-
- // Search scope object
- if (resource->secondaryScope &&
- qobjectWrapper->setProperty(resource->secondaryScope, propertystring, value,
- QV8QObjectWrapper::IgnoreRevision))
- return value;
-
- while (context) {
- // Search context properties
- if (context->propertyNames && -1 != context->propertyNames->value(propertystring))
- return value;
-
- // Search scope object
- if (scopeObject &&
- qobjectWrapper->setProperty(scopeObject, propertystring, value, QV8QObjectWrapper::CheckRevision))
- return value;
- scopeObject = 0;
-
- // Search context object
- if (context->contextObject &&
- qobjectWrapper->setProperty(context->contextObject, propertystring, value,
- QV8QObjectWrapper::CheckRevision))
- return value;
-
- context = context->parent;
- }
-
- expressionContext->unresolvedNames = true;
-
- if (!resource->readOnly) {
- return v8::Handle<v8::Value>();
- } else {
- QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) +
- QLatin1String("\"");
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Undefined();
- }
-}
-
-QT_END_NAMESPACE