src/script/bridge/qscriptdeclarativeclass.cpp
changeset 3 41300fa6a67c
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
       
    10 ** GNU Lesser General Public License Usage
       
    11 ** This file may be used under the terms of the GNU Lesser
       
    12 ** General Public License version 2.1 as published by the Free Software
       
    13 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    14 ** packaging of this file.  Please review the following information to
       
    15 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    16 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    17 **
       
    18 ** If you have questions regarding the use of this file, please contact
       
    19 ** Nokia at qt-info@nokia.com.
       
    20 ** $QT_END_LICENSE$
       
    21 **
       
    22 ****************************************************************************/
       
    23 
       
    24 #include "qscriptdeclarativeclass_p.h"
       
    25 #include "qscriptdeclarativeobject_p.h"
       
    26 #include "qscriptobject_p.h"
       
    27 #include <QtScript/qscriptstring.h>
       
    28 #include <QtScript/qscriptengine.h>
       
    29 #include <QtScript/qscriptengineagent.h>
       
    30 #include <private/qscriptengine_p.h>
       
    31 #include <private/qscriptvalue_p.h>
       
    32 #include <private/qscriptqobject_p.h>
       
    33 #include <private/qscriptactivationobject_p.h>
       
    34 #include <QtCore/qstringlist.h>
       
    35 
       
    36 QT_BEGIN_NAMESPACE
       
    37 
       
    38 QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier()
       
    39 {
       
    40     new (&d) JSC::Identifier();
       
    41 }
       
    42 
       
    43 QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier()
       
    44 {
       
    45     ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
       
    46 }
       
    47 
       
    48 QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other)
       
    49 {
       
    50     identifier = other.identifier;
       
    51     new (&d) JSC::Identifier((JSC::Identifier &)(other.d));
       
    52 }
       
    53 
       
    54 QScriptDeclarativeClass::PersistentIdentifier &
       
    55 QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentifier &other)
       
    56 {
       
    57     identifier = other.identifier;
       
    58     ((JSC::Identifier &)d) = (JSC::Identifier &)(other.d);
       
    59     return *this;
       
    60 }
       
    61 
       
    62 QScriptDeclarativeClass::QScriptDeclarativeClass(QScriptEngine *engine)
       
    63 : d_ptr(new QScriptDeclarativeClassPrivate)
       
    64 {
       
    65     Q_ASSERT(sizeof(void*) == sizeof(JSC::Identifier));
       
    66     d_ptr->q_ptr = this;
       
    67     d_ptr->engine = engine;
       
    68 }
       
    69 
       
    70 QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, 
       
    71                                                 QScriptDeclarativeClass *scriptClass, 
       
    72                                                 Object *object)
       
    73 {
       
    74     Q_ASSERT(engine);
       
    75     Q_ASSERT(scriptClass);
       
    76 
       
    77     QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine)); 
       
    78 
       
    79     JSC::ExecState* exec = p->currentFrame;
       
    80     QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
       
    81     result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
       
    82     return p->scriptValueFromJSCValue(result);
       
    83 }
       
    84 
       
    85 QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v)
       
    86 {
       
    87     QScriptValuePrivate *d = QScriptValuePrivate::get(v);
       
    88     if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
       
    89         return 0;
       
    90     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
       
    91     QScriptObjectDelegate *delegate = scriptObject->delegate();
       
    92     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
       
    93         return 0;
       
    94     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass();
       
    95 }
       
    96 
       
    97 QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v)
       
    98 {
       
    99     QScriptValuePrivate *d = QScriptValuePrivate::get(v);
       
   100     if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
       
   101         return 0;
       
   102     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
       
   103     QScriptObjectDelegate *delegate = scriptObject->delegate();
       
   104     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
       
   105         return 0;
       
   106     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object();
       
   107 }
       
   108 
       
   109 QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name)
       
   110 {
       
   111     QScriptValuePrivate *d = QScriptValuePrivate::get(v);
       
   112 
       
   113     if (!d->isObject())
       
   114         return QScriptValue();
       
   115 
       
   116     JSC::ExecState *exec = d->engine->currentFrame;
       
   117     JSC::JSObject *object = d->jscValue.getObject();
       
   118     JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
       
   119     JSC::JSValue result;
       
   120 
       
   121     JSC::Identifier id(exec, (JSC::UString::Rep *)name);
       
   122 
       
   123     if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
       
   124         result = slot.getValue(exec, id);
       
   125         if (QScript::isFunction(result))
       
   126             return d->engine->scriptValueFromJSCValue(result);
       
   127     }
       
   128 
       
   129     return QScriptValue();
       
   130 }
       
   131 
       
   132 QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Identifier &name)
       
   133 {
       
   134     QScriptValuePrivate *d = QScriptValuePrivate::get(v);
       
   135 
       
   136     if (!d->isObject())
       
   137         return QScriptValue();
       
   138 
       
   139     JSC::ExecState *exec = d->engine->currentFrame;
       
   140     JSC::JSObject *object = d->jscValue.getObject();
       
   141     JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
       
   142     JSC::JSValue result;
       
   143 
       
   144     JSC::Identifier id(exec, (JSC::UString::Rep *)name);
       
   145 
       
   146     if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
       
   147         result = slot.getValue(exec, id);
       
   148         return d->engine->scriptValueFromJSCValue(result);
       
   149     }
       
   150 
       
   151     return QScriptValue();
       
   152 }
       
   153 
       
   154 /*
       
   155 Returns the scope chain entry at \a index.  If index is less than 0, returns
       
   156 entries starting at the end.  For example, scopeChainValue(context, -1) will return
       
   157 the value last in the scope chain.
       
   158 */
       
   159 QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index)
       
   160 {
       
   161     context->activationObject(); //ensure the creation of the normal scope for native context
       
   162     const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context);
       
   163     QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
       
   164 
       
   165     JSC::ScopeChainNode *node = frame->scopeChain();
       
   166     JSC::ScopeChainIterator it(node);
       
   167 
       
   168     if (index < 0) {
       
   169         int count = 0;
       
   170         for (it = node->begin(); it != node->end(); ++it) 
       
   171             ++count;
       
   172 
       
   173         index = qAbs(index);
       
   174         if (index > count)
       
   175             return QScriptValue();
       
   176         else
       
   177             index = count - index;
       
   178     }
       
   179 
       
   180     for (it = node->begin(); it != node->end(); ++it) {
       
   181 
       
   182         if (index == 0) {
       
   183 
       
   184             JSC::JSObject *object = *it;
       
   185             if (!object) return QScriptValue();
       
   186 
       
   187             if (object->inherits(&QScript::QScriptActivationObject::info)
       
   188                     && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) {
       
   189                 // Return the object that property access is being delegated to
       
   190                 object = static_cast<QScript::QScriptActivationObject*>(object)->delegate();
       
   191             }
       
   192             return engine->scriptValueFromJSCValue(object);
       
   193 
       
   194         } else {
       
   195             --index;
       
   196         }
       
   197 
       
   198     }
       
   199 
       
   200     return QScriptValue();
       
   201 }
       
   202 
       
   203 /*!
       
   204   Enters a new execution context and returns the associated
       
   205   QScriptContext object.
       
   206 
       
   207   Once you are done with the context, you should call popContext() to
       
   208   restore the old context.
       
   209 
       
   210   By default, the `this' object of the new context is the Global Object.
       
   211   The context's \l{QScriptContext::callee()}{callee}() will be invalid.
       
   212 
       
   213   Unlike pushContext(), the default scope chain is reset to include
       
   214   only the global object and the QScriptContext's activation object.
       
   215 
       
   216   \sa QScriptEngine::popContext()
       
   217 */
       
   218 QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine)
       
   219 {
       
   220     if (!engine)
       
   221         return 0;
       
   222 
       
   223     QScriptEnginePrivate *d = QScriptEnginePrivate::get(engine);
       
   224 
       
   225     JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, 
       
   226                                               d->currentFrame->globalData().dynamicGlobalObject,
       
   227                                               JSC::ArgList(), /*callee = */0, false, true);
       
   228 
       
   229     if (engine->agent())
       
   230         engine->agent()->contextPush();
       
   231 
       
   232     return d->contextForFrame(newFrame);
       
   233 }
       
   234 
       
   235 QScriptDeclarativeClass::~QScriptDeclarativeClass()
       
   236 {
       
   237 }
       
   238 
       
   239 QScriptEngine *QScriptDeclarativeClass::engine() const
       
   240 {
       
   241     return d_ptr->engine;
       
   242 }
       
   243 
       
   244 QScriptDeclarativeClass::PersistentIdentifier 
       
   245 QScriptDeclarativeClass::createPersistentIdentifier(const QString &str)
       
   246 {
       
   247     QScriptEnginePrivate *p = 
       
   248         static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine)); 
       
   249     JSC::ExecState* exec = p->currentFrame;
       
   250 
       
   251     PersistentIdentifier rv(true);
       
   252     new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size());
       
   253     rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
       
   254     return rv;
       
   255 }
       
   256 
       
   257 QScriptDeclarativeClass::PersistentIdentifier 
       
   258 QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id)
       
   259 {
       
   260     QScriptEnginePrivate *p = 
       
   261         static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine)); 
       
   262     JSC::ExecState* exec = p->currentFrame;
       
   263 
       
   264     PersistentIdentifier rv(true);
       
   265     new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id);
       
   266     rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
       
   267     return rv;
       
   268 }
       
   269 
       
   270 QString QScriptDeclarativeClass::toString(const Identifier &identifier)
       
   271 {
       
   272     JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
       
   273     return QString((QChar *)r->data(), r->size());
       
   274 }
       
   275 
       
   276 quint32 QScriptDeclarativeClass::toArrayIndex(const Identifier &identifier, bool *ok)
       
   277 {
       
   278     JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
       
   279     JSC::UString s(r);
       
   280     return s.toArrayIndex(ok);
       
   281 }
       
   282 
       
   283 QScriptClass::QueryFlags 
       
   284 QScriptDeclarativeClass::queryProperty(Object *object, const Identifier &name, 
       
   285                                        QScriptClass::QueryFlags flags)
       
   286 {
       
   287     Q_UNUSED(object);
       
   288     Q_UNUSED(name);
       
   289     Q_UNUSED(flags);
       
   290     return 0;
       
   291 }
       
   292 
       
   293 QScriptValue QScriptDeclarativeClass::property(Object *object, const Identifier &name)
       
   294 {
       
   295     Q_UNUSED(object);
       
   296     Q_UNUSED(name);
       
   297     return QScriptValue();
       
   298 }
       
   299 
       
   300 void QScriptDeclarativeClass::setProperty(Object *object, const Identifier &name, 
       
   301                                           const QScriptValue &value)
       
   302 {
       
   303     Q_UNUSED(object);
       
   304     Q_UNUSED(name);
       
   305     Q_UNUSED(value);
       
   306 }
       
   307 
       
   308 QScriptValue::PropertyFlags 
       
   309 QScriptDeclarativeClass::propertyFlags(Object *object, const Identifier &name)
       
   310 {
       
   311     Q_UNUSED(object);
       
   312     Q_UNUSED(name);
       
   313     return 0;
       
   314 }
       
   315 
       
   316 QStringList QScriptDeclarativeClass::propertyNames(Object *object)
       
   317 {
       
   318     Q_UNUSED(object);
       
   319     return QStringList();
       
   320 }
       
   321 
       
   322 QObject *QScriptDeclarativeClass::toQObject(Object *, bool *ok)
       
   323 {
       
   324     if (ok) *ok = false;
       
   325     return 0;
       
   326 }
       
   327 
       
   328 QVariant QScriptDeclarativeClass::toVariant(Object *, bool *ok)
       
   329 {
       
   330     if (ok) *ok = false;
       
   331     return QVariant();
       
   332 }
       
   333 
       
   334 QScriptContext *QScriptDeclarativeClass::context() const
       
   335 {
       
   336     return d_ptr->context;
       
   337 }
       
   338 
       
   339 QT_END_NAMESPACE