util/src/script/api/qscriptengine_p.h
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 QtScript 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 #ifndef QSCRIPTENGINE_P_H
       
    25 #define QSCRIPTENGINE_P_H
       
    26 
       
    27 //
       
    28 //  W A R N I N G
       
    29 //  -------------
       
    30 //
       
    31 // This file is not part of the Qt API.  It exists purely as an
       
    32 // implementation detail.  This header file may change from version to
       
    33 // version without notice, or even be removed.
       
    34 //
       
    35 // We mean it.
       
    36 //
       
    37 
       
    38 #include "private/qobject_p.h"
       
    39 
       
    40 #include <QtCore/qhash.h>
       
    41 #include <QtCore/qset.h>
       
    42 #include "qscriptvalue_p.h"
       
    43 #include "qscriptstring_p.h"
       
    44 
       
    45 #include "Debugger.h"
       
    46 #include "Lexer.h"
       
    47 #include "RefPtr.h"
       
    48 #include "SourceProvider.h"
       
    49 #include "Structure.h"
       
    50 #include "JSGlobalObject.h"
       
    51 #include "JSValue.h"
       
    52 
       
    53 namespace JSC
       
    54 {
       
    55     class EvalExecutable;
       
    56     class ExecState;
       
    57     typedef ExecState CallFrame;
       
    58     class JSCell;
       
    59     class JSGlobalObject;
       
    60     class UString;
       
    61 }
       
    62 
       
    63 
       
    64 QT_BEGIN_NAMESPACE
       
    65 
       
    66 class QString;
       
    67 class QStringList;
       
    68 class QScriptContext;
       
    69 class QScriptValue;
       
    70 class QScriptTypeInfo;
       
    71 class QScriptEngineAgent;
       
    72 class QScriptEnginePrivate;
       
    73 class QScriptSyntaxCheckResult;
       
    74 class QScriptEngine;
       
    75 
       
    76 namespace QScript
       
    77 {
       
    78     class QObjectPrototype;
       
    79     class QMetaObjectPrototype;
       
    80     class QVariantPrototype;
       
    81 #ifndef QT_NO_QOBJECT
       
    82     class QObjectData;
       
    83 #endif
       
    84     class TimeoutCheckerProxy;
       
    85 
       
    86     //some conversion helper functions
       
    87     inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
       
    88     bool isFunction(JSC::JSValue value);
       
    89 
       
    90     class UStringSourceProviderWithFeedback;
       
    91 
       
    92 struct GlobalClientData : public JSC::JSGlobalData::ClientData
       
    93 {
       
    94     GlobalClientData(QScriptEnginePrivate *e)
       
    95         : engine(e) {}
       
    96     virtual ~GlobalClientData() {}
       
    97     virtual void mark(JSC::MarkStack& markStack);
       
    98 
       
    99     QScriptEnginePrivate *engine;
       
   100 };
       
   101 
       
   102 } // namespace QScript
       
   103 
       
   104 class QScriptEnginePrivate
       
   105 #ifndef QT_NO_QOBJECT
       
   106     : public QObjectPrivate
       
   107 #endif
       
   108 {
       
   109     Q_DECLARE_PUBLIC(QScriptEngine)
       
   110 public:
       
   111     QScriptEnginePrivate();
       
   112     virtual ~QScriptEnginePrivate();
       
   113 
       
   114     static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; }
       
   115     static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; }
       
   116 
       
   117     static bool convert(const QScriptValue &value,
       
   118                         int type, void *ptr,
       
   119                         QScriptEnginePrivate *eng);
       
   120     QScriptValue create(int type, const void *ptr);
       
   121     bool hasDemarshalFunction(int type) const;
       
   122 
       
   123     inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
       
   124     inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
       
   125 
       
   126     QScriptValue scriptValueFromVariant(const QVariant &value);
       
   127     QVariant scriptValueToVariant(const QScriptValue &value, int targetType);
       
   128 
       
   129     JSC::JSValue jscValueFromVariant(const QVariant &value);
       
   130     QVariant jscValueToVariant(JSC::JSValue value, int targetType);
       
   131 
       
   132     QScriptValue arrayFromStringList(const QStringList &lst);
       
   133     static QStringList stringListFromArray(const QScriptValue &arr);
       
   134 
       
   135     QScriptValue arrayFromVariantList(const QVariantList &lst);
       
   136     static QVariantList variantListFromArray(const QScriptValue &arr);
       
   137 
       
   138     QScriptValue objectFromVariantMap(const QVariantMap &vmap);
       
   139     static QVariantMap variantMapFromObject(const QScriptValue &obj);
       
   140 
       
   141     JSC::JSValue defaultPrototype(int metaTypeId) const;
       
   142     void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
       
   143 
       
   144     static inline QScriptContext *contextForFrame(JSC::ExecState *frame);
       
   145     static inline JSC::ExecState *frameForContext(QScriptContext *context);
       
   146     static inline const JSC::ExecState *frameForContext(const QScriptContext *context);
       
   147 
       
   148     JSC::JSGlobalObject *originalGlobalObject() const;
       
   149     JSC::JSObject *getOriginalGlobalObjectProxy();
       
   150     JSC::JSObject *customGlobalObject() const;
       
   151     JSC::JSObject *globalObject() const;
       
   152     void setGlobalObject(JSC::JSObject *object);
       
   153     inline JSC::ExecState *globalExec() const;
       
   154     JSC::JSValue toUsableValue(JSC::JSValue value);
       
   155     static JSC::JSValue thisForContext(JSC::ExecState *frame);
       
   156     static JSC::Register *thisRegisterForFrame(JSC::ExecState *frame);
       
   157 
       
   158     JSC::CallFrame *pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList& args,
       
   159                                 JSC::JSObject *callee, bool calledAsConstructor = false, bool clearScopeChain = false);
       
   160     void popContext();
       
   161 
       
   162     void mark(JSC::MarkStack& markStack);
       
   163     bool isCollecting() const;
       
   164     void collectGarbage();
       
   165 
       
   166     //flags that we set on the return value register for native function. (ie when codeBlock is 0)
       
   167     enum ContextFlags {
       
   168         NativeContext = 1,
       
   169         CalledAsConstructorContext = 2,
       
   170         HasScopeContext = 4, // Specifies that the is a QScriptActivationObject
       
   171         ShouldRestoreCallFrame = 8
       
   172     };
       
   173     static uint contextFlags(JSC::ExecState *);
       
   174     static void setContextFlags(JSC::ExecState *, uint);
       
   175 
       
   176     QScript::TimeoutCheckerProxy *timeoutChecker() const;
       
   177 
       
   178     void agentDeleted(QScriptEngineAgent *agent);
       
   179 
       
   180     void setCurrentException(QScriptValue exception) { m_currentException = exception; }
       
   181     QScriptValue currentException() const { return m_currentException; }
       
   182     void clearCurrentException() { m_currentException.d_ptr.reset(); }
       
   183 
       
   184 #ifndef QT_NO_QOBJECT
       
   185     JSC::JSValue newQObject(QObject *object,
       
   186         QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership,
       
   187         const QScriptEngine:: QObjectWrapOptions &options = 0);
       
   188     JSC::JSValue newQMetaObject(const QMetaObject *metaObject,
       
   189                                 JSC::JSValue ctor);
       
   190 
       
   191     static QScriptSyntaxCheckResult checkSyntax(const QString &program);
       
   192     static bool canEvaluate(const QString &program);
       
   193     static bool convertToNativeQObject(const QScriptValue &value,
       
   194                                        const QByteArray &targetType,
       
   195                                        void **result);
       
   196 
       
   197     JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId,
       
   198                                 JSC::EvalExecutable *executable,
       
   199                                 bool &compile);
       
   200 
       
   201     QScript::QObjectData *qobjectData(QObject *object);
       
   202     void disposeQObject(QObject *object);
       
   203     void emitSignalHandlerException();
       
   204 
       
   205     bool scriptConnect(QObject *sender, const char *signal,
       
   206                        JSC::JSValue receiver, JSC::JSValue function,
       
   207                        Qt::ConnectionType type);
       
   208     bool scriptDisconnect(QObject *sender, const char *signal,
       
   209                           JSC::JSValue receiver, JSC::JSValue function);
       
   210 
       
   211     bool scriptConnect(QObject *sender, int index,
       
   212                        JSC::JSValue receiver, JSC::JSValue function,
       
   213                        JSC::JSValue senderWrapper,
       
   214                        Qt::ConnectionType type);
       
   215     bool scriptDisconnect(QObject *sender, int index,
       
   216                           JSC::JSValue receiver, JSC::JSValue function);
       
   217 
       
   218     bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver,
       
   219                        JSC::JSValue function, Qt::ConnectionType type);
       
   220     bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver,
       
   221                           JSC::JSValue function);
       
   222 
       
   223     inline QScriptValuePrivate *allocateScriptValuePrivate(size_t);
       
   224     inline void freeScriptValuePrivate(QScriptValuePrivate *p);
       
   225 
       
   226     inline void registerScriptValue(QScriptValuePrivate *value);
       
   227     inline void unregisterScriptValue(QScriptValuePrivate *value);
       
   228     void detachAllRegisteredScriptValues();
       
   229 
       
   230     inline void registerScriptString(QScriptStringPrivate *value);
       
   231     inline void unregisterScriptString(QScriptStringPrivate *value);
       
   232     void detachAllRegisteredScriptStrings();
       
   233 
       
   234     // private slots
       
   235     void _q_objectDestroyed(QObject *);
       
   236 #endif
       
   237 
       
   238     JSC::JSGlobalData *globalData;
       
   239     JSC::JSObject *originalGlobalObjectProxy;
       
   240     JSC::ExecState *currentFrame;
       
   241 
       
   242     WTF::RefPtr<JSC::Structure> scriptObjectStructure;
       
   243 
       
   244     QScript::QObjectPrototype *qobjectPrototype;
       
   245     WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure;
       
   246 
       
   247     QScript::QMetaObjectPrototype *qmetaobjectPrototype;
       
   248     WTF::RefPtr<JSC::Structure> qmetaobjectWrapperObjectStructure;
       
   249 
       
   250     QScript::QVariantPrototype *variantPrototype;
       
   251     WTF::RefPtr<JSC::Structure> variantWrapperObjectStructure;
       
   252 
       
   253     QList<QScriptEngineAgent*> ownedAgents;
       
   254     QScriptEngineAgent *activeAgent;
       
   255     int agentLineNumber;
       
   256     QScriptValuePrivate *registeredScriptValues;
       
   257     QScriptValuePrivate *freeScriptValues;
       
   258     static const int maxFreeScriptValues = 256;
       
   259     int freeScriptValuesCount;
       
   260     QScriptStringPrivate *registeredScriptStrings;
       
   261     QHash<int, QScriptTypeInfo*> m_typeInfos;
       
   262     int processEventsInterval;
       
   263     QScriptValue abortResult;
       
   264     bool inEval;
       
   265 
       
   266     QSet<QString> importedExtensions;
       
   267     QSet<QString> extensionsBeingImported;
       
   268     
       
   269     QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
       
   270     QScriptValue m_currentException;
       
   271 
       
   272 #ifndef QT_NO_QOBJECT
       
   273     QHash<QObject*, QScript::QObjectData*> m_qobjectData;
       
   274 #endif
       
   275 
       
   276 #ifdef QT_NO_QOBJECT
       
   277     QScriptEngine *q_ptr;
       
   278 #endif
       
   279 };
       
   280 
       
   281 namespace QScript
       
   282 {
       
   283 
       
   284 /*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
       
   285   It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update
       
   286   this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/
       
   287 class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider
       
   288 {
       
   289 public:
       
   290     static PassRefPtr<UStringSourceProviderWithFeedback> create(
       
   291         const JSC::UString& source, const JSC::UString& url,
       
   292         int lineNumber, QScriptEnginePrivate* engine)
       
   293     {
       
   294         return adoptRef(new UStringSourceProviderWithFeedback(source, url, lineNumber, engine));
       
   295     }
       
   296 
       
   297     /* Destruction means that there is no more copies of script so create scriptUnload event
       
   298        and unregister script in QScriptEnginePrivate::loadedScripts */
       
   299     virtual ~UStringSourceProviderWithFeedback()
       
   300     {
       
   301         if (m_ptr) {
       
   302             if (JSC::Debugger* debugger = this->debugger())
       
   303                 debugger->scriptUnload(asID());
       
   304             m_ptr->loadedScripts.remove(asID());
       
   305         }
       
   306     }
       
   307 
       
   308     /* set internal QScriptEnginePrivate pointer to null and create unloadScript event, should be called
       
   309        only if QScriptEnginePrivate is about to be  destroyed.*/
       
   310     void disconnectFromEngine()
       
   311     {
       
   312         if (JSC::Debugger* debugger = this->debugger())
       
   313             debugger->scriptUnload(asID());
       
   314         m_ptr = 0;
       
   315     }
       
   316 
       
   317     int columnNumberFromOffset(int offset) const
       
   318     {
       
   319         for (const UChar *c = m_source.data() + offset; c >= m_source.data(); --c) {
       
   320             if (JSC::Lexer::isLineTerminator(*c))
       
   321                 return offset - static_cast<int>(c - data());
       
   322         }
       
   323         return offset + 1;
       
   324     }
       
   325 
       
   326 protected:
       
   327     UStringSourceProviderWithFeedback(const JSC::UString& source, const JSC::UString& url,
       
   328                                       int lineNumber, QScriptEnginePrivate* engine)
       
   329         : UStringSourceProvider(source, url),
       
   330           m_ptr(engine)
       
   331     {
       
   332         if (JSC::Debugger* debugger = this->debugger())
       
   333             debugger->scriptLoad(asID(), source, url, lineNumber);
       
   334         if (m_ptr)
       
   335             m_ptr->loadedScripts.insert(asID(), this);
       
   336     }
       
   337 
       
   338     JSC::Debugger* debugger()
       
   339     {
       
   340         //if m_ptr is null it mean that QScriptEnginePrivate was destroyed and scriptUnload was called
       
   341         //else m_ptr is stable and we can use it as normal pointer without hesitation
       
   342         if(!m_ptr)
       
   343             return 0; //we are in ~QScriptEnginePrivate
       
   344         else
       
   345             return m_ptr->originalGlobalObject()->debugger(); //QScriptEnginePrivate is still alive
       
   346     }
       
   347 
       
   348     //trace global object and debugger instance
       
   349     QScriptEnginePrivate* m_ptr;
       
   350 };
       
   351 
       
   352 class SaveFrameHelper
       
   353 {
       
   354 public:
       
   355     SaveFrameHelper(QScriptEnginePrivate *eng,
       
   356                     JSC::ExecState *newFrame)
       
   357         : engine(eng), oldFrame(eng->currentFrame)
       
   358     {
       
   359         eng->currentFrame = newFrame;
       
   360     }
       
   361     ~SaveFrameHelper()
       
   362     {
       
   363         engine->currentFrame = oldFrame;
       
   364     }
       
   365 private:
       
   366     QScriptEnginePrivate *engine;
       
   367     JSC::ExecState *oldFrame;
       
   368 };
       
   369 
       
   370 inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec)
       
   371 {
       
   372     return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine;
       
   373 }
       
   374 
       
   375 } // namespace QScript
       
   376 
       
   377 inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
       
   378 {
       
   379     if (freeScriptValues) {
       
   380         QScriptValuePrivate *p = freeScriptValues;
       
   381         freeScriptValues = p->next;
       
   382         --freeScriptValuesCount;
       
   383         return p;
       
   384     }
       
   385     return reinterpret_cast<QScriptValuePrivate*>(qMalloc(size));
       
   386 }
       
   387 
       
   388 inline void QScriptEnginePrivate::freeScriptValuePrivate(QScriptValuePrivate *p)
       
   389 {
       
   390     if (freeScriptValuesCount < maxFreeScriptValues) {
       
   391         p->next = freeScriptValues;
       
   392         freeScriptValues = p;
       
   393         ++freeScriptValuesCount;
       
   394     } else {
       
   395         qFree(p);
       
   396     }
       
   397 }
       
   398 
       
   399 inline void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value)
       
   400 {
       
   401     value->prev = 0;
       
   402     value->next = registeredScriptValues;
       
   403     if (registeredScriptValues)
       
   404         registeredScriptValues->prev = value;
       
   405     registeredScriptValues = value;
       
   406 }
       
   407 
       
   408 inline void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *value)
       
   409 {
       
   410     if (value->prev)
       
   411         value->prev->next = value->next;
       
   412     if (value->next)
       
   413         value->next->prev = value->prev;
       
   414     if (value == registeredScriptValues)
       
   415         registeredScriptValues = value->next;
       
   416     value->prev = 0;
       
   417     value->next = 0;
       
   418 }
       
   419 
       
   420 inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value)
       
   421 {
       
   422     if (!value)
       
   423         return QScriptValue();
       
   424 
       
   425     QScriptValuePrivate *p_value = new (this)QScriptValuePrivate(this);
       
   426     p_value->initFrom(value);
       
   427     return QScriptValuePrivate::toPublic(p_value);
       
   428 }
       
   429 
       
   430 inline JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &value)
       
   431 {
       
   432     QScriptValuePrivate *vv = QScriptValuePrivate::get(value);
       
   433     if (!vv)
       
   434         return JSC::JSValue();
       
   435     if (vv->type != QScriptValuePrivate::JavaScriptCore) {
       
   436         Q_ASSERT(!vv->engine || vv->engine == this);
       
   437         vv->engine = this;
       
   438         if (vv->type == QScriptValuePrivate::Number) {
       
   439             vv->initFrom(JSC::jsNumber(currentFrame, vv->numberValue));
       
   440         } else { //QScriptValuePrivate::String
       
   441             vv->initFrom(JSC::jsString(currentFrame, vv->stringValue));
       
   442         }
       
   443     }
       
   444     return vv->jscValue;
       
   445 }
       
   446 
       
   447 inline QScriptValuePrivate::~QScriptValuePrivate()
       
   448 {
       
   449     if (engine)
       
   450         engine->unregisterScriptValue(this);
       
   451 }
       
   452 
       
   453 inline void QScriptValuePrivate::initFrom(JSC::JSValue value)
       
   454 {
       
   455     if (value.isCell()) {
       
   456         Q_ASSERT(engine != 0);
       
   457         value = engine->toUsableValue(value);
       
   458     }
       
   459     type = JavaScriptCore;
       
   460     jscValue = value;
       
   461     if (engine)
       
   462         engine->registerScriptValue(this);
       
   463 }
       
   464 
       
   465 inline void QScriptValuePrivate::initFrom(qsreal value)
       
   466 {
       
   467     type = Number;
       
   468     numberValue = value;
       
   469     if (engine)
       
   470         engine->registerScriptValue(this);
       
   471 }
       
   472 
       
   473 inline void QScriptValuePrivate::initFrom(const QString &value)
       
   474 {
       
   475     type = String;
       
   476     stringValue = value;
       
   477     if (engine)
       
   478         engine->registerScriptValue(this);
       
   479 }
       
   480 
       
   481 inline QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const
       
   482 {
       
   483     JSC::ExecState *exec = engine->currentFrame;
       
   484     return property(JSC::Identifier(exec, name), resolveMode);
       
   485 }
       
   486 
       
   487 inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const
       
   488 {
       
   489     Q_ASSERT(isObject());
       
   490     JSC::ExecState *exec = engine->currentFrame;
       
   491     JSC::JSObject *object = JSC::asObject(jscValue);
       
   492     JSC::PropertySlot slot(object);
       
   493     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot))
       
   494         return engine->scriptValueFromJSCValue(slot.getValue(exec, id));
       
   495     return propertyHelper(id, resolveMode);
       
   496 }
       
   497 
       
   498 inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
       
   499 {
       
   500     Q_ASSERT(isObject());
       
   501     JSC::ExecState *exec = engine->currentFrame;
       
   502     JSC::JSObject *object = JSC::asObject(jscValue);
       
   503     JSC::PropertySlot slot(object);
       
   504     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot))
       
   505         return engine->scriptValueFromJSCValue(slot.getValue(exec, index));
       
   506     return propertyHelper(index, resolveMode);
       
   507 }
       
   508 
       
   509 inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine)
       
   510 {
       
   511     if (engine)
       
   512         return engine->allocateScriptValuePrivate(size);
       
   513     return qMalloc(size);
       
   514 }
       
   515 
       
   516 inline void QScriptValuePrivate::operator delete(void *ptr)
       
   517 {
       
   518     QScriptValuePrivate *d = reinterpret_cast<QScriptValuePrivate*>(ptr);
       
   519     if (d->engine)
       
   520         d->engine->freeScriptValuePrivate(d);
       
   521     else
       
   522         qFree(d);
       
   523 }
       
   524 
       
   525 inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
       
   526 {
       
   527     if (exec) {
       
   528         *val = exec->exception();
       
   529         exec->clearException();
       
   530     } else {
       
   531         *val = JSC::JSValue();
       
   532     }
       
   533 }
       
   534 
       
   535 inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
       
   536 {
       
   537     if (exec && val)
       
   538         exec->setException(val);
       
   539 }
       
   540 
       
   541 inline void QScriptEnginePrivate::registerScriptString(QScriptStringPrivate *value)
       
   542 {
       
   543     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated);
       
   544     value->prev = 0;
       
   545     value->next = registeredScriptStrings;
       
   546     if (registeredScriptStrings)
       
   547         registeredScriptStrings->prev = value;
       
   548     registeredScriptStrings = value;
       
   549 }
       
   550 
       
   551 inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *value)
       
   552 {
       
   553     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated);
       
   554     if (value->prev)
       
   555         value->prev->next = value->next;
       
   556     if (value->next)
       
   557         value->next->prev = value->prev;
       
   558     if (value == registeredScriptStrings)
       
   559         registeredScriptStrings = value->next;
       
   560     value->prev = 0;
       
   561     value->next = 0;
       
   562 }
       
   563 
       
   564 inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame)
       
   565 {
       
   566     if (frame && frame->callerFrame()->hasHostCallFrameFlag() && !frame->callee()
       
   567         && frame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(frame)->globalExec()) {
       
   568         //skip the "fake" context created in Interpreter::execute.
       
   569         frame = frame->callerFrame()->removeHostCallFrameFlag();
       
   570     }
       
   571     return reinterpret_cast<QScriptContext *>(frame);
       
   572 }
       
   573 
       
   574 inline JSC::ExecState *QScriptEnginePrivate::frameForContext(QScriptContext *context)
       
   575 {
       
   576     return reinterpret_cast<JSC::ExecState*>(context);
       
   577 }
       
   578 
       
   579 inline const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScriptContext *context)
       
   580 {
       
   581     return reinterpret_cast<const JSC::ExecState*>(context);
       
   582 }
       
   583 
       
   584 inline JSC::ExecState *QScriptEnginePrivate::globalExec() const
       
   585 {
       
   586     return originalGlobalObject()->globalExec();
       
   587 }
       
   588 
       
   589 QT_END_NAMESPACE
       
   590 
       
   591 #endif