QSObject QSErrorClass::construct( ErrorType e, const QString &msg, int ln ) const { QSErrorShared *error = new QSErrorShared(e, msg, ln); #ifdef QSDEBUGGER error->sid = env()->engine()->debugger()->sourceId(); #endif return QSObject(this, error); }
QSObject QSList::at( int i ) const { if ( i < 0 || i >= size() ) { Q_ASSERT( 0 ); return QSObject(); } QSListIterator it = begin(); int j = 0; while ( (j++ < i) ) it++; return *it; }
QVariant QuickInterpreter::call(QSObject ctx, const QString &func, const QSList &args) { if (shuttingDown) return QVariant(); QSEngine::call(&ctx, func, args); if (hadError()) emit runtimeError(); // Make sure we dereference the engines return value to avoid pooling QVariant a = convertToArgument(returnValue()); setReturnValue(QSObject()); return a; }
QSObject QSEnv::resolveValue(const QString &ident) const { Q_ASSERT(!ident.isEmpty()); ScopeChain::const_iterator it = scopeChain->begin(); QSMember mem; int offset; while (it != scopeChain->end() && (*it).isValid()) { offset = 0; const QSClass *cl = (*it).resolveMember(ident, &mem, (*it).objectType(), &offset); if (cl && mem.type() != QSMember::Identifier) { while (offset--) it++; return cl->fetchValue(&(*it), mem); } it++; } return QSObject(); }
QSObject QuickInterpreter::wrap( QObject *o ) { if( !o ) { QSList list; return env()->nullClass()->construct( list ); } #if defined (QT_THREAD_SUPPORT) && QT_VERSION >= 0x030300 if (qt_get_application_thread_id() != QThread::currentThread() && o->inherits("QWidget")) { qWarning("QuickInterpreter::wrap(), GUI object (%s [%s]) cannot be used in non GUI thread", o->name(), o->className()); return QSObject(); } #endif QSUserData *udata = (QSUserData*) o->userData( userDataId() ); // set user data in QObject if it's not there, yet if( !udata ) { udata = new QSUserData( 0 ); o->setUserData( userDataId(), udata ); } QSWrapperShared *shared = udata->data(); const QSWrapperClass *cl; if ( shared ) { // wrapper is already there, reuse it cl = shared->wrapperClass(); } else { // create & remember wrapper cl = new QSWrapperClass( wrapperClass() ); shared = cl->createShared( o ); shared->setObjectType( QSWrapperShared::GlobalObject ); env()->registerShared( shared ); wrapperShared->append( shared ); } shared->setUserData( udata ); udata->setData( shared ); shared->ref(); // additional ref by either QObject or QSObject QSObject obj( cl ); obj.setVal( shared ); // no ownership needs to be transferred anymore return obj; }
QVariant QuickInterpreter::execute(QObject *obj, const QString &c, const QString &name) { QString code = c + QString::fromLatin1("\n"); int sourceId = debugger ? debugger->freeSourceId() : -1; if(!name.isNull() && sourceId >= 0) sourceIdNames[sourceId] = name; QSObject t, oldThis; if (obj) { if (!name.isNull() && sourceId >= 0) addSourceId(sourceId, obj); if (!hasTopLevelParent(obj)) addTopLevelObject(obj); t = wrap(obj); oldThis = env()->thisValue(); env()->setThisValue(t); } QSEngine::evaluate(t, code); // restore this value if (obj) env()->setThisValue(oldThis); if (hadError()) if(errorType() == QSErrParseError) emit parseError(); else emit runtimeError(); // Make sure we dereference the engines return value to avoid pooling QVariant a = convertToArgument(returnValue()); setReturnValue(QSObject()); return a; }
QSObject QuickInterpreter::wrap(QObject *o) { if(!o) { QSList list; return env()->nullClass()->construct(list); } if (qsa_is_non_gui_thread() && o->isWidgetType()) { qWarning("QuickInterpreter::wrap(), GUI object (%s [%s]) cannot be used in non GUI thread", o->objectName().toLatin1().constData(), o->metaObject()->className()); return QSObject(); } QSUserData *udata = (QSUserData*) o->userData(userDataId()); // set user data in QObject if it's not there, yet if(!udata) { udata = new QSUserData(0); o->setUserData(userDataId(), udata); } QSWrapperShared *shared = udata->data(); const QSWrapperClass *cl; if (shared) { // wrapper is already there, reuse it cl = shared->wrapperClass(); } else { // create & remember wrapper cl = new QSWrapperClass(wrapperClass()); shared = cl->createShared(o); shared->setObjectType(QSWrapperShared::GlobalObject); env()->registerShared(shared); wrapperShared->append(shared); } shared->setUserData(udata); udata->setData(shared); shared->ref(); // additional ref by either QObject or QSObject QSObject obj(cl); obj.setVal(shared); // no ownership needs to be transferred anymore return obj; }
QSObject QSPixmapClass::construct( const QPixmap &p ) const { return QSObject( this, new PixmapShared( p ) ); }
void QSList::init() { hook = new ListNode( QSObject(), 0L, 0L ); hook->next = hook; hook->prev = hook; }
QSObject QSEnv::createShared(const QSClass *cl, QSShared *sh) const { return QSObject(cl, sh); }
QSObject QSRectClass::construct(const QRect &r) const { return QSObject(this, new RectShared(r)); }
QSObject QSSizeClass::construct(const QSize &s) const { return QSObject(this, new SizeShared(s)); }
QSObject QSPointClass::construct(const QPoint &p) const { return QSObject(this, new PointShared(p)); }
static QSObject qsConnectCommon( QSEnv *env, QSObject &arg0, QSObject &arg2, QSWrapperShared *&sendObj, QSWrapperShared *&recObj, const QPtrVector<QObject> *&sendIfaces, const QPtrVector<QObject> *&recIfaces, QString &sig, QString &sl, int &signal_index, QObject *&sender, const QString &func ) { const QSList &args = *env->arguments(); QuickInterpreter *ip = QuickInterpreter::fromEnv( env ); const QString overloads = QString::fromLatin1( "Following overloads are possible:\n" "%1( sender : QObject, signal : String, receiver : QObject, slot : String )\n" "%2( sender : QObject, signal : String, function : DeclaredFunction )" ). arg( func ).arg( func ); if ( args.size() < 3 || args.size() > 4 ) { QString msg = QString::fromLatin1("No matching overload found. ") + overloads; return env->throwError( SyntaxError, msg ); } QSWrapperClass *wClass = ip->wrapperClass(); if ( !args[0].isA( wClass ) ) { QString msg = QString::fromLatin1("No matching overload found. 'sender' must be of type QObject but is of type ") + args[0].typeName() + QString::fromLatin1("\n") + overloads; return env->throwError( TypeError, msg ); } if ( args.size() == 3 && !args[2].isFunction() ) { QString msg = QString::fromLatin1("No matching overloads found. Third argument in this overload " "must be of type function but is of type ") + args[2].typeName() + QString::fromLatin1("\n") + overloads; return env->throwError( TypeError, msg ); } arg0 = args[0]; arg2 = args[2]; sendObj = wClass->shared( &arg0 ); recObj = arg2.isA( wClass ) ? wClass->shared( &arg2 ) : 0; sendIfaces = sendObj->interfaceObjects(); recIfaces = recObj ? recObj->interfaceObjects() : 0; // signal and slot in string representation sig = args[1].toString(); sl = ( args.size()>3 ? args[3] : env->createUndefined() ).toString(); // find sender and signal sender = 0; signal_index = -1; const char *sigName = sig.ascii(); int i; for ( i = (int)sendIfaces->count()-1; i >= 0; --i ) { sender = sendIfaces->at( i ); signal_index = sender->metaObject()->findSignal( sigName, TRUE ); if ( signal_index > 0 ) break; } if ( signal_index == -1 ) { // didn't find the signal- this signature might be in Qt // Script syntax, so lets's try to find out if we can connect QString sn = sig; QString arg = sig.mid( sig.find( '(' ) + 1 ); arg = arg.left( arg.findRev( ')' ) ); QStringList args = QStringList::split( ',', arg ); sn = sig.left( sig.find( '(' ) ); for ( i = (int)sendIfaces->count()-1; i >= 0; --i ) { sender = sendIfaces->at( i ); for ( int j = 0; j < (int)sender->metaObject()->numSignals( TRUE ); ++j ) { const QMetaData *md = sender->metaObject()->signal( j, TRUE ); QString mdn = QString::fromLatin1(md->name); mdn = mdn.left( mdn.find( '(' ) ); if ( mdn != sn ) continue; const QUMethod *method = md->method; bool ok = method->count == (int)args.count(); for ( int k = 0; k < method->count; ++k ) { QUParameter p = method->parameters[k]; QString s = *args.at( k ); int sep; if ( ( sep = s.find( ':' ) ) != -1 ) s = s.mid( sep + 1 ); s = s.simplifyWhiteSpace(); if ( s == QString::fromLatin1(p.type->desc()) || s == QString::fromLatin1((const char*)p.typeExtra)) continue; if ( s == QString::fromLatin1("Number") && ( qstrcmp( p.type->desc(), "int" ) == 0 || qstrcmp( p.type->desc(), "long" ) == 0 || qstrcmp( p.type->desc(), "double" ) == 0 || qstrcmp( p.type->desc(), "float" ) == 0 || qstrcmp( p.type->desc(), "short" ) == 0 || qstrcmp( p.type->desc(), "uint" ) == 0 || qstrcmp( p.type->desc(), "ushort" ) == 0 || qstrcmp( p.type->desc(), "ulong" ) == 0 || qstrcmp( p.type->desc(), "unsigned int" ) == 0 || qstrcmp( p.type->desc(), "unsigned short" ) == 0 || qstrcmp( p.type->desc(), "unsigned long" ) == 0 ) ) continue; s.prepend( QString::fromLatin1("Q") ); if (s == QString::fromLatin1(p.type->desc()) || s == QString::fromLatin1((const char*)p.typeExtra)) continue; ok = FALSE; break; } if ( !ok ) continue; signal_index = j; sig = sender->metaObject()->signal( j, TRUE )->name; break; } if ( signal_index != -1 ) break; } } return QSObject(); }