src/script/api/qscriptengine_p.h
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    35 // We mean it.
    35 // We mean it.
    36 //
    36 //
    37 
    37 
    38 #include "private/qobject_p.h"
    38 #include "private/qobject_p.h"
    39 
    39 
       
    40 #include <QtCore/qdatetime.h>
    40 #include <QtCore/qhash.h>
    41 #include <QtCore/qhash.h>
       
    42 #include <QtCore/qnumeric.h>
       
    43 #include <QtCore/qregexp.h>
    41 #include <QtCore/qset.h>
    44 #include <QtCore/qset.h>
    42 #include "qscriptvalue_p.h"
    45 #include "qscriptvalue_p.h"
    43 #include "qscriptstring_p.h"
    46 #include "qscriptstring_p.h"
    44 
    47 #include "bridge/qscriptclassobject_p.h"
       
    48 #include "bridge/qscriptdeclarativeclass_p.h"
       
    49 #include "bridge/qscriptdeclarativeobject_p.h"
       
    50 #include "bridge/qscriptobject_p.h"
       
    51 #include "bridge/qscriptqobject_p.h"
       
    52 #include "bridge/qscriptvariant_p.h"
       
    53 #include "utils/qscriptdate_p.h"
       
    54 
       
    55 #include "DateConstructor.h"
       
    56 #include "DateInstance.h"
    45 #include "Debugger.h"
    57 #include "Debugger.h"
       
    58 #include "ErrorInstance.h"
       
    59 #include "JSArray.h"
    46 #include "Lexer.h"
    60 #include "Lexer.h"
    47 #include "RefPtr.h"
    61 #include "RefPtr.h"
       
    62 #include "RegExpConstructor.h"
       
    63 #include "RegExpObject.h"
    48 #include "SourceProvider.h"
    64 #include "SourceProvider.h"
    49 #include "Structure.h"
    65 #include "Structure.h"
       
    66 #include "UString.h"
    50 #include "JSGlobalObject.h"
    67 #include "JSGlobalObject.h"
    51 #include "JSValue.h"
    68 #include "JSValue.h"
    52 
    69 
    53 namespace JSC
    70 namespace JSC
    54 {
    71 {
    55     class EvalExecutable;
    72     class EvalExecutable;
    56     class ExecState;
    73     class ExecState;
    57     typedef ExecState CallFrame;
    74     typedef ExecState CallFrame;
    58     class JSCell;
    75     class JSCell;
    59     class JSGlobalObject;
    76     class JSGlobalObject;
    60     class UString;
       
    61 }
    77 }
    62 
    78 
    63 
    79 
    64 QT_BEGIN_NAMESPACE
    80 QT_BEGIN_NAMESPACE
    65 
    81 
    81 #ifndef QT_NO_QOBJECT
    97 #ifndef QT_NO_QOBJECT
    82     class QObjectData;
    98     class QObjectData;
    83 #endif
    99 #endif
    84     class TimeoutCheckerProxy;
   100     class TimeoutCheckerProxy;
    85 
   101 
       
   102     qint32 ToInt32(qsreal);
       
   103     quint32 ToUInt32(qsreal);
       
   104     quint16 ToUInt16(qsreal);
       
   105     qsreal ToInteger(qsreal);
       
   106 
       
   107     inline bool ToBool(qsreal);
       
   108     inline bool ToBool(const QString &);
       
   109     inline qint32 ToInt32(const QString &);
       
   110     inline quint32 ToUInt32(const QString &);
       
   111     inline quint16 ToUInt16(const QString &);
       
   112     inline qsreal ToInteger(const QString &);
       
   113 #ifdef Q_CC_MSVC
       
   114     // MSVC2008 crashes if these are inlined.
       
   115     qsreal ToNumber(const QString &);
       
   116     QString ToString(qsreal);
       
   117 #else
       
   118     inline qsreal ToNumber(const QString &);
       
   119     inline QString ToString(qsreal);
       
   120 #endif
       
   121 
    86     //some conversion helper functions
   122     //some conversion helper functions
    87     inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
   123     inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
    88     bool isFunction(JSC::JSValue value);
   124     bool isFunction(JSC::JSValue value);
       
   125 
       
   126     inline void convertToLatin1_helper(const UChar *i, int length, char *s);
       
   127     inline QByteArray convertToLatin1(const JSC::UString &str);
    89 
   128 
    90     class UStringSourceProviderWithFeedback;
   129     class UStringSourceProviderWithFeedback;
    91 
   130 
    92 struct GlobalClientData : public JSC::JSGlobalData::ClientData
   131 struct GlobalClientData : public JSC::JSGlobalData::ClientData
    93 {
   132 {
   112     virtual ~QScriptEnginePrivate();
   151     virtual ~QScriptEnginePrivate();
   113 
   152 
   114     static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; }
   153     static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; }
   115     static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; }
   154     static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; }
   116 
   155 
   117     static bool convert(const QScriptValue &value,
   156     static inline bool isArray(JSC::JSValue);
   118                         int type, void *ptr,
   157     static inline bool isDate(JSC::JSValue);
   119                         QScriptEnginePrivate *eng);
   158     static inline bool isError(JSC::JSValue);
   120     QScriptValue create(int type, const void *ptr);
   159     static inline bool isObject(JSC::JSValue);
       
   160     static inline bool isRegExp(JSC::JSValue);
       
   161     static inline bool isVariant(JSC::JSValue);
       
   162     static inline bool isQObject(JSC::JSValue);
       
   163     static inline bool isQMetaObject(JSC::JSValue);
       
   164 
       
   165     static inline bool toBool(JSC::ExecState *, JSC::JSValue);
       
   166     static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue);
       
   167     static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue);
       
   168     static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue);
       
   169     static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue);
       
   170     static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue);
       
   171     static inline JSC::UString toString(JSC::ExecState *, JSC::JSValue);
       
   172 
       
   173     static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue);
       
   174 #ifndef QT_NO_REGEXP
       
   175     static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue);
       
   176 #endif
       
   177     static QVariant toVariant(JSC::ExecState *, JSC::JSValue);
       
   178     static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue);
       
   179     static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue);
       
   180 
       
   181     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id,
       
   182                                  int resolveMode = QScriptValue::ResolvePrototype);
       
   183     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode);
       
   184     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index,
       
   185                                  int resolveMode = QScriptValue::ResolvePrototype);
       
   186     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode);
       
   187     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::UString &, int resolveMode);
       
   188     static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::UString &name, JSC::JSValue,
       
   189                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
       
   190     static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue,
       
   191                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
       
   192     static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue,
       
   193                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
       
   194     static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
       
   195                                               const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode);
       
   196     static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
       
   197                                               const JSC::UString &name, const QScriptValue::ResolveFlags &mode);
       
   198 
       
   199     static bool convertValue(JSC::ExecState*, JSC::JSValue value,
       
   200                              int type, void *ptr);
       
   201     static bool convertNumber(qsreal, int type, void *ptr);
       
   202     static bool convertString(const QString &, int type, void *ptr);
       
   203     static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr);
   121     bool hasDemarshalFunction(int type) const;
   204     bool hasDemarshalFunction(int type) const;
   122 
   205 
   123     inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
   206     inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
   124     inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
   207     inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
   125 
   208 
   126     QScriptValue scriptValueFromVariant(const QVariant &value);
   209     static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value);
   127     QVariant scriptValueToVariant(const QScriptValue &value, int targetType);
   210     static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType);
   128 
   211     static inline QVariant &variantValue(JSC::JSValue value);
   129     JSC::JSValue jscValueFromVariant(const QVariant &value);
   212     static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value);
   130     QVariant jscValueToVariant(JSC::JSValue value, int targetType);
   213 
   131 
   214     static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst);
   132     QScriptValue arrayFromStringList(const QStringList &lst);
   215     static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr);
   133     static QStringList stringListFromArray(const QScriptValue &arr);
   216 
   134 
   217     static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst);
   135     QScriptValue arrayFromVariantList(const QVariantList &lst);
   218     static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSValue arr);
   136     static QVariantList variantListFromArray(const QScriptValue &arr);
   219 
   137 
   220     static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap);
   138     QScriptValue objectFromVariantMap(const QVariantMap &vmap);
   221     static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSValue obj);
   139     static QVariantMap variantMapFromObject(const QScriptValue &obj);
       
   140 
   222 
   141     JSC::JSValue defaultPrototype(int metaTypeId) const;
   223     JSC::JSValue defaultPrototype(int metaTypeId) const;
   142     void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
   224     void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
   143 
   225 
   144     static inline QScriptContext *contextForFrame(JSC::ExecState *frame);
   226     static inline QScriptContext *contextForFrame(JSC::ExecState *frame);
   160     void popContext();
   242     void popContext();
   161 
   243 
   162     void mark(JSC::MarkStack& markStack);
   244     void mark(JSC::MarkStack& markStack);
   163     bool isCollecting() const;
   245     bool isCollecting() const;
   164     void collectGarbage();
   246     void collectGarbage();
       
   247     void reportAdditionalMemoryCost(int size);
   165 
   248 
   166     //flags that we set on the return value register for native function. (ie when codeBlock is 0)
   249     //flags that we set on the return value register for native function. (ie when codeBlock is 0)
   167     enum ContextFlags {
   250     enum ContextFlags {
   168         NativeContext = 1,
   251         NativeContext = 1,
   169         CalledAsConstructorContext = 2,
   252         CalledAsConstructorContext = 2,
   175 
   258 
   176     QScript::TimeoutCheckerProxy *timeoutChecker() const;
   259     QScript::TimeoutCheckerProxy *timeoutChecker() const;
   177 
   260 
   178     void agentDeleted(QScriptEngineAgent *agent);
   261     void agentDeleted(QScriptEngineAgent *agent);
   179 
   262 
       
   263     static inline void saveException(JSC::ExecState *, JSC::JSValue *);
       
   264     static inline void restoreException(JSC::ExecState *, JSC::JSValue);
       
   265 
   180     void setCurrentException(QScriptValue exception) { m_currentException = exception; }
   266     void setCurrentException(QScriptValue exception) { m_currentException = exception; }
   181     QScriptValue currentException() const { return m_currentException; }
   267     QScriptValue currentException() const { return m_currentException; }
   182     void clearCurrentException() { m_currentException.d_ptr.reset(); }
   268     void clearCurrentException() { m_currentException.d_ptr.reset(); }
       
   269 
       
   270     static QScriptSyntaxCheckResult checkSyntax(const QString &program);
       
   271     static bool canEvaluate(const QString &program);
       
   272 
       
   273     inline QScriptValuePrivate *allocateScriptValuePrivate(size_t);
       
   274     inline void freeScriptValuePrivate(QScriptValuePrivate *p);
       
   275 
       
   276     inline void registerScriptValue(QScriptValuePrivate *value);
       
   277     inline void unregisterScriptValue(QScriptValuePrivate *value);
       
   278     void detachAllRegisteredScriptValues();
       
   279 
       
   280     inline void registerScriptString(QScriptStringPrivate *value);
       
   281     inline void unregisterScriptString(QScriptStringPrivate *value);
       
   282     void detachAllRegisteredScriptStrings();
       
   283     QScriptString toStringHandle(const JSC::Identifier &name);
       
   284 
       
   285     static inline JSC::JSValue newArray(JSC::ExecState *, uint length);
       
   286     static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value);
       
   287     static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &);
       
   288     inline JSC::JSValue newObject();
       
   289 
       
   290 #ifndef QT_NO_REGEXP
       
   291     static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &);
       
   292 #endif
       
   293 
       
   294     static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags);
       
   295     JSC::JSValue newVariant(const QVariant &);
       
   296     JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &);
       
   297 
       
   298     static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue);
       
   299     static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue);
       
   300 
       
   301     JSC::UString translationContextFromUrl(const JSC::UString &);
   183 
   302 
   184 #ifndef QT_NO_QOBJECT
   303 #ifndef QT_NO_QOBJECT
   185     JSC::JSValue newQObject(QObject *object,
   304     JSC::JSValue newQObject(QObject *object,
   186         QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership,
   305         QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership,
   187         const QScriptEngine:: QObjectWrapOptions &options = 0);
   306         const QScriptEngine:: QObjectWrapOptions &options = 0);
   188     JSC::JSValue newQMetaObject(const QMetaObject *metaObject,
   307     JSC::JSValue newQMetaObject(const QMetaObject *metaObject,
   189                                 JSC::JSValue ctor);
   308                                 JSC::JSValue ctor);
   190 
   309 
   191     static QScriptSyntaxCheckResult checkSyntax(const QString &program);
   310     static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue,
   192     static bool canEvaluate(const QString &program);
       
   193     static bool convertToNativeQObject(const QScriptValue &value,
       
   194                                        const QByteArray &targetType,
   311                                        const QByteArray &targetType,
   195                                        void **result);
   312                                        void **result);
   196 
   313 
   197     JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId,
   314     JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId,
   198                                 JSC::EvalExecutable *executable,
   315                                 JSC::EvalExecutable *executable,
   217 
   334 
   218     bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver,
   335     bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver,
   219                        JSC::JSValue function, Qt::ConnectionType type);
   336                        JSC::JSValue function, Qt::ConnectionType type);
   220     bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver,
   337     bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver,
   221                           JSC::JSValue function);
   338                           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 
   339 
   234     // private slots
   340     // private slots
   235     void _q_objectDestroyed(QObject *);
   341     void _q_objectDestroyed(QObject *);
   236 #endif
   342 #endif
   237 
   343 
   261     QHash<int, QScriptTypeInfo*> m_typeInfos;
   367     QHash<int, QScriptTypeInfo*> m_typeInfos;
   262     int processEventsInterval;
   368     int processEventsInterval;
   263     QScriptValue abortResult;
   369     QScriptValue abortResult;
   264     bool inEval;
   370     bool inEval;
   265 
   371 
       
   372     JSC::UString cachedTranslationUrl;
       
   373     JSC::UString cachedTranslationContext;
       
   374 
   266     QSet<QString> importedExtensions;
   375     QSet<QString> importedExtensions;
   267     QSet<QString> extensionsBeingImported;
   376     QSet<QString> extensionsBeingImported;
   268     
   377     
   269     QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
   378     QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
   270     QScriptValue m_currentException;
   379     QScriptValue m_currentException;
   278 #endif
   387 #endif
   279 };
   388 };
   280 
   389 
   281 namespace QScript
   390 namespace QScript
   282 {
   391 {
       
   392 
       
   393 class APIShim
       
   394 {
       
   395 public:
       
   396     APIShim(QScriptEnginePrivate *engine)
       
   397         : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable))
       
   398     {
       
   399     }
       
   400     ~APIShim()
       
   401     {
       
   402         JSC::setCurrentIdentifierTable(m_oldTable);
       
   403     }
       
   404 
       
   405 private:
       
   406     QScriptEnginePrivate *m_engine;
       
   407     JSC::IdentifierTable *m_oldTable;
       
   408 };
   283 
   409 
   284 /*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
   410 /*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
   411   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.*/
   412   this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/
   287 class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider
   413 class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider
   370 inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec)
   496 inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec)
   371 {
   497 {
   372     return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine;
   498     return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine;
   373 }
   499 }
   374 
   500 
       
   501 #ifndef Q_CC_MSVC
       
   502 // MSVC2008 crashes if these are inlined.
       
   503 
       
   504 inline QString ToString(qsreal value)
       
   505 {
       
   506     return JSC::UString::from(value);
       
   507 }
       
   508 
       
   509 inline qsreal ToNumber(const QString &value)
       
   510 {
       
   511     return ((JSC::UString)value).toDouble();
       
   512 }
       
   513 
       
   514 #endif
       
   515 
       
   516 inline qint32 ToInt32(const QString &value)
       
   517 {
       
   518     return ToInt32(ToNumber(value));
       
   519 }
       
   520 
       
   521 inline quint32 ToUInt32(const QString &value)
       
   522 {
       
   523     return ToUInt32(ToNumber(value));
       
   524 }
       
   525 
       
   526 inline quint16 ToUInt16(const QString &value)
       
   527 {
       
   528     return ToUInt16(ToNumber(value));
       
   529 }
       
   530 
       
   531 inline qsreal ToInteger(const QString &value)
       
   532 {
       
   533     return ToInteger(ToNumber(value));
       
   534 }
       
   535 
       
   536 inline bool ToBool(qsreal value)
       
   537 {
       
   538     return (value != 0) && !qIsNaN(value);
       
   539 }
       
   540 
       
   541 inline bool ToBool(const QString &value)
       
   542 {
       
   543      return !value.isEmpty();
       
   544 }
       
   545 
       
   546 inline void convertToLatin1_helper(const UChar *i, int length, char *s)
       
   547 {
       
   548     const UChar *e = i + length;
       
   549     while (i != e)
       
   550         *(s++) = (uchar) *(i++);
       
   551     *s = '\0';
       
   552 }
       
   553 
       
   554 inline QByteArray convertToLatin1(const JSC::UString &str)
       
   555 {
       
   556     QByteArray ba(str.size(), Qt::Uninitialized);
       
   557     convertToLatin1_helper(str.data(), str.size(), ba.data());
       
   558     return ba;
       
   559 }
       
   560 
   375 } // namespace QScript
   561 } // namespace QScript
   376 
   562 
   377 inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
   563 inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
   378 {
   564 {
   379     if (freeScriptValues) {
   565     if (freeScriptValues) {
   413         value->next->prev = value->prev;
   599         value->next->prev = value->prev;
   414     if (value == registeredScriptValues)
   600     if (value == registeredScriptValues)
   415         registeredScriptValues = value->next;
   601         registeredScriptValues = value->next;
   416     value->prev = 0;
   602     value->prev = 0;
   417     value->next = 0;
   603     value->next = 0;
       
   604 }
       
   605 
       
   606 inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v)
       
   607 {
       
   608     JSC::JSValue result = create(exec, v.userType(), v.data());
       
   609     Q_ASSERT(result);
       
   610     return result;
   418 }
   611 }
   419 
   612 
   420 inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value)
   613 inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value)
   421 {
   614 {
   422     if (!value)
   615     if (!value)
   476     stringValue = value;
   669     stringValue = value;
   477     if (engine)
   670     if (engine)
   478         engine->registerScriptValue(this);
   671         engine->registerScriptValue(this);
   479 }
   672 }
   480 
   673 
   481 inline QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const
   674 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::UString &name, int resolveMode)
   482 {
   675 {
   483     JSC::ExecState *exec = engine->currentFrame;
   676     return property(exec, value, JSC::Identifier(exec, name), resolveMode);
   484     return property(JSC::Identifier(exec, name), resolveMode);
   677 }
   485 }
   678 
   486 
   679 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
   487 inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const
   680 {
   488 {
   681     Q_ASSERT(isObject(value));
   489     Q_ASSERT(isObject());
   682     JSC::JSObject *object = JSC::asObject(value);
   490     JSC::ExecState *exec = engine->currentFrame;
       
   491     JSC::JSObject *object = JSC::asObject(jscValue);
       
   492     JSC::PropertySlot slot(object);
   683     JSC::PropertySlot slot(object);
   493     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot))
   684     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot))
   494         return engine->scriptValueFromJSCValue(slot.getValue(exec, id));
   685         return slot.getValue(exec, id);
   495     return propertyHelper(id, resolveMode);
   686     return propertyHelper(exec, value, id, resolveMode);
   496 }
   687 }
   497 
   688 
   498 inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
   689 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
   499 {
   690 {
   500     Q_ASSERT(isObject());
   691     Q_ASSERT(isObject(value));
   501     JSC::ExecState *exec = engine->currentFrame;
   692     JSC::JSObject *object = JSC::asObject(value);
   502     JSC::JSObject *object = JSC::asObject(jscValue);
       
   503     JSC::PropertySlot slot(object);
   693     JSC::PropertySlot slot(object);
   504     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot))
   694     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot))
   505         return engine->scriptValueFromJSCValue(slot.getValue(exec, index));
   695         return slot.getValue(exec, index);
   506     return propertyHelper(index, resolveMode);
   696     return propertyHelper(exec, value, index, resolveMode);
       
   697 }
       
   698 
       
   699 inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value,
       
   700                                                                        const JSC::UString &name,
       
   701                                                                        const QScriptValue::ResolveFlags &mode)
       
   702 {
       
   703     return propertyFlags(exec, value, JSC::Identifier(exec, name), mode);
       
   704 }
       
   705 
       
   706 inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::UString &name,
       
   707                                               JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
       
   708 {
       
   709     setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags);
       
   710 }
       
   711 
       
   712 inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, const QScriptValue::ResolveFlags &resolveMode) const
       
   713 {
       
   714     return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode);
       
   715 }
       
   716 
       
   717 inline JSC::JSValue QScriptValuePrivate::property(quint32 index, const QScriptValue::ResolveFlags &resolveMode) const
       
   718 {
       
   719     return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode);
       
   720 }
       
   721 
       
   722 inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, const QScriptValue::ResolveFlags &resolveMode) const
       
   723 {
       
   724     JSC::ExecState *exec = engine->currentFrame;
       
   725     return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode);
       
   726 }
       
   727 
       
   728 inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(
       
   729         const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const
       
   730 {
       
   731     return QScriptEnginePrivate::propertyFlags(engine->currentFrame, jscValue, id, mode);
       
   732 }
       
   733 
       
   734 inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value,
       
   735                                              const QScriptValue::PropertyFlags &flags)
       
   736 {
       
   737     QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, id, value, flags);
       
   738 }
       
   739 
       
   740 inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value,
       
   741                                              const QScriptValue::PropertyFlags &flags)
       
   742 {
       
   743     QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags);
       
   744 }
       
   745 
       
   746 inline void QScriptValuePrivate::setProperty(const JSC::UString &name, const JSC::JSValue &value,
       
   747                                              const QScriptValue::PropertyFlags &flags)
       
   748 {
       
   749     JSC::ExecState *exec = engine->currentFrame;
       
   750     QScriptEnginePrivate::setProperty(exec, jscValue, JSC::Identifier(exec, name), value, flags);
   507 }
   751 }
   508 
   752 
   509 inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine)
   753 inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine)
   510 {
   754 {
   511     if (engine)
   755     if (engine)
   520         d->engine->freeScriptValuePrivate(d);
   764         d->engine->freeScriptValuePrivate(d);
   521     else
   765     else
   522         qFree(d);
   766         qFree(d);
   523 }
   767 }
   524 
   768 
   525 inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
   769 inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
   526 {
   770 {
   527     if (exec) {
   771     if (exec) {
   528         *val = exec->exception();
   772         *val = exec->exception();
   529         exec->clearException();
   773         exec->clearException();
   530     } else {
   774     } else {
   531         *val = JSC::JSValue();
   775         *val = JSC::JSValue();
   532     }
   776     }
   533 }
   777 }
   534 
   778 
   535 inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
   779 inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
   536 {
   780 {
   537     if (exec && val)
   781     if (exec && val)
   538         exec->setException(val);
   782         exec->setException(val);
   539 }
   783 }
   540 
   784 
   584 inline JSC::ExecState *QScriptEnginePrivate::globalExec() const
   828 inline JSC::ExecState *QScriptEnginePrivate::globalExec() const
   585 {
   829 {
   586     return originalGlobalObject()->globalExec();
   830     return originalGlobalObject()->globalExec();
   587 }
   831 }
   588 
   832 
       
   833 inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length)
       
   834 {
       
   835     return JSC::constructEmptyArray(exec, length);
       
   836 }
       
   837 
       
   838 inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value)
       
   839 {
       
   840     JSC::JSValue val = JSC::jsNumber(exec, value);
       
   841     JSC::ArgList args(&val, 1);
       
   842     return JSC::constructDate(exec, args);
       
   843 }
       
   844 
       
   845 inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value)
       
   846 {
       
   847     return newDate(exec, QScript::FromDateTime(value));
       
   848 }
       
   849 
       
   850 inline JSC::JSValue QScriptEnginePrivate::newObject()
       
   851 {
       
   852     return new (currentFrame)QScriptObject(scriptObjectStructure);
       
   853 }
       
   854 
       
   855 inline bool QScriptEnginePrivate::isObject(JSC::JSValue value)
       
   856 {
       
   857     return value && value.isObject();
       
   858 }
       
   859 
       
   860 inline bool QScriptEnginePrivate::isArray(JSC::JSValue value)
       
   861 {
       
   862     return isObject(value) && value.inherits(&JSC::JSArray::info);
       
   863 }
       
   864 
       
   865 inline bool QScriptEnginePrivate::isDate(JSC::JSValue value)
       
   866 {
       
   867     return isObject(value) && value.inherits(&JSC::DateInstance::info);
       
   868 }
       
   869 
       
   870 inline bool QScriptEnginePrivate::isError(JSC::JSValue value)
       
   871 {
       
   872     return isObject(value) && value.inherits(&JSC::ErrorInstance::info);
       
   873 }
       
   874 
       
   875 inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value)
       
   876 {
       
   877     return isObject(value) && value.inherits(&JSC::RegExpObject::info);
       
   878 }
       
   879 
       
   880 inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value)
       
   881 {
       
   882     if (!isObject(value) || !value.inherits(&QScriptObject::info))
       
   883         return false;
       
   884     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
       
   885     QScriptObjectDelegate *delegate = object->delegate();
       
   886     return (delegate && (delegate->type() == QScriptObjectDelegate::Variant));
       
   887 }
       
   888 
       
   889 inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value)
       
   890 {
       
   891 #ifndef QT_NO_QOBJECT
       
   892     if (!isObject(value) || !value.inherits(&QScriptObject::info))
       
   893         return false;
       
   894     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
       
   895     QScriptObjectDelegate *delegate = object->delegate();
       
   896     return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject ||
       
   897                          (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject &&
       
   898                           static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject())));
       
   899 #else
       
   900     return false;
       
   901 #endif
       
   902 }
       
   903 
       
   904 inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value)
       
   905 {
       
   906 #ifndef QT_NO_QOBJECT
       
   907     return isObject(value) && JSC::asObject(value)->inherits(&QScript::QMetaObjectWrapperObject::info);
       
   908 #else
       
   909     return false;
       
   910 #endif
       
   911 }
       
   912 
       
   913 inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value)
       
   914 {
       
   915     JSC::JSValue savedException;
       
   916     saveException(exec, &savedException);
       
   917     bool result = value.toBoolean(exec);
       
   918     restoreException(exec, savedException);
       
   919     return result;
       
   920 }
       
   921 
       
   922 inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value)
       
   923 {
       
   924     JSC::JSValue savedException;
       
   925     saveException(exec, &savedException);
       
   926     qsreal result = value.toInteger(exec);
       
   927     restoreException(exec, savedException);
       
   928     return result;
       
   929 }
       
   930 
       
   931 inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value)
       
   932 {
       
   933     JSC::JSValue savedException;
       
   934     saveException(exec, &savedException);
       
   935     qsreal result = value.toNumber(exec);
       
   936     restoreException(exec, savedException);
       
   937     return result;
       
   938 }
       
   939 
       
   940 inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value)
       
   941 {
       
   942     JSC::JSValue savedException;
       
   943     saveException(exec, &savedException);
       
   944     qint32 result = value.toInt32(exec);
       
   945     restoreException(exec, savedException);
       
   946     return result;
       
   947 }
       
   948 
       
   949 inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value)
       
   950 {
       
   951     JSC::JSValue savedException;
       
   952     saveException(exec, &savedException);
       
   953     quint32 result = value.toUInt32(exec);
       
   954     restoreException(exec, savedException);
       
   955     return result;
       
   956 }
       
   957 
       
   958 inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value)
       
   959 {
       
   960     // ### no equivalent function in JSC
       
   961     return QScript::ToUInt16(toNumber(exec, value));
       
   962 }
       
   963 
       
   964 inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value)
       
   965 {
       
   966     JSC::JSValue savedException;
       
   967     saveException(exec, &savedException);
       
   968     JSC::UString str = value.toString(exec);
       
   969     if (exec && exec->hadException() && !str.size()) {
       
   970         JSC::JSValue savedException2;
       
   971         saveException(exec, &savedException2);
       
   972         str = savedException2.toString(exec);
       
   973         restoreException(exec, savedException2);
       
   974     }
       
   975     if (savedException)
       
   976         restoreException(exec, savedException);
       
   977     return str;
       
   978 }
       
   979 
       
   980 inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue value)
       
   981 {
       
   982     if (!isDate(value))
       
   983         return QDateTime();
       
   984     qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber();
       
   985     return QScript::ToDateTime(t, Qt::LocalTime);
       
   986 }
       
   987 
       
   988 inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value)
       
   989 {
       
   990 #ifndef QT_NO_QOBJECT
       
   991     if (isObject(value) && value.inherits(&QScriptObject::info)) {
       
   992         QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
       
   993         QScriptObjectDelegate *delegate = object->delegate();
       
   994         if (!delegate)
       
   995             return 0;
       
   996         if (delegate->type() == QScriptObjectDelegate::QtObject)
       
   997             return static_cast<QScript::QObjectDelegate*>(delegate)->value();
       
   998         if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject)
       
   999             return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(declarativeObject(value));
       
  1000         if (delegate->type() == QScriptObjectDelegate::Variant) {
       
  1001             QVariant var = variantValue(value);
       
  1002             int type = var.userType();
       
  1003             if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar))
       
  1004                 return *reinterpret_cast<QObject* const *>(var.constData());
       
  1005         }
       
  1006     }
       
  1007 #endif
       
  1008     return 0;
       
  1009 }
       
  1010 
       
  1011 inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value)
       
  1012 {
       
  1013 #ifndef QT_NO_QOBJECT
       
  1014     if (isQMetaObject(value))
       
  1015         return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(value))->value();
       
  1016 #endif
       
  1017     return 0;
       
  1018 }
       
  1019 
       
  1020 inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value)
       
  1021 {
       
  1022     Q_ASSERT(value.inherits(&QScriptObject::info));
       
  1023     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value))->delegate();
       
  1024     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
       
  1025     return static_cast<QScript::QVariantDelegate*>(delegate)->value();
       
  1026 }
       
  1027 
       
  1028 inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value)
       
  1029 {
       
  1030     Q_ASSERT(objectValue.inherits(&QScriptObject::info));
       
  1031     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(objectValue))->delegate();
       
  1032     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
       
  1033     static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
       
  1034 }
       
  1035 
       
  1036 inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v)
       
  1037 {
       
  1038     if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
       
  1039         return 0;
       
  1040     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
       
  1041     QScriptObjectDelegate *delegate = scriptObject->delegate();
       
  1042     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
       
  1043         return 0;
       
  1044     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass();
       
  1045 }
       
  1046 
       
  1047 inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v)
       
  1048 {
       
  1049     if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
       
  1050         return 0;
       
  1051     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
       
  1052     QScriptObjectDelegate *delegate = scriptObject->delegate();
       
  1053     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
       
  1054         return 0;
       
  1055     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object();
       
  1056 }
       
  1057 
   589 QT_END_NAMESPACE
  1058 QT_END_NAMESPACE
   590 
  1059 
   591 #endif
  1060 #endif