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