1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). 4 ** Contact: http://www.qt-project.org/legal 5 ** 6 ** This file is part of the Qt Solutions component. 7 ** 8 ** $QT_BEGIN_LICENSE:BSD$ 9 ** You may use this file under the terms of the BSD license as follows: 10 ** 11 ** "Redistribution and use in source and binary forms, with or without 12 ** modification, are permitted provided that the following conditions are 13 ** met: 14 ** * Redistributions of source code must retain the above copyright 15 ** notice, this list of conditions and the following disclaimer. 16 ** * Redistributions in binary form must reproduce the above copyright 17 ** notice, this list of conditions and the following disclaimer in 18 ** the documentation and/or other materials provided with the 19 ** distribution. 20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names 21 ** of its contributors may be used to endorse or promote products derived 22 ** from this software without specific prior written permission. 23 ** 24 ** 25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 36 ** 37 ** $QT_END_LICENSE$ 38 ** 39 ****************************************************************************/ 40 41 42 #ifndef QSCRIPTENGINEFWD_P_H 43 #define QSCRIPTENGINEFWD_P_H 44 45 #ifndef QT_NO_QOBJECT 46 #include "private/qobject_p.h" 47 #endif 48 49 50 #include <qobjectdefs.h> 51 52 #include <QHash> 53 #include <QList> 54 #include <QRegExp> 55 #include <QSet> 56 #include <QStringList> 57 #include <QTime> 58 #include <QVector> 59 60 #include "qscriptengine.h" 61 #include "qscriptrepository_p.h" 62 #include "qscriptgc_p.h" 63 #include "qscriptobjectfwd_p.h" 64 #include "qscriptclassinfo_p.h" 65 #include "qscriptstring_p.h" 66 67 QT_BEGIN_NAMESPACE 68 69 // 70 // W A R N I N G 71 // ------------- 72 // 73 // This file is not part of the Qt API. It exists purely as an 74 // implementation detail. This header file may change from version to 75 // version without notice, or even be removed. 76 // 77 // We mean it. 78 // 79 80 class QScriptClass; 81 class QScriptContext; 82 83 namespace QScript { 84 85 namespace AST { 86 class Node; 87 } // namespace AST 88 89 namespace Ecma { 90 class Object; 91 class Number; 92 class Boolean; 93 class String; 94 class Math; 95 class Date; 96 class Function; 97 class Array; 98 class RegExp; 99 class Error; 100 } // namespace Ecma 101 102 namespace Ext { 103 class Enumeration; 104 class Variant; 105 } // namespace Ext 106 107 class ExtQObject; 108 class ExtQMetaObject; 109 110 class Array; 111 class Lexer; 112 class Code; 113 class CompilationUnit; 114 class IdTable; 115 class MemoryPool; 116 117 class IdTable 118 { 119 public: IdTable()120 inline IdTable() 121 : id_constructor(0), id_false(0), id_null(0), 122 id_object(0), id_pointer(0), id_prototype(0), 123 id_arguments(0), id_this(0), id_toString(0), 124 id_true(0), id_undefined(0), id_valueOf(0), 125 id_length(0), id_callee(0), id___proto__(0), 126 id___qt_sender__(0) 127 {} 128 129 QScriptNameIdImpl *id_constructor; 130 QScriptNameIdImpl *id_false; 131 QScriptNameIdImpl *id_null; 132 QScriptNameIdImpl *id_object; 133 QScriptNameIdImpl *id_pointer; 134 QScriptNameIdImpl *id_prototype; 135 QScriptNameIdImpl *id_arguments; 136 QScriptNameIdImpl *id_this; 137 QScriptNameIdImpl *id_toString; 138 QScriptNameIdImpl *id_true; 139 QScriptNameIdImpl *id_undefined; 140 QScriptNameIdImpl *id_valueOf; 141 QScriptNameIdImpl *id_length; 142 QScriptNameIdImpl *id_callee; 143 QScriptNameIdImpl *id___proto__; 144 QScriptNameIdImpl *id___qt_sender__; 145 }; 146 147 } // namespace QScript 148 149 #ifndef QT_NO_QOBJECT 150 class QScriptQObjectData; 151 class QScriptMetaObject; 152 #endif 153 154 class QScriptCustomTypeInfo 155 { 156 public: QScriptCustomTypeInfo()157 QScriptCustomTypeInfo() : signature(0, '\0'), marshal(0), demarshal(0) 158 { prototype.invalidate(); } 159 160 QByteArray signature; 161 QScriptEngine::MarshalFunction marshal; 162 QScriptEngine::DemarshalFunction demarshal; 163 QScriptValueImpl prototype; 164 }; 165 166 class QScriptEnginePrivate 167 #ifndef QT_NO_QOBJECT 168 : public QObjectPrivate 169 #endif 170 { 171 Q_DECLARE_PUBLIC(QScriptEngine) 172 173 enum { 174 DefaultHashSize = 1021 175 }; 176 177 public: 178 QScriptEnginePrivate(); 179 virtual ~QScriptEnginePrivate(); 180 181 void init(); 182 void initStringRepository(); 183 184 static inline QScriptEnginePrivate *get(QScriptEngine *q); 185 static inline const QScriptEnginePrivate *get(const QScriptEngine *q); 186 static inline QScriptEngine *get(QScriptEnginePrivate *d); 187 188 QScript::AST::Node *createAbstractSyntaxTree( 189 const QString &source, int lineNumber, 190 QString *errorMessage, int *errorLineNumber); 191 QScript::AST::Node *changeAbstractSyntaxTree(QScript::AST::Node *program); 192 193 inline QScript::AST::Node *abstractSyntaxTree() const; 194 inline bool hasUncaughtException() const; 195 inline QScriptValueImpl uncaughtException() const; 196 QStringList uncaughtExceptionBacktrace() const; 197 void clearExceptions(); 198 #ifndef QT_NO_QOBJECT 199 void emitSignalHandlerException(); 200 #endif 201 202 static bool canEvaluate(const QString &program); 203 static QScriptSyntaxCheckResult checkSyntax(const QString &program); 204 205 inline QScriptContextPrivate *currentContext() const; 206 inline QScriptContextPrivate *pushContext(); 207 inline void popContext(); 208 209 inline QScript::MemoryPool *nodePool(); 210 inline QScript::Lexer *lexer(); 211 inline QScriptObject *allocObject(); 212 213 inline void maybeGC(); 214 215 void maybeGC_helper(bool do_string_gc); 216 217 inline bool blockGC(bool block); 218 219 void gc(); 220 bool isCollecting() const; 221 void processMarkStack(int generation); 222 223 inline void adjustBytesAllocated(int bytes); 224 225 void markObject(const QScriptValueImpl &object, int generation); 226 void markFrame(QScriptContextPrivate *context, int generation); 227 228 inline void markString(QScriptNameIdImpl *id, int generation); 229 230 inline QScriptValueImpl createFunction(QScriptFunction *fun); 231 inline QScriptValueImpl newArray(const QScript::Array &value); 232 inline QScriptValueImpl newArray(uint length = 0); 233 234 void evaluate(QScriptContextPrivate *context, const QString &contents, 235 int lineNumber, const QString &fileName = QString()); 236 237 inline void setLexer(QScript::Lexer *lexer); 238 239 inline void setNodePool(QScript::MemoryPool *pool); 240 241 inline QScriptClassInfo *registerClass(const QString &pname, int type); 242 243 inline QScriptClassInfo *registerClass(const QString &name); 244 245 int registerCustomClassType(); 246 247 inline QScriptValueImpl createFunction(QScriptInternalFunctionSignature fun, 248 int length, QScriptClassInfo *classInfo, 249 const QString &name = QString()); 250 251 static inline QString toString(QScriptNameIdImpl *id); 252 inline QString memberName(const QScript::Member &member) const; 253 inline void newReference(QScriptValueImpl *object, int mode); 254 inline void newActivation(QScriptValueImpl *object); 255 inline void newFunction(QScriptValueImpl *object, QScriptFunction *function); 256 inline void newConstructor(QScriptValueImpl *ctor, QScriptFunction *function, 257 QScriptValueImpl &proto); 258 inline void newInteger(QScriptValueImpl *object, int i); 259 inline void newPointer(QScriptValueImpl *object, void *ptr); 260 inline void newNameId(QScriptValueImpl *object, const QString &s); 261 inline void newNameId(QScriptValueImpl *object, QScriptNameIdImpl *id); 262 inline void newString(QScriptValueImpl *object, const QString &s); 263 inline void newArguments(QScriptValueImpl *object, const QScriptValueImpl &activation, 264 uint length, const QScriptValueImpl &callee); 265 static inline QString convertToNativeString(const QScriptValueImpl &value); 266 static QString convertToNativeString_helper(const QScriptValueImpl &value); 267 static inline qsreal convertToNativeDouble(const QScriptValueImpl &value); 268 static qsreal convertToNativeDouble_helper(const QScriptValueImpl &value); 269 static inline bool convertToNativeBoolean(const QScriptValueImpl &value); 270 static bool convertToNativeBoolean_helper(const QScriptValueImpl &value); 271 static inline qint32 convertToNativeInt32(const QScriptValueImpl &value); 272 static inline QScriptFunction *convertToNativeFunction(const QScriptValueImpl &value); 273 274 inline QScriptValue toPublic(const QScriptValueImpl &value); 275 inline QScriptValueImpl toImpl(const QScriptValue &value); 276 QScriptValueImpl toImpl_helper(const QScriptValue &value); 277 inline QScriptValueImplList toImplList(const QScriptValueList &lst); 278 279 inline const QScript::IdTable *idTable() const; 280 281 inline QScriptValueImpl toObject(const QScriptValueImpl &value); 282 QScriptValueImpl toObject_helper(const QScriptValueImpl &value); 283 284 inline QScriptValueImpl toPrimitive(const QScriptValueImpl &object, 285 QScriptValueImpl::TypeHint hint = QScriptValueImpl::NoTypeHint); 286 QScriptValueImpl toPrimitive_helper(const QScriptValueImpl &object, 287 QScriptValueImpl::TypeHint hint); 288 289 static const qsreal D16; 290 static const qsreal D32; 291 292 inline static qsreal toInteger(qsreal n); 293 inline static qint32 toInt32(qsreal m); 294 inline static quint32 toUint32(qsreal n); 295 inline static quint16 toUint16(qsreal n); 296 297 inline QDateTime toDateTime(const QScriptValueImpl &value) const; 298 299 inline void newArray(QScriptValueImpl *object, const QScript::Array &value); 300 301 inline void newObject(QScriptValueImpl *o, const QScriptValueImpl &proto, 302 QScriptClassInfo *oc = 0); 303 inline void newObject(QScriptValueImpl *o, QScriptClassInfo *oc = 0); 304 QScriptValueImpl newObject(QScriptClass *scriptClass, const QScriptValueImpl &data); 305 306 inline QScriptValueImpl newObject(); 307 308 inline void newVariant(QScriptValueImpl *out, const QVariant &value, 309 bool setDefaultPrototype = true); 310 311 #ifndef QT_NO_QOBJECT 312 void newQObject(QScriptValueImpl *out, QObject *object, 313 QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, 314 const QScriptEngine::QObjectWrapOptions &options = 0, 315 bool setDefaultPrototype = true); 316 317 # ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE 318 inline QScriptMetaObject *cachedMetaObject(const QMetaObject *meta); 319 # endif 320 #endif 321 322 inline QScriptNameIdImpl *nameId(const QString &str, bool persistent = false); 323 324 inline QScriptNameIdImpl *intern(const QChar *u, int s); 325 326 QScriptString internedString(const QString &str); 327 QScriptString internedString(QScriptNameIdImpl *nid); 328 void uninternString(QScriptStringPrivate *d); 329 330 inline QScriptValueImpl valueFromVariant(const QVariant &v); 331 332 inline QScriptValueImpl undefinedValue(); 333 334 inline QScriptValueImpl nullValue(); 335 336 inline QScriptValueImpl defaultPrototype(int metaTypeId) const; 337 338 inline void setDefaultPrototype(int metaTypeId, const QScriptValueImpl &prototype); 339 340 QScriptValueImpl call(const QScriptValueImpl &callee, const QScriptValueImpl &thisObject, 341 const QScriptValueImplList &args, bool asConstructor); 342 QScriptValueImpl call(const QScriptValueImpl &callee, const QScriptValueImpl &thisObject, 343 const QScriptValueImpl &args, bool asConstructor); 344 345 void rehashStringRepository(bool resize = true); 346 inline QScriptNameIdImpl *toStringEntry(const QString &s); 347 QScriptNameIdImpl *insertStringEntry(const QString &s); 348 349 QScriptValueImpl create(int type, const void *ptr); 350 static bool convert(const QScriptValueImpl &value, int type, void *ptr, 351 QScriptEnginePrivate *eng); 352 QScriptEngine::DemarshalFunction demarshalFunction(int type) const; 353 354 QScriptValueImpl arrayFromStringList(const QStringList &lst); 355 static QStringList stringListFromArray(const QScriptValueImpl &arr); 356 357 QScriptValueImpl arrayFromVariantList(const QVariantList &lst); 358 static QVariantList variantListFromArray(const QScriptValueImpl &arr); 359 360 QScriptValueImpl objectFromVariantMap(const QVariantMap &vmap); 361 static QVariantMap variantMapFromObject(const QScriptValueImpl &obj); 362 363 static inline bool lessThan(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); 364 static inline bool equals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); 365 static inline bool strictlyEquals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); 366 367 QScriptValuePrivate *registerValue(const QScriptValueImpl &value); 368 inline void unregisterValue(QScriptValuePrivate *p); 369 370 inline QScriptValueImpl globalObject() const; 371 372 QScriptValueImpl objectById(qint64 id) const; 373 374 QScriptValueImpl importExtension(const QString &extension); 375 QStringList availableExtensions() const; 376 QStringList importedExtensions() const; 377 378 inline void maybeProcessEvents(); 379 void setupProcessEvents(); 380 void processEvents(); 381 382 #ifndef QT_NO_QOBJECT 383 QScriptQObjectData *qobjectData(QObject *object); 384 385 bool scriptConnect(QObject *sender, const char *signal, 386 const QScriptValueImpl &receiver, 387 const QScriptValueImpl &function, 388 Qt::ConnectionType type); 389 bool scriptDisconnect(QObject *sender, const char *signal, 390 const QScriptValueImpl &receiver, 391 const QScriptValueImpl &function); 392 393 bool scriptConnect(QObject *sender, int index, 394 const QScriptValueImpl &receiver, 395 const QScriptValueImpl &function, 396 const QScriptValueImpl &senderWrapper, 397 Qt::ConnectionType type); 398 bool scriptDisconnect(QObject *sender, int index, 399 const QScriptValueImpl &receiver, 400 const QScriptValueImpl &function); 401 402 bool scriptConnect(const QScriptValueImpl &signal, 403 const QScriptValueImpl &receiver, 404 const QScriptValueImpl &function, 405 Qt::ConnectionType type); 406 bool scriptDisconnect(const QScriptValueImpl &signal, 407 const QScriptValueImpl &receiver, 408 const QScriptValueImpl &function); 409 410 void _q_objectDestroyed(QObject *object); 411 412 void disposeQObject(QObject *object); 413 void deletePendingQObjects(); 414 415 static bool convertToNativeQObject(const QScriptValueImpl &value, 416 const QByteArray &targetType, 417 void **result); 418 #endif 419 420 void abortEvaluation(const QScriptValueImpl &result); 421 inline bool shouldAbort() const; 422 inline void resetAbortFlag(); 423 424 void setAgent(QScriptEngineAgent *agent); 425 QScriptEngineAgent *agent() const; 426 427 void agentDeleted(QScriptEngineAgent *agent); 428 429 void installTranslatorFunctions(QScriptValueImpl &object); 430 431 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY 432 qint64 nextScriptId(); 433 inline bool shouldNotify() const; 434 inline void notifyScriptLoad(qint64 id, const QString &program, 435 const QString &fileName, int lineNumber); 436 void notifyScriptLoad_helper(qint64 id, const QString &program, 437 const QString &fileName, int lineNumber); 438 inline void notifyScriptUnload(qint64 id); 439 void notifyScriptUnload_helper(qint64 id); 440 inline void notifyPositionChange(QScriptContextPrivate *ctx); 441 void notifyPositionChange_helper(QScriptContextPrivate *ctx); 442 inline void notifyContextPush(); 443 void notifyContextPush_helper(); 444 inline void notifyContextPop(); 445 void notifyContextPop_helper(); 446 inline void notifyFunctionEntry(QScriptContextPrivate *ctx); 447 void notifyFunctionEntry_helper(QScriptContextPrivate *ctx); 448 inline void notifyFunctionExit(QScriptContextPrivate *ctx); 449 void notifyFunctionExit_helper(QScriptContextPrivate *ctx); 450 inline void notifyException(QScriptContextPrivate *ctx); 451 void notifyException_helper(QScriptContextPrivate *ctx); 452 inline void notifyExceptionCatch(QScriptContextPrivate *ctx); 453 void notifyExceptionCatch_helper(QScriptContextPrivate *ctx); 454 void notifyDebugger(QScriptContextPrivate *ctx); 455 #endif // Q_SCRIPT_NO_EVENT_NOTIFY 456 457 public: // attributes 458 bool m_evaluating; 459 bool m_abort; 460 int m_callDepth; 461 int m_maxCallDepth; 462 int m_gc_depth; 463 QList<QScriptValueImpl> m_markStack; 464 QScriptValueImpl m_globalObject; 465 int m_oldStringRepositorySize; 466 int m_oldTempStringRepositorySize; 467 QVector<QScriptNameIdImpl*> m_stringRepository; 468 int m_newAllocatedStringRepositoryChars; 469 QVector<QScriptNameIdImpl*> m_tempStringRepository; 470 int m_newAllocatedTempStringRepositoryChars; 471 QScriptNameIdImpl **m_string_hash_base; 472 int m_string_hash_size; 473 QScript::GCAlloc<QScriptObject> objectAllocator; 474 int m_objectGeneration; 475 QScript::Repository<QScriptContext, QScriptContextPrivate> m_frameRepository; 476 QScriptContextPrivate *m_context; 477 QScriptValueImpl *tempStackBegin; 478 QScriptValueImpl *tempStackEnd; 479 QScript::AST::Node *m_abstractSyntaxTree; 480 QScript::Lexer *m_lexer; 481 QScript::MemoryPool *m_pool; 482 QStringList m_exceptionBacktrace; 483 qint64 m_scriptCounter; 484 485 QScriptValueImpl m_undefinedValue; 486 QScriptValueImpl m_nullValue; 487 488 QScript::Ecma::Object *objectConstructor; 489 QScript::Ecma::Number *numberConstructor; 490 QScript::Ecma::Boolean *booleanConstructor; 491 QScript::Ecma::String *stringConstructor; 492 QScript::Ecma::Date *dateConstructor; 493 QScript::Ecma::Function *functionConstructor; 494 QScript::Ecma::Array *arrayConstructor; 495 QScript::Ecma::RegExp *regexpConstructor; 496 QScript::Ecma::Error *errorConstructor; 497 QScript::Ext::Enumeration *enumerationConstructor; 498 QScript::Ext::Variant *variantConstructor; 499 QScript::ExtQObject *qobjectConstructor; 500 QScript::ExtQMetaObject *qmetaObjectConstructor; 501 502 QHash<int, QScriptCustomTypeInfo> m_customTypes; 503 504 QScriptFunction *m_evalFunction; 505 506 QList<QScriptClassInfo*> m_allocated_classes; 507 QScriptClassInfo *m_class_object; 508 QScriptClassInfo *m_class_function; 509 QScriptClassInfo *m_class_with; 510 QScriptClassInfo *m_class_arguments; 511 QScriptClassInfo *m_class_activation; 512 513 int m_class_prev_id; 514 qint64 m_next_object_id; 515 516 QScript::Repository<QScriptValuePrivate, QScriptValuePrivate> m_handleRepository; 517 QHash<QScriptObject*, QScriptValuePrivate*> m_objectHandles; 518 QHash<QScriptNameIdImpl*, QScriptValuePrivate*> m_stringHandles; 519 QVector<QScriptValuePrivate*> m_otherHandles; 520 521 QScript::Repository<QScriptStringPrivate, 522 QScriptStringPrivate> m_internedStringRepository; 523 QHash<QScriptNameIdImpl*, QScriptStringPrivate*> m_internedStrings; 524 525 QSet<QScriptObject*> visitedArrayElements; 526 527 #ifndef QT_NO_REGEXP 528 QHash<QString, QRegExp> m_regExpLiterals; 529 #endif 530 531 QScript::IdTable m_id_table; 532 533 QSet<QString> m_importedExtensions; 534 QSet<QString> m_extensionsBeingImported; 535 536 int m_processEventsInterval; 537 int m_nextProcessEvents; 538 int m_processEventIncr; 539 QTime m_processEventTracker; 540 541 QList<QScriptEngineAgent*> m_agents; 542 QScriptEngineAgent *m_agent; 543 544 #ifndef QT_NO_QOBJECT 545 QList<QObject*> m_qobjectsToBeDeleted; 546 QHash<QObject*, QScriptQObjectData*> m_qobjectData; 547 548 # ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE 549 QHash<const QMetaObject*, QScriptMetaObject*> m_cachedMetaObjects; 550 # endif 551 #endif 552 553 #ifdef QT_NO_QOBJECT 554 QScriptEngine *q_ptr; 555 #endif 556 }; 557 558 QT_END_NAMESPACE 559 560 561 #endif 562