| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2015 The Qt Company Ltd. | 
| 4 | ** Contact: http://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the QtScript module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU Lesser General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | 
| 21 | ** packaging of this file. Please review the following information to | 
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | 
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | 
| 24 | ** | 
| 25 | ** GNU General Public License Usage | 
| 26 | ** Alternatively, this file may be used under the terms of the GNU | 
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | 
| 28 | ** Public license version 3 or any later version approved by the KDE Free | 
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | 
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | 
| 31 | ** included in the packaging of this file. Please review the following | 
| 32 | ** information to ensure the GNU General Public License requirements will | 
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | 
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | 
| 35 | ** | 
| 36 | ** $QT_END_LICENSE$ | 
| 37 | ** | 
| 38 | ****************************************************************************/ | 
| 39 |  | 
| 40 | #ifndef QSCRIPTENGINE_P_H | 
| 41 | #define QSCRIPTENGINE_P_H | 
| 42 |  | 
| 43 | // | 
| 44 | //  W A R N I N G | 
| 45 | //  ------------- | 
| 46 | // | 
| 47 | // This file is not part of the Qt API.  It exists purely as an | 
| 48 | // implementation detail.  This header file may change from version to | 
| 49 | // version without notice, or even be removed. | 
| 50 | // | 
| 51 | // We mean it. | 
| 52 | // | 
| 53 |  | 
| 54 | #include "private/qobject_p.h" | 
| 55 |  | 
| 56 | #include <QtCore/qdatetime.h> | 
| 57 | #include <QtCore/qhash.h> | 
| 58 | #include <QtCore/qnumeric.h> | 
| 59 | #include <QtCore/qregexp.h> | 
| 60 | #include <QtCore/qset.h> | 
| 61 | #include <QtCore/qstringlist.h> | 
| 62 | #include "qscriptvalue_p.h" | 
| 63 | #include "qscriptstring_p.h" | 
| 64 | #include "bridge/qscriptclassobject_p.h" | 
| 65 | #include "bridge/qscriptdeclarativeclass_p.h" | 
| 66 | #include "bridge/qscriptdeclarativeobject_p.h" | 
| 67 | #include "bridge/qscriptobject_p.h" | 
| 68 | #include "bridge/qscriptqobject_p.h" | 
| 69 | #include "bridge/qscriptvariant_p.h" | 
| 70 | #include "bridge/qscriptactivationobject_p.h" | 
| 71 |  | 
| 72 | #include "DateConstructor.h" | 
| 73 | #include "DateInstance.h" | 
| 74 | #include "Debugger.h" | 
| 75 | #include "ErrorInstance.h" | 
| 76 | #include "JSArray.h" | 
| 77 | #include "Executable.h" | 
| 78 | #include "Lexer.h" | 
| 79 | #include "RefPtr.h" | 
| 80 | #include "RegExpConstructor.h" | 
| 81 | #include "RegExpObject.h" | 
| 82 | #include "SourceProvider.h" | 
| 83 | #include "Structure.h" | 
| 84 | #include "UString.h" | 
| 85 | #include "JSGlobalObject.h" | 
| 86 | #include "JSValue.h" | 
| 87 |  | 
| 88 | #include <stdlib.h> | 
| 89 |  | 
| 90 | namespace JSC | 
| 91 | { | 
| 92 |     class EvalExecutable; | 
| 93 |     class ExecState; | 
| 94 |     typedef ExecState CallFrame; | 
| 95 |     class JSCell; | 
| 96 |     class JSGlobalObject; | 
| 97 | } | 
| 98 |  | 
| 99 |  | 
| 100 | QT_BEGIN_NAMESPACE | 
| 101 |  | 
| 102 | class QString; | 
| 103 | class QStringList; | 
| 104 | class QScriptContext; | 
| 105 | class QScriptValue; | 
| 106 | class QScriptTypeInfo; | 
| 107 | class QScriptEngineAgent; | 
| 108 | class QScriptEnginePrivate; | 
| 109 | class QScriptSyntaxCheckResult; | 
| 110 | class QScriptEngine; | 
| 111 | class QScriptProgramPrivate; | 
| 112 |  | 
| 113 | namespace QScript | 
| 114 | { | 
| 115 |     class QObjectPrototype; | 
| 116 |     class QMetaObjectPrototype; | 
| 117 |     class QVariantPrototype; | 
| 118 | #ifndef QT_NO_QOBJECT | 
| 119 |     class QObjectData; | 
| 120 | #endif | 
| 121 |     class TimeoutCheckerProxy; | 
| 122 |  | 
| 123 |     qint32 ToInt32(qsreal); | 
| 124 |     quint32 ToUInt32(qsreal); | 
| 125 |     quint16 ToUInt16(qsreal); | 
| 126 |     qsreal ToInteger(qsreal); | 
| 127 |  | 
| 128 |     inline bool ToBool(qsreal); | 
| 129 |     inline bool ToBool(const QString &); | 
| 130 |     inline qint32 ToInt32(const QString &); | 
| 131 |     inline quint32 ToUInt32(const QString &); | 
| 132 |     inline quint16 ToUInt16(const QString &); | 
| 133 |     inline qsreal ToInteger(const QString &); | 
| 134 | #ifdef Q_CC_MSVC | 
| 135 |     // MSVC2008 crashes if these are inlined. | 
| 136 |     qsreal ToNumber(const QString &); | 
| 137 |     QString ToString(qsreal); | 
| 138 | #else | 
| 139 |     inline qsreal ToNumber(const QString &); | 
| 140 |     inline QString ToString(qsreal); | 
| 141 | #endif | 
| 142 |  | 
| 143 |     QDateTime MsToDateTime(JSC::ExecState *, qsreal); | 
| 144 |     qsreal DateTimeToMs(JSC::ExecState *, const QDateTime &); | 
| 145 |  | 
| 146 |     //some conversion helper functions | 
| 147 |     inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); | 
| 148 |     bool isFunction(JSC::JSValue value); | 
| 149 |  | 
| 150 |     inline void convertToLatin1_helper(const UChar *i, int length, char *s); | 
| 151 |     inline QByteArray convertToLatin1(const JSC::UString &str); | 
| 152 |  | 
| 153 |     class UStringSourceProviderWithFeedback; | 
| 154 |  | 
| 155 | struct GlobalClientData : public JSC::JSGlobalData::ClientData | 
| 156 | { | 
| 157 |     GlobalClientData(QScriptEnginePrivate *e) | 
| 158 |         : engine(e) {} | 
| 159 |     virtual ~GlobalClientData() {} | 
| 160 |     virtual void mark(JSC::MarkStack& markStack); | 
| 161 |     virtual void uncaughtException(JSC::ExecState*, unsigned bytecodeOffset, | 
| 162 |                                    JSC::JSValue); | 
| 163 |  | 
| 164 |     QScriptEnginePrivate *engine; | 
| 165 | }; | 
| 166 |  | 
| 167 | } // namespace QScript | 
| 168 |  | 
| 169 | class QScriptEnginePrivate | 
| 170 | #ifndef QT_NO_QOBJECT | 
| 171 |     : public QObjectPrivate | 
| 172 | #endif | 
| 173 | { | 
| 174 |     Q_DECLARE_PUBLIC(QScriptEngine) | 
| 175 | public: | 
| 176 |     QScriptEnginePrivate(); | 
| 177 |     virtual ~QScriptEnginePrivate(); | 
| 178 |  | 
| 179 |     static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; } | 
| 180 |     static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; } | 
| 181 |  | 
| 182 |     static inline bool isArray(JSC::JSValue); | 
| 183 |     static inline bool isDate(JSC::JSValue); | 
| 184 |     static inline bool isError(JSC::JSValue); | 
| 185 |     static inline bool isObject(JSC::JSValue); | 
| 186 |     static inline bool isRegExp(JSC::JSValue); | 
| 187 |     static inline bool isVariant(JSC::JSValue); | 
| 188 |     static inline bool isQObject(JSC::JSValue); | 
| 189 |     static inline bool isQMetaObject(JSC::JSValue); | 
| 190 |  | 
| 191 |     static inline bool toBool(JSC::ExecState *, JSC::JSValue); | 
| 192 |     static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue); | 
| 193 |     static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue); | 
| 194 |     static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue); | 
| 195 |     static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue); | 
| 196 |     static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue); | 
| 197 |     static inline JSC::UString toString(JSC::ExecState *, JSC::JSValue); | 
| 198 |  | 
| 199 |     static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); | 
| 200 | #ifndef QT_NO_REGEXP | 
| 201 |     static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue); | 
| 202 | #endif | 
| 203 |     static QVariant toVariant(JSC::ExecState *, JSC::JSValue); | 
| 204 |     static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue); | 
| 205 |     static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue); | 
| 206 |  | 
| 207 |     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, | 
| 208 |                                  int resolveMode = QScriptValue::ResolvePrototype); | 
| 209 |     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode); | 
| 210 |     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index, | 
| 211 |                                  int resolveMode = QScriptValue::ResolvePrototype); | 
| 212 |     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode); | 
| 213 |     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::UString &, int resolveMode); | 
| 214 |     static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::UString &name, JSC::JSValue, | 
| 215 |                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); | 
| 216 |     static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue, | 
| 217 |                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); | 
| 218 |     static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue, | 
| 219 |                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); | 
| 220 |     static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, | 
| 221 |                                               const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode); | 
| 222 |     static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, | 
| 223 |                                               const JSC::UString &name, const QScriptValue::ResolveFlags &mode); | 
| 224 |  | 
| 225 |     static bool convertValue(JSC::ExecState*, JSC::JSValue value, | 
| 226 |                              int type, void *ptr); | 
| 227 |     static bool convertNumber(qsreal, int type, void *ptr); | 
| 228 |     static bool convertString(const QString &, int type, void *ptr); | 
| 229 |     static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr); | 
| 230 |     bool hasDemarshalFunction(int type) const; | 
| 231 |  | 
| 232 |     inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value); | 
| 233 |     inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value); | 
| 234 |     static inline unsigned propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags); | 
| 235 |  | 
| 236 |     static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value); | 
| 237 |     static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType); | 
| 238 |     static inline QVariant &variantValue(JSC::JSValue value); | 
| 239 |     static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value); | 
| 240 |  | 
| 241 |     static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst); | 
| 242 |     static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr); | 
| 243 |  | 
| 244 |     static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst); | 
| 245 |     static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSArray *arr); | 
| 246 |  | 
| 247 |     static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap); | 
| 248 |     static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSObject *obj); | 
| 249 |  | 
| 250 |     JSC::JSValue defaultPrototype(int metaTypeId) const; | 
| 251 |     void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype); | 
| 252 |  | 
| 253 |     static inline QScriptContext *contextForFrame(JSC::ExecState *frame); | 
| 254 |     static inline JSC::ExecState *frameForContext(QScriptContext *context); | 
| 255 |     static inline const JSC::ExecState *frameForContext(const QScriptContext *context); | 
| 256 |  | 
| 257 |     static inline bool hasValidCodeBlockRegister(JSC::ExecState *frame); | 
| 258 |  | 
| 259 |     JSC::JSGlobalObject *originalGlobalObject() const; | 
| 260 |     JSC::JSObject *getOriginalGlobalObjectProxy(); | 
| 261 |     JSC::JSObject *customGlobalObject() const; | 
| 262 |     JSC::JSObject *globalObject() const; | 
| 263 |     void setGlobalObject(JSC::JSObject *object); | 
| 264 |     inline JSC::ExecState *globalExec() const; | 
| 265 |     JSC::JSValue toUsableValue(JSC::JSValue value); | 
| 266 |     static JSC::JSValue thisForContext(JSC::ExecState *frame); | 
| 267 |     static JSC::Register *thisRegisterForFrame(JSC::ExecState *frame); | 
| 268 |  | 
| 269 |     JSC::CallFrame *pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList& args, | 
| 270 |                                 JSC::JSObject *callee, bool calledAsConstructor = false); | 
| 271 |     void popContext(); | 
| 272 |  | 
| 273 |     void mark(JSC::MarkStack& markStack); | 
| 274 |     bool isCollecting() const; | 
| 275 |     void collectGarbage(); | 
| 276 |     void reportAdditionalMemoryCost(int size); | 
| 277 |  | 
| 278 |     //flags that we set on the return value register for native function. (ie when codeBlock is 0) | 
| 279 |     enum ContextFlags { | 
| 280 |         NativeContext = 1, | 
| 281 |         CalledAsConstructorContext = 2, | 
| 282 |         HasScopeContext = 4, // Specifies that the is a QScriptActivationObject | 
| 283 |         ShouldRestoreCallFrame = 8 | 
| 284 |     }; | 
| 285 |     static uint contextFlags(JSC::ExecState *); | 
| 286 |     static void setContextFlags(JSC::ExecState *, uint); | 
| 287 |  | 
| 288 |     QScript::TimeoutCheckerProxy *timeoutChecker() const; | 
| 289 |  | 
| 290 |     void agentDeleted(QScriptEngineAgent *agent); | 
| 291 |  | 
| 292 |     static bool isLikelyStackOverflowError(JSC::ExecState *, JSC::JSValue); | 
| 293 |     void uncaughtException(JSC::ExecState *, unsigned bytecodeOffset, JSC::JSValue); | 
| 294 |  | 
| 295 |     static inline void saveException(JSC::ExecState *, JSC::JSValue *); | 
| 296 |     static inline void restoreException(JSC::ExecState *, JSC::JSValue); | 
| 297 |  | 
| 298 |     void setCurrentException(QScriptValue exception) { m_currentException = exception; } | 
| 299 |     QScriptValue currentException() const { return m_currentException; } | 
| 300 |     void clearCurrentException() | 
| 301 |     { | 
| 302 |         m_currentException.d_ptr.reset(); | 
| 303 |         uncaughtExceptionBacktrace.clear(); | 
| 304 |         uncaughtExceptionLineNumber = -1; | 
| 305 |     } | 
| 306 |  | 
| 307 |     static QScriptSyntaxCheckResult checkSyntax(const QString &program); | 
| 308 |     static bool canEvaluate(const QString &program); | 
| 309 |  | 
| 310 |     inline void registerScriptProgram(QScriptProgramPrivate *program); | 
| 311 |     inline void unregisterScriptProgram(QScriptProgramPrivate *program); | 
| 312 |     void detachAllRegisteredScriptPrograms(); | 
| 313 |  | 
| 314 |     inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); | 
| 315 |     inline void freeScriptValuePrivate(QScriptValuePrivate *p); | 
| 316 |  | 
| 317 |     inline void registerScriptValue(QScriptValuePrivate *value); | 
| 318 |     inline void unregisterScriptValue(QScriptValuePrivate *value); | 
| 319 |     void detachAllRegisteredScriptValues(); | 
| 320 |  | 
| 321 |     inline void registerScriptString(QScriptStringPrivate *value); | 
| 322 |     inline void unregisterScriptString(QScriptStringPrivate *value); | 
| 323 |     void detachAllRegisteredScriptStrings(); | 
| 324 |     QScriptString toStringHandle(const JSC::Identifier &name); | 
| 325 |  | 
| 326 |     static inline JSC::JSValue newArray(JSC::ExecState *, uint length); | 
| 327 |     static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value); | 
| 328 |     static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &); | 
| 329 |     inline JSC::JSValue newObject(); | 
| 330 |  | 
| 331 | #ifndef QT_NO_REGEXP | 
| 332 |     static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &); | 
| 333 | #endif | 
| 334 |  | 
| 335 |     static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags); | 
| 336 |     JSC::JSValue newVariant(const QVariant &); | 
| 337 |     JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &); | 
| 338 |  | 
| 339 |     static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue); | 
| 340 |     static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue); | 
| 341 |  | 
| 342 |     JSC::UString translationContextFromUrl(const JSC::UString &); | 
| 343 |  | 
| 344 | #ifndef QT_NO_QOBJECT | 
| 345 |     void markQObjectData(JSC::MarkStack&); | 
| 346 |     JSC::JSValue newQObject(QObject *object, | 
| 347 |         QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, | 
| 348 |                  const QScriptEngine:: QObjectWrapOptions &options = {}); | 
| 349 |     JSC::JSValue newQMetaObject(const QMetaObject *metaObject, | 
| 350 |                                 JSC::JSValue ctor); | 
| 351 |  | 
| 352 |     static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue, | 
| 353 |                                        const QByteArray &targetType, | 
| 354 |                                        void **result); | 
| 355 |  | 
| 356 |     JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId, | 
| 357 |                                 JSC::EvalExecutable *executable, | 
| 358 |                                 bool &compile); | 
| 359 |  | 
| 360 |     QScript::QObjectData *qobjectData(QObject *object); | 
| 361 |     void disposeQObject(QObject *object); | 
| 362 |     void emitSignalHandlerException(); | 
| 363 |  | 
| 364 |     bool scriptConnect(QObject *sender, const char *signal, | 
| 365 |                        JSC::JSValue receiver, JSC::JSValue function, | 
| 366 |                        Qt::ConnectionType type); | 
| 367 |     bool scriptDisconnect(QObject *sender, const char *signal, | 
| 368 |                           JSC::JSValue receiver, JSC::JSValue function); | 
| 369 |  | 
| 370 |     bool scriptConnect(QObject *sender, int index, | 
| 371 |                        JSC::JSValue receiver, JSC::JSValue function, | 
| 372 |                        JSC::JSValue senderWrapper, | 
| 373 |                        Qt::ConnectionType type); | 
| 374 |     bool scriptDisconnect(QObject *sender, int index, | 
| 375 |                           JSC::JSValue receiver, JSC::JSValue function); | 
| 376 |  | 
| 377 |     bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver, | 
| 378 |                        JSC::JSValue function, Qt::ConnectionType type); | 
| 379 |     bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, | 
| 380 |                           JSC::JSValue function); | 
| 381 |  | 
| 382 |     // private slots | 
| 383 |     void _q_objectDestroyed(QObject *); | 
| 384 | #endif | 
| 385 |  | 
| 386 |     JSC::JSGlobalData *globalData; | 
| 387 |     JSC::JSObject *originalGlobalObjectProxy; | 
| 388 |     JSC::ExecState *currentFrame; | 
| 389 |  | 
| 390 |     WTF::RefPtr<JSC::Structure> scriptObjectStructure; | 
| 391 |     WTF::RefPtr<JSC::Structure> staticScopeObjectStructure; | 
| 392 |  | 
| 393 |     QScript::QObjectPrototype *qobjectPrototype; | 
| 394 |     WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure; | 
| 395 |  | 
| 396 |     QScript::QMetaObjectPrototype *qmetaobjectPrototype; | 
| 397 |     WTF::RefPtr<JSC::Structure> qmetaobjectWrapperObjectStructure; | 
| 398 |  | 
| 399 |     QScript::QVariantPrototype *variantPrototype; | 
| 400 |     WTF::RefPtr<JSC::Structure> variantWrapperObjectStructure; | 
| 401 |  | 
| 402 |     QList<QScriptEngineAgent*> ownedAgents; | 
| 403 |     QScriptEngineAgent *activeAgent; | 
| 404 |     int agentLineNumber; | 
| 405 |     QScriptValuePrivate *registeredScriptValues; | 
| 406 |     QScriptValuePrivate *freeScriptValues; | 
| 407 |     static const int maxFreeScriptValues = 256; | 
| 408 |     int freeScriptValuesCount; | 
| 409 |     QScriptStringPrivate *registeredScriptStrings; | 
| 410 |     QSet<QScriptProgramPrivate*> registeredScriptPrograms; | 
| 411 |     QHash<int, QScriptTypeInfo*> m_typeInfos; | 
| 412 |     int processEventsInterval; | 
| 413 |     QScriptValue abortResult; | 
| 414 |     bool inEval; | 
| 415 |  | 
| 416 |     JSC::UString cachedTranslationUrl; | 
| 417 |     JSC::UString cachedTranslationContext; | 
| 418 |  | 
| 419 |     QSet<QString> importedExtensions; | 
| 420 |     QSet<QString> extensionsBeingImported; | 
| 421 |      | 
| 422 |     QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts; | 
| 423 |     QScriptValue m_currentException; | 
| 424 |     QStringList uncaughtExceptionBacktrace; | 
| 425 |     int uncaughtExceptionLineNumber; | 
| 426 |  | 
| 427 |     QSet<JSC::JSObject*> visitedConversionObjects; | 
| 428 |  | 
| 429 | #ifndef QT_NO_QOBJECT | 
| 430 |     QHash<QObject*, QScript::QObjectData*> m_qobjectData; | 
| 431 | #endif | 
| 432 |  | 
| 433 | #ifdef QT_NO_QOBJECT | 
| 434 |     QScriptEngine *q_ptr; | 
| 435 | #endif | 
| 436 | }; | 
| 437 |  | 
| 438 | namespace QScript | 
| 439 | { | 
| 440 |  | 
| 441 | class APIShim | 
| 442 | { | 
| 443 | public: | 
| 444 |     APIShim(QScriptEnginePrivate *engine) | 
| 445 |         : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable)) | 
| 446 |     { | 
| 447 |     } | 
| 448 |     ~APIShim() | 
| 449 |     { | 
| 450 |         JSC::setCurrentIdentifierTable(m_oldTable); | 
| 451 |     } | 
| 452 |  | 
| 453 | private: | 
| 454 |     QScriptEnginePrivate *m_engine; | 
| 455 |     JSC::IdentifierTable *m_oldTable; | 
| 456 | }; | 
| 457 |  | 
| 458 | /*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts. | 
| 459 |   It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update | 
| 460 |   this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/ | 
| 461 | class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider | 
| 462 | { | 
| 463 | public: | 
| 464 |     static PassRefPtr<UStringSourceProviderWithFeedback> create( | 
| 465 |         const JSC::UString& source, const JSC::UString& url, | 
| 466 |         int lineNumber, QScriptEnginePrivate* engine) | 
| 467 |     { | 
| 468 |         return adoptRef(p: new UStringSourceProviderWithFeedback(source, url, lineNumber, engine)); | 
| 469 |     } | 
| 470 |  | 
| 471 |     /* Destruction means that there is no more copies of script so create scriptUnload event | 
| 472 |        and unregister script in QScriptEnginePrivate::loadedScripts */ | 
| 473 |     virtual ~UStringSourceProviderWithFeedback() | 
| 474 |     { | 
| 475 |         if (m_ptr) { | 
| 476 |             if (JSC::Debugger* debugger = this->debugger()) | 
| 477 |                 debugger->scriptUnload(id: asID()); | 
| 478 |             m_ptr->loadedScripts.remove(akey: asID()); | 
| 479 |         } | 
| 480 |     } | 
| 481 |  | 
| 482 |     /* set internal QScriptEnginePrivate pointer to null and create unloadScript event, should be called | 
| 483 |        only if QScriptEnginePrivate is about to be  destroyed.*/ | 
| 484 |     void disconnectFromEngine() | 
| 485 |     { | 
| 486 |         if (JSC::Debugger* debugger = this->debugger()) | 
| 487 |             debugger->scriptUnload(id: asID()); | 
| 488 |         m_ptr = 0; | 
| 489 |     } | 
| 490 |  | 
| 491 |     int columnNumberFromOffset(int offset) const | 
| 492 |     { | 
| 493 |         for (const UChar *c = m_source.data() + offset; c >= m_source.data(); --c) { | 
| 494 |             if (JSC::Lexer::isLineTerminator(ch: *c)) | 
| 495 |                 return offset - static_cast<int>(c - data()); | 
| 496 |         } | 
| 497 |         return offset + 1; | 
| 498 |     } | 
| 499 |  | 
| 500 | protected: | 
| 501 |     UStringSourceProviderWithFeedback(const JSC::UString& source, const JSC::UString& url, | 
| 502 |                                       int lineNumber, QScriptEnginePrivate* engine) | 
| 503 |         : UStringSourceProvider(source, url), | 
| 504 |           m_ptr(engine) | 
| 505 |     { | 
| 506 |         if (JSC::Debugger* debugger = this->debugger()) | 
| 507 |             debugger->scriptLoad(id: asID(), program: source, fileName: url, baseLineNumber: lineNumber); | 
| 508 |         if (m_ptr) | 
| 509 |             m_ptr->loadedScripts.insert(akey: asID(), avalue: this); | 
| 510 |     } | 
| 511 |  | 
| 512 |     JSC::Debugger* debugger() | 
| 513 |     { | 
| 514 |         //if m_ptr is null it mean that QScriptEnginePrivate was destroyed and scriptUnload was called | 
| 515 |         //else m_ptr is stable and we can use it as normal pointer without hesitation | 
| 516 |         if(!m_ptr) | 
| 517 |             return 0; //we are in ~QScriptEnginePrivate | 
| 518 |         else | 
| 519 |             return m_ptr->originalGlobalObject()->debugger(); //QScriptEnginePrivate is still alive | 
| 520 |     } | 
| 521 |  | 
| 522 |     //trace global object and debugger instance | 
| 523 |     QScriptEnginePrivate* m_ptr; | 
| 524 | }; | 
| 525 |  | 
| 526 | class SaveFrameHelper | 
| 527 | { | 
| 528 | public: | 
| 529 |     SaveFrameHelper(QScriptEnginePrivate *eng, | 
| 530 |                     JSC::ExecState *newFrame) | 
| 531 |         : engine(eng), oldFrame(eng->currentFrame) | 
| 532 |     { | 
| 533 |         eng->currentFrame = newFrame; | 
| 534 |     } | 
| 535 |     ~SaveFrameHelper() | 
| 536 |     { | 
| 537 |         engine->currentFrame = oldFrame; | 
| 538 |     } | 
| 539 | private: | 
| 540 |     QScriptEnginePrivate *engine; | 
| 541 |     JSC::ExecState *oldFrame; | 
| 542 | }; | 
| 543 |  | 
| 544 | inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) | 
| 545 | { | 
| 546 |     return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine; | 
| 547 | } | 
| 548 |  | 
| 549 | #ifndef Q_CC_MSVC | 
| 550 | // MSVC2008 crashes if these are inlined. | 
| 551 |  | 
| 552 | inline QString ToString(qsreal value) | 
| 553 | { | 
| 554 |     return JSC::UString::from(value); | 
| 555 | } | 
| 556 |  | 
| 557 | inline qsreal ToNumber(const QString &value) | 
| 558 | { | 
| 559 |     return ((JSC::UString)value).toDouble(); | 
| 560 | } | 
| 561 |  | 
| 562 | #endif | 
| 563 |  | 
| 564 | inline qint32 ToInt32(const QString &value) | 
| 565 | { | 
| 566 |     return ToInt32(ToNumber(value)); | 
| 567 | } | 
| 568 |  | 
| 569 | inline quint32 ToUInt32(const QString &value) | 
| 570 | { | 
| 571 |     return ToUInt32(ToNumber(value)); | 
| 572 | } | 
| 573 |  | 
| 574 | inline quint16 ToUInt16(const QString &value) | 
| 575 | { | 
| 576 |     return ToUInt16(ToNumber(value)); | 
| 577 | } | 
| 578 |  | 
| 579 | inline qsreal ToInteger(const QString &value) | 
| 580 | { | 
| 581 |     return ToInteger(ToNumber(value)); | 
| 582 | } | 
| 583 |  | 
| 584 | inline bool ToBool(qsreal value) | 
| 585 | { | 
| 586 |     return (value != 0) && !qIsNaN(d: value); | 
| 587 | } | 
| 588 |  | 
| 589 | inline bool ToBool(const QString &value) | 
| 590 | { | 
| 591 |      return !value.isEmpty(); | 
| 592 | } | 
| 593 |  | 
| 594 | inline void convertToLatin1_helper(const UChar *i, int length, char *s) | 
| 595 | { | 
| 596 |     const UChar *e = i + length; | 
| 597 |     while (i != e) | 
| 598 |         *(s++) = (uchar) *(i++); | 
| 599 |     *s = '\0'; | 
| 600 | } | 
| 601 |  | 
| 602 | inline QByteArray convertToLatin1(const JSC::UString &str) | 
| 603 | { | 
| 604 |     QByteArray ba(str.size(), Qt::Uninitialized); | 
| 605 |     convertToLatin1_helper(i: str.data(), length: str.size(), s: ba.data()); | 
| 606 |     return ba; | 
| 607 | } | 
| 608 |  | 
| 609 | } // namespace QScript | 
| 610 |  | 
| 611 | inline void QScriptEnginePrivate::registerScriptProgram(QScriptProgramPrivate *program) | 
| 612 | { | 
| 613 |     Q_ASSERT(!registeredScriptPrograms.contains(program)); | 
| 614 |     registeredScriptPrograms.insert(value: program); | 
| 615 | } | 
| 616 |  | 
| 617 | inline void QScriptEnginePrivate::unregisterScriptProgram(QScriptProgramPrivate *program) | 
| 618 | { | 
| 619 |     Q_ASSERT(registeredScriptPrograms.contains(program)); | 
| 620 |     registeredScriptPrograms.remove(value: program); | 
| 621 | } | 
| 622 |  | 
| 623 | inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) | 
| 624 | { | 
| 625 |     if (freeScriptValues) { | 
| 626 |         QScriptValuePrivate *p = freeScriptValues; | 
| 627 |         freeScriptValues = p->next; | 
| 628 |         --freeScriptValuesCount; | 
| 629 |         return p; | 
| 630 |     } | 
| 631 |     return reinterpret_cast<QScriptValuePrivate*>(malloc(size: size)); | 
| 632 | } | 
| 633 |  | 
| 634 | inline void QScriptEnginePrivate::freeScriptValuePrivate(QScriptValuePrivate *p) | 
| 635 | { | 
| 636 |     if (freeScriptValuesCount < maxFreeScriptValues) { | 
| 637 |         p->next = freeScriptValues; | 
| 638 |         freeScriptValues = p; | 
| 639 |         ++freeScriptValuesCount; | 
| 640 |     } else { | 
| 641 |         free(ptr: p); | 
| 642 |     } | 
| 643 | } | 
| 644 |  | 
| 645 | inline void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value) | 
| 646 | { | 
| 647 |     value->prev = 0; | 
| 648 |     value->next = registeredScriptValues; | 
| 649 |     if (registeredScriptValues) | 
| 650 |         registeredScriptValues->prev = value; | 
| 651 |     registeredScriptValues = value; | 
| 652 | } | 
| 653 |  | 
| 654 | inline void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *value) | 
| 655 | { | 
| 656 |     if (value->prev) | 
| 657 |         value->prev->next = value->next; | 
| 658 |     if (value->next) | 
| 659 |         value->next->prev = value->prev; | 
| 660 |     if (value == registeredScriptValues) | 
| 661 |         registeredScriptValues = value->next; | 
| 662 |     value->prev = 0; | 
| 663 |     value->next = 0; | 
| 664 | } | 
| 665 |  | 
| 666 | inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v) | 
| 667 | { | 
| 668 |     JSC::JSValue result = create(exec, type: v.userType(), ptr: v.data()); | 
| 669 |     Q_ASSERT(result); | 
| 670 |     return result; | 
| 671 | } | 
| 672 |  | 
| 673 | inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value) | 
| 674 | { | 
| 675 |     if (!value) | 
| 676 |         return QScriptValue(); | 
| 677 |  | 
| 678 |     QScriptValuePrivate *p_value = new (this)QScriptValuePrivate(this); | 
| 679 |     p_value->initFrom(value); | 
| 680 |     return QScriptValuePrivate::toPublic(d: p_value); | 
| 681 | } | 
| 682 |  | 
| 683 | inline JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &value) | 
| 684 | { | 
| 685 |     QScriptValuePrivate *vv = QScriptValuePrivate::get(q: value); | 
| 686 |     if (!vv) | 
| 687 |         return JSC::JSValue(); | 
| 688 |     if (vv->type != QScriptValuePrivate::JavaScriptCore) { | 
| 689 |         Q_ASSERT(!vv->engine || vv->engine == this); | 
| 690 |         vv->engine = this; | 
| 691 |         if (vv->type == QScriptValuePrivate::Number) { | 
| 692 |             vv->initFrom(JSC::jsNumber(exec: currentFrame, d: vv->numberValue)); | 
| 693 |         } else { //QScriptValuePrivate::String | 
| 694 |             vv->initFrom(JSC::jsString(exec: currentFrame, s: vv->stringValue)); | 
| 695 |         } | 
| 696 |     } | 
| 697 |     return vv->jscValue; | 
| 698 | } | 
| 699 |  | 
| 700 | inline unsigned QScriptEnginePrivate::propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags) | 
| 701 | { | 
| 702 |     unsigned attribs = 0; | 
| 703 |     if (flags & QScriptValue::ReadOnly) | 
| 704 |         attribs |= JSC::ReadOnly; | 
| 705 |     if (flags & QScriptValue::SkipInEnumeration) | 
| 706 |         attribs |= JSC::DontEnum; | 
| 707 |     if (flags & QScriptValue::Undeletable) | 
| 708 |         attribs |= JSC::DontDelete; | 
| 709 |     attribs |= flags & QScriptValue::UserRange; | 
| 710 |     return attribs; | 
| 711 | } | 
| 712 |  | 
| 713 | inline QScriptValuePrivate::~QScriptValuePrivate() | 
| 714 | { | 
| 715 |     if (engine) | 
| 716 |         engine->unregisterScriptValue(value: this); | 
| 717 | } | 
| 718 |  | 
| 719 | inline void QScriptValuePrivate::initFrom(JSC::JSValue value) | 
| 720 | { | 
| 721 |     if (value.isCell()) { | 
| 722 |         Q_ASSERT(engine != 0); | 
| 723 |         value = engine->toUsableValue(value); | 
| 724 |     } | 
| 725 |     type = JavaScriptCore; | 
| 726 |     jscValue = value; | 
| 727 |     if (engine) | 
| 728 |         engine->registerScriptValue(value: this); | 
| 729 | } | 
| 730 |  | 
| 731 | inline void QScriptValuePrivate::initFrom(qsreal value) | 
| 732 | { | 
| 733 |     type = Number; | 
| 734 |     numberValue = value; | 
| 735 |     if (engine) | 
| 736 |         engine->registerScriptValue(value: this); | 
| 737 | } | 
| 738 |  | 
| 739 | inline void QScriptValuePrivate::initFrom(const QString &value) | 
| 740 | { | 
| 741 |     type = String; | 
| 742 |     stringValue = value; | 
| 743 |     if (engine) | 
| 744 |         engine->registerScriptValue(value: this); | 
| 745 | } | 
| 746 |  | 
| 747 | inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::UString &name, int resolveMode) | 
| 748 | { | 
| 749 |     return property(exec, value, JSC::Identifier(exec, name), resolveMode); | 
| 750 | } | 
| 751 |  | 
| 752 | inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) | 
| 753 | { | 
| 754 |     Q_ASSERT(isObject(value)); | 
| 755 |     JSC::JSObject *object = JSC::asObject(value); | 
| 756 |     JSC::PropertySlot slot(object); | 
| 757 |     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, propertyName: id, slot)) | 
| 758 |         return slot.getValue(exec, propertyName: id); | 
| 759 |     return propertyHelper(exec, value, id, resolveMode); | 
| 760 | } | 
| 761 |  | 
| 762 | inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) | 
| 763 | { | 
| 764 |     Q_ASSERT(isObject(value)); | 
| 765 |     JSC::JSObject *object = JSC::asObject(value); | 
| 766 |     JSC::PropertySlot slot(object); | 
| 767 |     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, propertyName: index, slot)) | 
| 768 |         return slot.getValue(exec, propertyName: index); | 
| 769 |     return propertyHelper(exec, value, index, resolveMode); | 
| 770 | } | 
| 771 |  | 
| 772 | inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, | 
| 773 |                                                                        const JSC::UString &name, | 
| 774 |                                                                        const QScriptValue::ResolveFlags &mode) | 
| 775 | { | 
| 776 |     return propertyFlags(exec, value, JSC::Identifier(exec, name), mode); | 
| 777 | } | 
| 778 |  | 
| 779 | inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::UString &name, | 
| 780 |                                               JSC::JSValue value, const QScriptValue::PropertyFlags &flags) | 
| 781 | { | 
| 782 |     setProperty(exec, object: objectValue, JSC::Identifier(exec, name), value, flags); | 
| 783 | } | 
| 784 |  | 
| 785 | inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, const QScriptValue::ResolveFlags &resolveMode) const | 
| 786 | { | 
| 787 |     return QScriptEnginePrivate::property(exec: engine->currentFrame, value: jscValue, id, resolveMode); | 
| 788 | } | 
| 789 |  | 
| 790 | inline JSC::JSValue QScriptValuePrivate::property(quint32 index, const QScriptValue::ResolveFlags &resolveMode) const | 
| 791 | { | 
| 792 |     return QScriptEnginePrivate::property(exec: engine->currentFrame, value: jscValue, index, resolveMode); | 
| 793 | } | 
| 794 |  | 
| 795 | inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, const QScriptValue::ResolveFlags &resolveMode) const | 
| 796 | { | 
| 797 |     JSC::ExecState *exec = engine->currentFrame; | 
| 798 |     return QScriptEnginePrivate::property(exec, value: jscValue, JSC::Identifier(exec, name), resolveMode); | 
| 799 | } | 
| 800 |  | 
| 801 | inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags( | 
| 802 |         const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const | 
| 803 | { | 
| 804 |     return QScriptEnginePrivate::propertyFlags(engine->currentFrame, value: jscValue, id, mode); | 
| 805 | } | 
| 806 |  | 
| 807 | inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value, | 
| 808 |                                              const QScriptValue::PropertyFlags &flags) | 
| 809 | { | 
| 810 |     QScriptEnginePrivate::setProperty(engine->currentFrame, object: jscValue, id, value, flags); | 
| 811 | } | 
| 812 |  | 
| 813 | inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value, | 
| 814 |                                              const QScriptValue::PropertyFlags &flags) | 
| 815 | { | 
| 816 |     QScriptEnginePrivate::setProperty(engine->currentFrame, object: jscValue, index, value, flags); | 
| 817 | } | 
| 818 |  | 
| 819 | inline void QScriptValuePrivate::setProperty(const JSC::UString &name, const JSC::JSValue &value, | 
| 820 |                                              const QScriptValue::PropertyFlags &flags) | 
| 821 | { | 
| 822 |     JSC::ExecState *exec = engine->currentFrame; | 
| 823 |     QScriptEnginePrivate::setProperty(exec, object: jscValue, JSC::Identifier(exec, name), value, flags); | 
| 824 | } | 
| 825 |  | 
| 826 | inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine) | 
| 827 | { | 
| 828 |     if (engine) | 
| 829 |         return engine->allocateScriptValuePrivate(size); | 
| 830 |     return malloc(size: size); | 
| 831 | } | 
| 832 |  | 
| 833 | inline void QScriptValuePrivate::operator delete(void *ptr) | 
| 834 | { | 
| 835 |     QScriptValuePrivate *d = reinterpret_cast<QScriptValuePrivate*>(ptr); | 
| 836 |     if (d->engine) | 
| 837 |         d->engine->freeScriptValuePrivate(p: d); | 
| 838 |     else | 
| 839 |         free(ptr: d); | 
| 840 | } | 
| 841 |  | 
| 842 | inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) | 
| 843 | { | 
| 844 |     if (exec) { | 
| 845 |         *val = exec->exception(); | 
| 846 |         exec->clearException(); | 
| 847 |     } else { | 
| 848 |         *val = JSC::JSValue(); | 
| 849 |     } | 
| 850 | } | 
| 851 |  | 
| 852 | inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) | 
| 853 | { | 
| 854 |     if (exec && val) | 
| 855 |         exec->setException(val); | 
| 856 | } | 
| 857 |  | 
| 858 | inline void QScriptEnginePrivate::registerScriptString(QScriptStringPrivate *value) | 
| 859 | { | 
| 860 |     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated); | 
| 861 |     value->prev = 0; | 
| 862 |     value->next = registeredScriptStrings; | 
| 863 |     if (registeredScriptStrings) | 
| 864 |         registeredScriptStrings->prev = value; | 
| 865 |     registeredScriptStrings = value; | 
| 866 | } | 
| 867 |  | 
| 868 | inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *value) | 
| 869 | { | 
| 870 |     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated); | 
| 871 |     if (value->prev) | 
| 872 |         value->prev->next = value->next; | 
| 873 |     if (value->next) | 
| 874 |         value->next->prev = value->prev; | 
| 875 |     if (value == registeredScriptStrings) | 
| 876 |         registeredScriptStrings = value->next; | 
| 877 |     value->prev = 0; | 
| 878 |     value->next = 0; | 
| 879 | } | 
| 880 |  | 
| 881 | inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) | 
| 882 | { | 
| 883 |     if (frame && frame->callerFrame()->hasHostCallFrameFlag() && !frame->callee() | 
| 884 |         && frame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(exec: frame)->globalExec()) { | 
| 885 |         //skip the "fake" context created in Interpreter::execute. | 
| 886 |         frame = frame->callerFrame()->removeHostCallFrameFlag(); | 
| 887 |     } | 
| 888 |     return reinterpret_cast<QScriptContext *>(frame); | 
| 889 | } | 
| 890 |  | 
| 891 | inline JSC::ExecState *QScriptEnginePrivate::frameForContext(QScriptContext *context) | 
| 892 | { | 
| 893 |     return reinterpret_cast<JSC::ExecState*>(context); | 
| 894 | } | 
| 895 |  | 
| 896 | inline const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScriptContext *context) | 
| 897 | { | 
| 898 |     return reinterpret_cast<const JSC::ExecState*>(context); | 
| 899 | } | 
| 900 |  | 
| 901 | inline bool QScriptEnginePrivate::hasValidCodeBlockRegister(JSC::ExecState *frame) | 
| 902 | { | 
| 903 | #if ENABLE(JIT) | 
| 904 |     // Frames created by the VM don't have their CodeBlock register | 
| 905 |     // initialized. We can detect such frames by checking if the | 
| 906 |     // callee is a host JSFunction. | 
| 907 |     JSC::JSObject *callee = frame->callee(); | 
| 908 |     return !(callee && callee->inherits(info: &JSC::JSFunction::info) | 
| 909 |              && JSC::asFunction(value: callee)->isHostFunction()); | 
| 910 | #else | 
| 911 |     Q_UNUSED(frame); | 
| 912 |     return true; | 
| 913 | #endif | 
| 914 | } | 
| 915 |  | 
| 916 | inline JSC::ExecState *QScriptEnginePrivate::globalExec() const | 
| 917 | { | 
| 918 |     return originalGlobalObject()->globalExec(); | 
| 919 | } | 
| 920 |  | 
| 921 | inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length) | 
| 922 | { | 
| 923 |     return JSC::constructEmptyArray(exec, initialLength: length); | 
| 924 | } | 
| 925 |  | 
| 926 | inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value) | 
| 927 | { | 
| 928 |     JSC::JSValue val = JSC::jsNumber(exec, d: value); | 
| 929 |     JSC::ArgList args(&val, 1); | 
| 930 |     return JSC::constructDate(exec, args); | 
| 931 | } | 
| 932 |  | 
| 933 | inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value) | 
| 934 | { | 
| 935 |     return newDate(exec, value: QScript::DateTimeToMs(exec, value)); | 
| 936 | } | 
| 937 |  | 
| 938 | inline JSC::JSValue QScriptEnginePrivate::newObject() | 
| 939 | { | 
| 940 |     return new (currentFrame)QScriptObject(scriptObjectStructure); | 
| 941 | } | 
| 942 |  | 
| 943 | inline bool QScriptEnginePrivate::isObject(JSC::JSValue value) | 
| 944 | { | 
| 945 |     return value && value.isObject(); | 
| 946 | } | 
| 947 |  | 
| 948 | inline bool QScriptEnginePrivate::isArray(JSC::JSValue value) | 
| 949 | { | 
| 950 |     return isObject(value) && value.inherits(classInfo: &JSC::JSArray::info); | 
| 951 | } | 
| 952 |  | 
| 953 | inline bool QScriptEnginePrivate::isDate(JSC::JSValue value) | 
| 954 | { | 
| 955 |     return isObject(value) && value.inherits(classInfo: &JSC::DateInstance::info); | 
| 956 | } | 
| 957 |  | 
| 958 | inline bool QScriptEnginePrivate::isError(JSC::JSValue value) | 
| 959 | { | 
| 960 |     return isObject(value) && value.inherits(classInfo: &JSC::ErrorInstance::info); | 
| 961 | } | 
| 962 |  | 
| 963 | inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value) | 
| 964 | { | 
| 965 |     return isObject(value) && value.inherits(classInfo: &JSC::RegExpObject::info); | 
| 966 | } | 
| 967 |  | 
| 968 | inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value) | 
| 969 | { | 
| 970 |     if (!isObject(value) || !value.inherits(classInfo: &QScriptObject::info)) | 
| 971 |         return false; | 
| 972 |     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); | 
| 973 |     QScriptObjectDelegate *delegate = object->delegate(); | 
| 974 |     return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); | 
| 975 | } | 
| 976 |  | 
| 977 | inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value) | 
| 978 | { | 
| 979 | #ifndef QT_NO_QOBJECT | 
| 980 |     if (!isObject(value) || !value.inherits(classInfo: &QScriptObject::info)) | 
| 981 |         return false; | 
| 982 |     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); | 
| 983 |     QScriptObjectDelegate *delegate = object->delegate(); | 
| 984 |  | 
| 985 |     if (delegate) { | 
| 986 |         if (delegate->type() == QScriptObjectDelegate::QtObject | 
| 987 |             || (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject | 
| 988 |             && static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject())) | 
| 989 |             return true; | 
| 990 |  | 
| 991 |         if (delegate->type() == QScriptObjectDelegate::Variant) { | 
| 992 |             QVariant var = variantValue(value); | 
| 993 |             int type = var.userType(); | 
| 994 |             if ((QMetaType::typeFlags(type) & QMetaType::PointerToQObject)) | 
| 995 |                 return true; | 
| 996 |         } | 
| 997 |     } | 
| 998 | #endif | 
| 999 |     return false; | 
| 1000 | } | 
| 1001 |  | 
| 1002 | inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value) | 
| 1003 | { | 
| 1004 | #ifndef QT_NO_QOBJECT | 
| 1005 |     return isObject(value) && JSC::asObject(value)->inherits(info: &QScript::QMetaObjectWrapperObject::info); | 
| 1006 | #else | 
| 1007 |     return false; | 
| 1008 | #endif | 
| 1009 | } | 
| 1010 |  | 
| 1011 | inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value) | 
| 1012 | { | 
| 1013 |     JSC::JSValue savedException; | 
| 1014 |     saveException(exec, val: &savedException); | 
| 1015 |     bool result = value.toBoolean(exec); | 
| 1016 |     restoreException(exec, val: savedException); | 
| 1017 |     return result; | 
| 1018 | } | 
| 1019 |  | 
| 1020 | inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value) | 
| 1021 | { | 
| 1022 |     JSC::JSValue savedException; | 
| 1023 |     saveException(exec, val: &savedException); | 
| 1024 |     qsreal result = value.toInteger(exec); | 
| 1025 |     restoreException(exec, val: savedException); | 
| 1026 |     return result; | 
| 1027 | } | 
| 1028 |  | 
| 1029 | inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value) | 
| 1030 | { | 
| 1031 |     JSC::JSValue savedException; | 
| 1032 |     saveException(exec, val: &savedException); | 
| 1033 |     qsreal result = value.toNumber(exec); | 
| 1034 |     restoreException(exec, val: savedException); | 
| 1035 |     return result; | 
| 1036 | } | 
| 1037 |  | 
| 1038 | inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value) | 
| 1039 | { | 
| 1040 |     JSC::JSValue savedException; | 
| 1041 |     saveException(exec, val: &savedException); | 
| 1042 |     qint32 result = value.toInt32(exec); | 
| 1043 |     restoreException(exec, val: savedException); | 
| 1044 |     return result; | 
| 1045 | } | 
| 1046 |  | 
| 1047 | inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value) | 
| 1048 | { | 
| 1049 |     JSC::JSValue savedException; | 
| 1050 |     saveException(exec, val: &savedException); | 
| 1051 |     quint32 result = value.toUInt32(exec); | 
| 1052 |     restoreException(exec, val: savedException); | 
| 1053 |     return result; | 
| 1054 | } | 
| 1055 |  | 
| 1056 | inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value) | 
| 1057 | { | 
| 1058 |     // ### no equivalent function in JSC | 
| 1059 |     return QScript::ToUInt16(toNumber(exec, value)); | 
| 1060 | } | 
| 1061 |  | 
| 1062 | inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value) | 
| 1063 | { | 
| 1064 |     if (!value) | 
| 1065 |         return JSC::UString(); | 
| 1066 |     JSC::JSValue savedException; | 
| 1067 |     saveException(exec, val: &savedException); | 
| 1068 |     JSC::UString str = value.toString(exec); | 
| 1069 |     if (exec && exec->hadException() && !str.size()) { | 
| 1070 |         JSC::JSValue savedException2; | 
| 1071 |         saveException(exec, val: &savedException2); | 
| 1072 |         str = savedException2.toString(exec); | 
| 1073 |         restoreException(exec, val: savedException2); | 
| 1074 |     } | 
| 1075 |     if (savedException) | 
| 1076 |         restoreException(exec, val: savedException); | 
| 1077 |     return str; | 
| 1078 | } | 
| 1079 |  | 
| 1080 | inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *exec, JSC::JSValue value) | 
| 1081 | { | 
| 1082 |     if (!isDate(value)) | 
| 1083 |         return QDateTime(); | 
| 1084 |     qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber(); | 
| 1085 |     return QScript::MsToDateTime(exec, t); | 
| 1086 | } | 
| 1087 |  | 
| 1088 | inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value) | 
| 1089 | { | 
| 1090 | #ifndef QT_NO_QOBJECT | 
| 1091 |     if (isObject(value) && value.inherits(classInfo: &QScriptObject::info)) { | 
| 1092 |         QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); | 
| 1093 |         QScriptObjectDelegate *delegate = object->delegate(); | 
| 1094 |         if (!delegate) | 
| 1095 |             return 0; | 
| 1096 |         if (delegate->type() == QScriptObjectDelegate::QtObject) | 
| 1097 |             return static_cast<QScript::QObjectDelegate*>(delegate)->value(); | 
| 1098 |         if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) | 
| 1099 |             return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(declarativeObject(value)); | 
| 1100 |         if (delegate->type() == QScriptObjectDelegate::Variant) { | 
| 1101 |             QVariant var = variantValue(value); | 
| 1102 |             int type = var.userType(); | 
| 1103 |             if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) | 
| 1104 |                 return *reinterpret_cast<QObject* const *>(var.constData()); | 
| 1105 |         } | 
| 1106 |     } else if (isObject(value) && value.inherits(classInfo: &QScript::QScriptActivationObject::info)) { | 
| 1107 |         QScript::QScriptActivationObject *proxy = static_cast<QScript::QScriptActivationObject *>(JSC::asObject(value)); | 
| 1108 |         return toQObject(exec, value: proxy->delegate()); | 
| 1109 |     } | 
| 1110 | #endif | 
| 1111 |     return 0; | 
| 1112 | } | 
| 1113 |  | 
| 1114 | inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value) | 
| 1115 | { | 
| 1116 | #ifndef QT_NO_QOBJECT | 
| 1117 |     if (isQMetaObject(value)) | 
| 1118 |         return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(value))->value(); | 
| 1119 | #endif | 
| 1120 |     return 0; | 
| 1121 | } | 
| 1122 |  | 
| 1123 | inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value) | 
| 1124 | { | 
| 1125 |     Q_ASSERT(value.inherits(&QScriptObject::info)); | 
| 1126 |     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value))->delegate(); | 
| 1127 |     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); | 
| 1128 |     return static_cast<QScript::QVariantDelegate*>(delegate)->value(); | 
| 1129 | } | 
| 1130 |  | 
| 1131 | inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value) | 
| 1132 | { | 
| 1133 |     Q_ASSERT(objectValue.inherits(&QScriptObject::info)); | 
| 1134 |     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value: objectValue))->delegate(); | 
| 1135 |     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); | 
| 1136 |     static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); | 
| 1137 | } | 
| 1138 |  | 
| 1139 | inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v) | 
| 1140 | { | 
| 1141 |     if (!QScriptEnginePrivate::isObject(value: v) || !v.inherits(classInfo: &QScriptObject::info)) | 
| 1142 |         return 0; | 
| 1143 |     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(value: v)); | 
| 1144 |     QScriptObjectDelegate *delegate = scriptObject->delegate(); | 
| 1145 |     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) | 
| 1146 |         return 0; | 
| 1147 |     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass(); | 
| 1148 | } | 
| 1149 |  | 
| 1150 | inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v) | 
| 1151 | { | 
| 1152 |     if (!QScriptEnginePrivate::isObject(value: v) || !v.inherits(classInfo: &QScriptObject::info)) | 
| 1153 |         return 0; | 
| 1154 |     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(value: v)); | 
| 1155 |     QScriptObjectDelegate *delegate = scriptObject->delegate(); | 
| 1156 |     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) | 
| 1157 |         return 0; | 
| 1158 |     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object(); | 
| 1159 | } | 
| 1160 |  | 
| 1161 | QT_END_NAMESPACE | 
| 1162 |  | 
| 1163 | #endif | 
| 1164 |  |