void FunctionClassData::mark(const QScriptValueImpl &object, int generation)
{
    if (object.classInfo() != classInfo())
        return;
    QScriptFunction *fun = object.toFunction();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine());
    fun->mark(eng, generation);
}
QScriptValueImpl Function::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
{
    QScriptValueImpl self = context->thisObject();
    if (QScriptFunction *foo = self.toFunction()) {
        QString code = foo->toString(context);
        return QScriptValueImpl(eng, code);
    }

    return context->throwError(QScriptContext::TypeError,
                               QLatin1String("Function.prototype.toString"));
}
bool FunctionClassData::get(const QScriptValueImpl &object, const Member &member,
                            QScriptValueImpl *result)
{
    if (object.classInfo() != classInfo())
        return false;

    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine());
    if (! member.isNativeProperty())
        return false;

    if (member.nameId() == eng->idTable()->id_length) {
        eng->newNumber(result, object.toFunction()->length);
        return true;
    } else if (member.nameId() == eng->idTable()->id_arguments) {
        eng->newNull(result);
        return true;
    }

    return false;
}
/*!
  \internal
*/
QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *context)
{
    Q_ASSERT(context);
    ref = 0;
    functionType = QScriptContextInfo::NativeFunction;
    functionMetaIndex = -1;
    functionStartLineNumber = -1;
    functionEndLineNumber = -1;

    const QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(context);
    scriptId = ctx_p->scriptId();
    fileName = ctx_p->fileName();
    lineNumber = ctx_p->currentLine;
    columnNumber = ctx_p->currentColumn;

    QScriptValueImpl callee = QScriptValuePrivate::valueOf(context->callee());
    QScriptFunction *fun = callee.toFunction();
    if (fun) {
        functionName = fun->functionName();
        functionStartLineNumber = fun->startLineNumber();
        functionEndLineNumber = fun->endLineNumber();

        switch (fun->type()) {
        case QScriptFunction::Unknown:
            functionType = QScriptContextInfo::NativeFunction;
            break;

        case QScriptFunction::Script:
            functionType = QScriptContextInfo::ScriptFunction;
            for (int i = 0; i < fun->formals.count(); ++i)
                parameterNames.append(fun->formals.at(i)->s);
            break;

        case QScriptFunction::C:
            functionType = QScriptContextInfo::NativeFunction;
            break;

        case QScriptFunction::C2:
            functionType = QScriptContextInfo::NativeFunction;
            break;

        case QScriptFunction::C3:
            functionType = QScriptContextInfo::NativeFunction;
            break;

        case QScriptFunction::Qt: {
            functionType = QScriptContextInfo::QtFunction;
            functionMetaIndex = ctx_p->calleeMetaIndex;

#ifndef QT_NO_QOBJECT
            const QMetaObject *meta;
            meta = static_cast<QScript::QtFunction*>(fun)->metaObject();
            if (meta) {
                QMetaMethod method = meta->method(functionMetaIndex);
                QList<QByteArray> formals = method.parameterNames();
                for (int i = 0; i < formals.count(); ++i)
                    parameterNames.append(QLatin1String(formals.at(i)));
            }
#endif
        }   break;

        case QScriptFunction::QtProperty:
            functionType = QScriptContextInfo::QtPropertyFunction;
            functionMetaIndex = ctx_p->calleeMetaIndex;
            break;
        }
    }
}
QScriptValueImpl Function::method_connect(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo)
{
    Q_UNUSED(classInfo);

#ifndef QT_NO_QOBJECT
    if (context->argumentCount() == 0) {
        return context->throwError(
            QLatin1String("Function.prototype.connect: no arguments given"));
    }

    QScriptValueImpl self = context->thisObject();
    QScriptFunction *fun = self.toFunction();
    if ((fun == 0) || (fun->type() != QScriptFunction::Qt)) {
        return context->throwError(
            QScriptContext::TypeError,
            QLatin1String("Function.prototype.connect: this object is not a signal"));
    }

    QtFunction *qtSignal = static_cast<QtFunction*>(fun);

    const QMetaObject *meta = qtSignal->metaObject();
    if (!meta) {
        return context->throwError(
            QScriptContext::TypeError,
            QString::fromLatin1("Function.prototype.connect: cannot connect to deleted QObject"));
    }

    QMetaMethod sig = meta->method(qtSignal->initialIndex());
    if (sig.methodType() != QMetaMethod::Signal) {
        return context->throwError(QScriptContext::TypeError,
            QString::fromLatin1("Function.prototype.connect: %0::%1 is not a signal")
            .arg(QLatin1String(qtSignal->metaObject()->className()))
            .arg(QLatin1String(sig.signature())));
    }

    QScriptValueImpl receiver;
    QScriptValueImpl slot;
    QScriptValueImpl arg0 = context->argument(0);
    if (context->argumentCount() < 2) {
        receiver = QScriptValueImpl();
        slot = arg0;
    } else {
        receiver = arg0;
        QScriptValueImpl arg1 = context->argument(1);
        if (arg1.isFunction())
            slot = arg1;
        else
            slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype);
    }

    if (!slot.isFunction()) {
        return context->throwError(
            QScriptContext::TypeError,
            QLatin1String("Function.prototype.connect: target is not a function"));
    }

    bool ok = eng->scriptConnect(self, receiver, slot);
    if (!ok) {
        return context->throwError(
            QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1")
            .arg(QLatin1String(qtSignal->metaObject()->className()))
            .arg(QLatin1String(sig.signature())));
    }
    return eng->undefinedValue();
#else
    Q_UNUSED(eng);
    Q_UNUSED(classInfo);
    return context->throwError(QScriptContext::TypeError,
                               QLatin1String("Function.prototype.connect"));
#endif // QT_NO_QOBJECT
}