QList<JSAgentWatchData> QJSDebuggerAgent::localsAtFrame(int frameId)
{
    SetupExecEnv execEnv(d);

    int deep = 0;
    QScriptContext *ctx = engine()->currentContext();
    while (ctx && deep < frameId) {
        ctx = ctx->parentContext();
        deep++;
    }

    return d->getLocals(ctx);
}
Exemple #2
0
/*!
  Returns the context for the frame with the given \a index.
*/
QScriptContext *QScriptDebuggerBackend::context(int index) const
{
    if (index < 0)
        return 0;
    QScriptContext *ctx = engine()->currentContext();
    while (ctx) {
        if (index == 0)
            return ctx;
        ctx = ctx->parentContext();
        --index;
    }
    return 0;
}
Exemple #3
0
void Cluster::setup ()
{
    QScriptEngine* engine = scene->scriptEngine();
    QScriptContext* ctx = engine->pushContext();
    QScriptValue ao = ctx->activationObject();
    prepGlobalObject(ao);
    ao.setProperty("emit", engine->newFunction(emitFun));

    /// @todo is this the best way to get access to the cluster?
    QVariant var = qVariantFromValue(this);
    ao.setProperty("self", engine->newVariant(var));

    engine->evaluate(d->shellProgram);
    engine->popContext();
}
/*!
  Constructs a new agent for the given \a engine. The agent will
  report debugging-related events (e.g. step completion) to the given
  \a backend.
*/
QScriptDebuggerAgent::QScriptDebuggerAgent(
    QScriptDebuggerBackendPrivate *backend, QScriptEngine *engine)
    : QScriptEngineAgent(engine), d_ptr(new QScriptDebuggerAgentPrivate())
{
    Q_D(QScriptDebuggerAgent);
    d->backend = backend;

    QScriptContext *ctx = engine->currentContext();
    while (ctx) {
        d->scriptIdStack.append(QList<qint64>());
        d->contextIdStack.append(d->nextContextId);
        ++d->nextContextId;
        ctx = ctx->parentContext();
    }
}
Exemple #5
0
QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, 
                                                              const QString &program, QScriptValue *contextObject)
{
    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
    QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
    if (contextObject) {
        *contextObject = ep->contextClass->newContext(context, object);
        scriptContext->pushScope(*contextObject);
    } else {
        scriptContext->pushScope(ep->contextClass->newContext(context, object));
    }
    scriptContext->pushScope(ep->globalClass->globalObject());
    QScriptValue rv = ep->scriptEngine.evaluate(program);
    ep->scriptEngine.popContext();
    return rv;
}
static PyObject *meth_QScriptContext_parentContext(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;

    {
        QScriptContext *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "B", &sipSelf, sipType_QScriptContext, &sipCpp))
        {
            QScriptContext *sipRes;

            Py_BEGIN_ALLOW_THREADS
            sipRes = sipCpp->parentContext();
            Py_END_ALLOW_THREADS

            return sipConvertFromType(sipRes,sipType_QScriptContext,NULL);
        }
    }
Exemple #7
0
bool XTreeView::throwScriptException(const QString &message)
{
   QObject *ancestor = this;
   QScriptEngine *engine = 0;
   for ( ; ancestor; ancestor = ancestor->parent())
   {
     engine = ancestor->findChild<QScriptEngine*>();
     if (engine)
       break;
   } 
   if (engine)
   {
      QScriptContext *ctx = engine->currentContext();
      ctx->throwError(message);
      return true;
   }
   return false;
}
Exemple #8
0
/*!
  Executes the pending evaluate, if any.
*/
void QScriptDebuggerBackend::doPendingEvaluate(bool postEvent)
{
    Q_D(QScriptDebuggerBackend);
    QString program = d->pendingEvaluateProgram;
    if (program.isEmpty())
        return;
    int contextIndex = d->pendingEvaluateContextIndex;
    QScriptContext *ctx = context(contextIndex);
    Q_ASSERT(ctx != 0);
    QString fileName = d->pendingEvaluateFileName;
    int lineNumber = d->pendingEvaluateLineNumber;
    d->pendingEvaluateProgram = QString();
    d->pendingEvaluateFileName = QString();
    d->pendingEvaluateLineNumber = -1;
    d->pendingEvaluateContextIndex = -1;

    // push a new context and initialize its scope chain etc.
    {
        QScriptContext *evalContext = engine()->pushContext();
        QScriptValueList scopeChain = ctx->scopeChain();
        if (scopeChain.isEmpty())
            scopeChain.append(engine()->globalObject());
        while (!scopeChain.isEmpty())
            evalContext->pushScope(scopeChain.takeLast());
        evalContext->setActivationObject(ctx->activationObject());
        evalContext->setThisObject(ctx->thisObject());
    }

    d->agent->enterContinueMode();
    // set a flag so that any exception that happens in
    // the evaluate() is not sent to the debugger
    d->ignoreExceptions = true;
    bool hadException = engine()->hasUncaughtException();
    QScriptValue ret = engine()->evaluate(program, fileName, lineNumber);
    d->ignoreExceptions = false;
    if (!hadException && engine()->hasUncaughtException())
        engine()->clearExceptions();
    engine()->popContext();

    QScriptDebuggerValue retret(ret);
    QScriptDebuggerEvent e(QScriptDebuggerEvent::InlineEvalFinished);
    e.setScriptValue(retret);
    if (!ret.isUndefined())
        e.setMessage(ret.toString()); // for convenience -- we always need it

    e.setNestedEvaluate(engine()->isEvaluating());

    if (postEvent) {
        QScriptDebuggerEventEvent *de = new QScriptDebuggerEventEvent(e);
        d->postEvent(de);
    } else {
        event(e);
    }
}
JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObject *callee,
                                              const JSC::ArgList &args)
{
    Q_ASSERT(callee->inherits(&QScriptObject::info));
    QScriptObject *obj = static_cast<QScriptObject*>(callee);
    QScriptObjectDelegate *delegate = obj->delegate();
    QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();

    QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
    //JSC::ExecState *oldFrame = eng_p->currentFrame;
    eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
    QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);

    QScriptValue defaultObject = ctx->thisObject();
    QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)));
    if (!result.isObject())
        result = defaultObject;
    return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}
Exemple #10
0
JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee,
                                                      const JSC::ArgList &args)
{
    FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee);
    QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);

    JSC::ExecState *oldFrame = eng_p->currentFrame;
    eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
    QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);

    QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p) , self->data->arg);
    if (!result.isObject())
        result = ctx->thisObject();

    eng_p->popContext();
    eng_p->currentFrame = oldFrame;

    return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}
Exemple #11
0
static QScriptValue loadScripts(QScriptContext *context, QScriptEngine *engine)
{
    for (int i = 0; i < context->argumentCount(); ++i) {
        QString fileName = context->argument(0).toString();
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
            return context->throwError(QString::fromLatin1("could not open %0 for reading").arg(fileName));
        QTextStream ts(&file);
        QString contents = ts.readAll();
        file.close();
        QScriptContext *pc = context->parentContext();
        context->setActivationObject(pc->activationObject());
        context->setThisObject(pc->thisObject());
        QScriptValue ret = engine->evaluate(contents);
        if (engine->hasUncaughtException())
            return ret;
    }
    return engine->undefinedValue();
}
Exemple #12
0
bool HttpHandlerQtScriptFile::handleRequest(Pillow::HttpConnection *request)
{
	if (!_lastModified.isValid() || (_autoReload && QFileInfo(_fileName).lastModified() > _lastModified))
	{
		// Time to (re)load the script.
		qDebug() << "HttpHandlerQtScriptFile::handleRequest: (re)loading" << _fileName;
		QFile file(_fileName);
		if (!file.open(QIODevice::ReadOnly))
		{
			request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Could not read file %1").arg(_fileName));
			return true;
		}

		QScriptEngine* engine = _scriptObject.engine();
		_scriptObject = engine->newObject();
		QScriptContext* context = engine->pushContext();
		context->setActivationObject(_scriptObject);
		context->setThisObject(_scriptObject);
		QScriptValue result = engine->evaluate(file.readAll(), _fileName);
		engine->popContext();

		if (result.isError())
		{
			request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Error while evaluating script %1: %2").arg(_fileName).arg(objectToString(result)));
			return true;
		}

		QScriptValue scriptFunction = _scriptObject.property(_functionName);
		if (!scriptFunction.isFunction())
		{
			request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Error while evaluating script %1: '%2' is not a function defined in the script").arg(_fileName).arg(_functionName));
			return true;
		}

		_lastModified = QFileInfo(_fileName).lastModified();
		setScriptFunction(scriptFunction);
	}

	return HttpHandlerQtScript::handleRequest(request);
}
QList<JSAgentStackData> QJSDebuggerAgent::backtrace()
{
    SetupExecEnv execEnv(d);

    QList<JSAgentStackData> backtrace;

    for (QScriptContext *ctx = engine()->currentContext(); ctx; ctx = ctx->parentContext()) {
        QScriptContextInfo info(ctx);

        JSAgentStackData frame;
        frame.functionName = info.functionName().toUtf8();
        if (frame.functionName.isEmpty()) {
            if (ctx->parentContext()) {
                switch (info.functionType()) {
                case QScriptContextInfo::ScriptFunction:
                    frame.functionName = "<anonymous>";
                    break;
                case QScriptContextInfo::NativeFunction:
                    frame.functionName = "<native>";
                    break;
                case QScriptContextInfo::QtFunction:
                case QScriptContextInfo::QtPropertyFunction:
                    frame.functionName = "<native slot>";
                    break;
                }
            } else {
                frame.functionName = "<global>";
            }
        }
        frame.lineNumber = info.lineNumber();
        // if the line number is unknown, fallback to the function line number
        if (frame.lineNumber == -1)
            frame.lineNumber = info.functionStartLineNumber();

        frame.fileUrl = info.fileName().toUtf8();
        backtrace.append(frame);
    }

    return backtrace;
}
Exemple #14
0
	static QScriptValue includeFunction(QScriptContext *context, QScriptEngine *engine)
    {
        QString filename = prefixFilenameWithCurrentPath(context->argument(0).toString(), engine);
        QFile file(filename);
        if(!file.open(QIODevice::ReadOnly))
        {
			Code::CodeClass::throwError(context, engine, QStringLiteral("IncludeFileError"), QObject::tr("Unable to include file %1").arg(filename));
            return context->thisObject();
        }

		QString fileContent = QString::fromUtf8(file.readAll());
        file.close();

        QScriptContext *parent = context->parentContext();
        if(parent)
        {
            context->setActivationObject(parent->activationObject());
            context->setThisObject(parent->thisObject());
        }

		return engine->evaluate(fileContent, filename);
	}
Exemple #15
0
QVariant TestClass::extension(Extension extension,
                              const QVariant &argument)
{
    m_lastExtensionType = extension;
    m_lastExtensionArgument = argument;
    if (extension == Callable) {
        Q_ASSERT(m_callableMode != NotCallable);
        QScriptContext *ctx = qvariant_cast<QScriptContext*>(argument);
        if (m_callableMode == CallableReturnsSum) {
            qsreal sum = 0;
            for (int i = 0; i < ctx->argumentCount(); ++i)
                sum += ctx->argument(i).toNumber();
            QScriptValueIterator it(ctx->callee());
            while (it.hasNext()) {
                it.next();
                sum += it.value().toNumber();
            }
            return sum;
        } else if (m_callableMode == CallableReturnsArgument) {
            return qVariantFromValue(ctx->argument(0));
        } else if (m_callableMode == CallableReturnsInvalidVariant) {
            return QVariant();
        } else if (m_callableMode == CallableReturnsGlobalObject) {
            return qVariantFromValue(engine()->globalObject());
        } else if (m_callableMode == CallableReturnsThisObject) {
            return qVariantFromValue(ctx->thisObject());
        } else if (m_callableMode == CallableReturnsCallee) {
            return qVariantFromValue(ctx->callee());
        } else if (m_callableMode == CallableReturnsArgumentsObject) {
            return qVariantFromValue(ctx->argumentsObject());
        } else if (m_callableMode == CallableInitializesThisObject) {
            engine()->newQObject(ctx->thisObject(), engine());
            return QVariant();
        }
    } else if (extension == HasInstance) {
        Q_ASSERT(m_hasInstance);
        QScriptValueList args = qvariant_cast<QScriptValueList>(argument);
        QScriptValue obj = args.at(0);
        QScriptValue value = args.at(1);
        return value.property("foo").equals(obj.property("foo"));
    }
    return QVariant();
}
void JavascriptInstance::IncludeFile(const QString &path)
{
    for(uint i = 0; i < includedFiles.size(); ++i)
        if (includedFiles[i].toLower() == path.toLower())
        {
            LogDebug("JavascriptInstance::IncludeFile: Not including already included file " + path);
            return;
        }

    QString script = LoadScript(path);

    QScriptContext *context = engine_->currentContext();
    assert(context);
    if (!context)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::currentContext() returned null!");
        return;
    }

    QScriptContext *parent = context->parentContext();
    if (!parent)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::parentContext() returned null!");
        return;
    }

    context->setActivationObject(context->parentContext()->activationObject());
    context->setThisObject(context->parentContext()->thisObject());

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(script);
    if(syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("JavascriptInstance::IncludeFile: Syntax error in " + path + ". " + syntaxResult.errorMessage() +
            " In line:" + QString::number(syntaxResult.errorLineNumber()));
        return;
    }

    QScriptValue result = engine_->evaluate(script, path);

    includedFiles.push_back(path);
    
    if (engine_->hasUncaughtException())
        LogError(result.toString());
}
Exemple #17
0
QVariant JSEmitClass::extension( Extension extension, const QVariant& argument )
{
    Q_UNUSED(argument);

    if (extension == Callable)
    {
        // QScriptContext *context = qvariant_cast<QScriptContext*>(argument);
        QScriptContext *context = engine()->currentContext();
        if ( context->argumentCount() != 2)
        {
            context->throwError("emit() accepts exactly two parameters");
            return QVariant();
        }
        if ( !context->argument(0).isArray() )
        {
            context->throwError("The first argument to emit() must be an array");
            return QVariant();
        }
        qDebug("emit(%s,%s)", qPrintable(context->argument(0).toString()), qPrintable(context->argument(1).toString()));
        return QVariant(true);
    }
    return QVariant();
}
/*!
  Applies the given \a command to the given \a backend.
*/
QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
    QScriptDebuggerBackend *backend,
    const QScriptDebuggerCommand &command)
{
    QScriptDebuggerResponse response;
    switch (command.type()) {
    case QScriptDebuggerCommand::None:
        break;

    case QScriptDebuggerCommand::Interrupt:
        backend->interruptEvaluation();
        break;

    case QScriptDebuggerCommand::Continue:
        if (backend->engine()->isEvaluating()) {
            backend->continueEvalution();
            response.setAsync(true);
        }
        break;

    case QScriptDebuggerCommand::StepInto: {
        QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
        int count = attr.isValid() ? attr.toInt() : 1;
        backend->stepInto(count);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::StepOver: {
        QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
        int count = attr.isValid() ? attr.toInt() : 1;
        backend->stepOver(count);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::StepOut:
        backend->stepOut();
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::RunToLocation:
        backend->runToLocation(command.fileName(), command.lineNumber());
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::RunToLocationByID:
        backend->runToLocation(command.scriptId(), command.lineNumber());
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::ForceReturn: {
        int contextIndex = command.contextIndex();
        QScriptDebuggerValue value = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realValue = value.toScriptValue(engine);
        backend->returnToCaller(contextIndex, realValue);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::Resume:
        backend->resume();
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::SetBreakpoint: {
        QScriptBreakpointData data = command.breakpointData();
        if (!data.isValid())
            data = QScriptBreakpointData(command.fileName(), command.lineNumber());
        int id = backend->setBreakpoint(data);
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::DeleteBreakpoint: {
        int id = command.breakpointId();
        if (!backend->deleteBreakpoint(id))
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::DeleteAllBreakpoints:
        backend->deleteAllBreakpoints();
        break;

    case QScriptDebuggerCommand::GetBreakpoints: {
        QScriptBreakpointMap bps = backend->breakpoints();
        if (!bps.isEmpty())
            response.setResult(bps);
    }   break;

    case QScriptDebuggerCommand::GetBreakpointData: {
        int id = command.breakpointId();
        QScriptBreakpointData data = backend->breakpointData(id);
        if (data.isValid())
            response.setResult(data);
        else
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::SetBreakpointData: {
        int id = command.breakpointId();
        QScriptBreakpointData data = command.breakpointData();
        if (!backend->setBreakpointData(id, data))
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::GetScripts: {
        QScriptScriptMap scripts = backend->scripts();
        if (!scripts.isEmpty())
            response.setResult(scripts);
    }   break;

    case QScriptDebuggerCommand::GetScriptData: {
        qint64 id = command.scriptId();
        QScriptScriptData data = backend->scriptData(id);
        if (data.isValid())
            response.setResult(data);
        else
            response.setError(QScriptDebuggerResponse::InvalidScriptID);
    }   break;

    case QScriptDebuggerCommand::ScriptsCheckpoint:
        backend->scriptsCheckpoint();
        response.setResult(QVariant::fromValue(backend->scriptsDelta()));
        break;

    case QScriptDebuggerCommand::GetScriptsDelta:
        response.setResult(QVariant::fromValue(backend->scriptsDelta()));
        break;

    case QScriptDebuggerCommand::ResolveScript:
        response.setResult(backend->resolveScript(command.fileName()));
        break;

    case QScriptDebuggerCommand::GetBacktrace:
        response.setResult(backend->backtrace());
        break;

    case QScriptDebuggerCommand::GetContextCount:
        response.setResult(backend->contextCount());
        break;

    case QScriptDebuggerCommand::GetContextState: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(static_cast<int>(ctx->state()));
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetContextID: {
        int idx = command.contextIndex();
        if ((idx >= 0) && (idx < backend->contextCount()))
            response.setResult(backend->contextIds()[idx]);
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetContextInfo: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(QScriptContextInfo(ctx));
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetThisObject: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(ctx->thisObject());
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetActivationObject: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(ctx->activationObject());
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetScopeChain: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx) {
            QScriptDebuggerValueList dest;
            QScriptValueList src = ctx->scopeChain();
            for (int i = 0; i < src.size(); ++i)
                dest.append(src.at(i));
            response.setResult(dest);
        } else {
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
        }
    }   break;

    case QScriptDebuggerCommand::ContextsCheckpoint: {
        response.setResult(QVariant::fromValue(backend->contextsCheckpoint()));
    }   break;

    case QScriptDebuggerCommand::GetPropertyExpressionValue: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        int lineNumber = command.lineNumber();
        QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
        QStringList path = attr.toStringList();
        if (!ctx || path.isEmpty())
            break;
        QScriptContextInfo ctxInfo(ctx);
        if (ctx->callee().isValid()
            && ((lineNumber < ctxInfo.functionStartLineNumber())
                || (lineNumber > ctxInfo.functionEndLineNumber()))) {
            break;
        }
        QScriptValueList objects;
        int pathIndex = 0;
        if (path.at(0) == QLatin1String("this")) {
            objects.append(ctx->thisObject());
            ++pathIndex;
        } else {
            objects << ctx->scopeChain();
        }
        for (int i = 0; i < objects.size(); ++i) {
            QScriptValue val = objects.at(i);
            for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) {
                val = val.property(path.at(j));
            }
            if (val.isValid()) {
                bool hadException = (ctx->state() == QScriptContext::ExceptionState);
                QString str = val.toString();
                if (!hadException && backend->engine()->hasUncaughtException())
                    backend->engine()->clearExceptions();
                response.setResult(str);
                break;
            }
        }
    }   break;

    case QScriptDebuggerCommand::GetCompletions: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
        QStringList path = attr.toStringList();
        if (!ctx || path.isEmpty())
            break;
        QScriptValueList objects;
        QString prefix = path.last();
        QSet<QString> matches;
        if (path.size() > 1) {
            const QString &topLevelIdent = path.at(0);
            QScriptValue obj;
            if (topLevelIdent == QLatin1String("this")) {
                obj = ctx->thisObject();
            } else {
                QScriptValueList scopeChain;
                scopeChain = ctx->scopeChain();
                for (int i = 0; i < scopeChain.size(); ++i) {
                    QScriptValue oo = scopeChain.at(i).property(topLevelIdent);
                    if (oo.isObject()) {
                        obj = oo;
                        break;
                    }
                }
            }
            for (int i = 1; obj.isObject() && (i < path.size()-1); ++i)
                obj = obj.property(path.at(i));
            if (obj.isValid())
                objects.append(obj);
        } else {
            objects << ctx->scopeChain();
            QStringList keywords;
            keywords.append(QString::fromLatin1("this"));
            keywords.append(QString::fromLatin1("true"));
            keywords.append(QString::fromLatin1("false"));
            keywords.append(QString::fromLatin1("null"));
            for (int i = 0; i < keywords.size(); ++i) {
                const QString &kwd = keywords.at(i);
                if (isPrefixOf(prefix, kwd))
                    matches.insert(kwd);
            }
        }

        for (int i = 0; i < objects.size(); ++i) {
            QScriptValue obj = objects.at(i);
            while (obj.isObject()) {
                QScriptValueIterator it(obj);
                while (it.hasNext()) {
                    it.next();
                    QString propertyName = it.name();
                    if (isPrefixOf(prefix, propertyName))
                        matches.insert(propertyName);
                }
                obj = obj.prototype();
            }
        }
        QStringList matchesList = matches.toList();
        qStableSort(matchesList);
        response.setResult(matchesList);
    }   break;

    case QScriptDebuggerCommand::NewScriptObjectSnapshot: {
        int id = backend->newScriptObjectSnapshot();
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::ScriptObjectSnapshotCapture: {
        int id = command.snapshotId();
        QScriptObjectSnapshot *snap = backend->scriptObjectSnapshot(id);
        Q_ASSERT(snap != 0);
        QScriptDebuggerValue object = command.scriptValue();
        Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        Q_ASSERT(realObject.isObject());
        QScriptObjectSnapshot::Delta delta = snap->capture(realObject);
        QScriptDebuggerObjectSnapshotDelta result;
        result.removedProperties = delta.removedProperties;
        bool didIgnoreExceptions = backend->ignoreExceptions();
        backend->setIgnoreExceptions(true);
        for (int i = 0; i < delta.changedProperties.size(); ++i) {
            const QScriptValueProperty &src = delta.changedProperties.at(i);
            bool hadException = engine->hasUncaughtException();
            QString str = src.value().toString();
            if (!hadException && engine->hasUncaughtException())
                engine->clearExceptions();
            QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
            result.changedProperties.append(dest);
        }
        for (int j = 0; j < delta.addedProperties.size(); ++j) {
            const QScriptValueProperty &src = delta.addedProperties.at(j);
            bool hadException = engine->hasUncaughtException();
            QString str = src.value().toString();
            if (!hadException && engine->hasUncaughtException())
                engine->clearExceptions();
            QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
            result.addedProperties.append(dest);
        }
        backend->setIgnoreExceptions(didIgnoreExceptions);
        response.setResult(QVariant::fromValue(result));
    }   break;

    case QScriptDebuggerCommand::DeleteScriptObjectSnapshot: {
        int id = command.snapshotId();
        backend->deleteScriptObjectSnapshot(id);
    }   break;

    case QScriptDebuggerCommand::NewScriptValueIterator: {
        QScriptDebuggerValue object = command.scriptValue();
        Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        Q_ASSERT(realObject.isObject());
        int id = backend->newScriptValueIterator(realObject);
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::GetPropertiesByIterator: {
        int id = command.iteratorId();
        int count = 1000;
        QScriptValueIterator *it = backend->scriptValueIterator(id);
        Q_ASSERT(it != 0);
        QScriptDebuggerValuePropertyList props;
        for (int i = 0; (i < count) && it->hasNext(); ++i) {
            it->next();
            QString name = it->name();
            QScriptValue value = it->value();
            QString valueAsString = value.toString();
            QScriptValue::PropertyFlags flags = it->flags();
            QScriptDebuggerValueProperty prp(name, value, valueAsString, flags);
            props.append(prp);
        }
        response.setResult(props);
    }   break;

    case QScriptDebuggerCommand::DeleteScriptValueIterator: {
        int id = command.iteratorId();
        backend->deleteScriptValueIterator(id);
    }   break;

    case QScriptDebuggerCommand::Evaluate: {
        int contextIndex = command.contextIndex();
        QString program = command.program();
        QString fileName = command.fileName();
        int lineNumber = command.lineNumber();
        backend->evaluate(contextIndex, program, fileName, lineNumber);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::ScriptValueToString: {
        QScriptDebuggerValue value = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realValue = value.toScriptValue(engine);
        response.setResult(realValue.toString());
    }   break;

    case QScriptDebuggerCommand::SetScriptValueProperty: {
        QScriptDebuggerValue object = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        QScriptDebuggerValue value = command.subordinateScriptValue();
        QScriptValue realValue = value.toScriptValue(engine);
        QString name = command.name();
        realObject.setProperty(name, realValue);
    }   break;

    case QScriptDebuggerCommand::ClearExceptions:
        backend->engine()->clearExceptions();
        break;

    case QScriptDebuggerCommand::UserCommand:
    case QScriptDebuggerCommand::MaxUserCommand:
        break;
    }
    return response;
}
Exemple #19
0
QStringList JSPluginsLoader::names() const {
    QScriptContext *ctx = eng.currentContext();
    QScriptValue jsLdr = ctx->activationObject().property("PluginsLoader").call();                  //var jsLdr = PluginsLoader();
    QStringList plgNames= qscriptvalue_cast<QStringList>(jsLdr.property("names").call(jsLdr));      //plgNames = jsLdr.names();
    return plgNames;
}
/*
    Documented in qdeclarativeengine.cpp
*/
QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *engine)
{
    if (ctxt->argumentCount() == 0)
        return engine->undefinedValue();

    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);

    QUrl contextUrl = ep->contextClass->urlFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));
    if (contextUrl.isEmpty()) 
        return ctxt->throwError(QLatin1String("Qt.include(): Can only be called from JavaScript files"));

    QString urlString = ctxt->argument(0).toString();
    QUrl url(urlString);
    if (url.isRelative()) {
        url = QUrl(contextUrl).resolved(url);
        urlString = url.toString();
    }

    QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);

    QScriptValue func = ctxt->argument(1);
    if (!func.isFunction())
        func = QScriptValue();

    QScriptValue result;
    if (localFile.isEmpty()) {
        QDeclarativeInclude *i = 
            new QDeclarativeInclude(url, QDeclarativeEnginePrivate::getEngine(engine), ctxt);

        if (func.isValid())
            i->setCallback(func);

        result = i->result();
    } else {

        QFile f(localFile);
        if (f.open(QIODevice::ReadOnly)) {
            QByteArray data = f.readAll();
            QString code = QString::fromUtf8(data);

            QDeclarativeContextData *context = 
                ep->contextClass->contextFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));

            QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine);
            scriptContext->pushScope(ep->contextClass->newUrlContext(context, 0, urlString));
            scriptContext->pushScope(ep->globalClass->staticGlobalObject());
            QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
            scriptContext->pushScope(scope);
            scriptContext->setActivationObject(scope);
            QDeclarativeScriptParser::extractPragmas(code);

            engine->evaluate(code, urlString, 1);

            engine->popContext();

            if (engine->hasUncaughtException()) {
                result = resultValue(engine, Exception);
                result.setProperty(QLatin1String("exception"), engine->uncaughtException());
                engine->clearExceptions();
            } else {
                result = resultValue(engine, Ok);
            }
            callback(engine, func, result);
        } else {
            result = resultValue(engine, NetworkError);
            callback(engine, func, result);
        }
    }

    return result;
}
Exemple #21
0
QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined)
{
    QDeclarativeExpressionData *data = this->data;
    QDeclarativeEngine *engine = data->context()->engine;
    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);

    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    if (!data->expressionFunctionValid) {

        QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
        data->expressionContext = ep->contextClass->newContext(data->context(), data->me);
        scriptContext->pushScope(data->expressionContext);
        scriptContext->pushScope(ep->globalClass->globalObject());

        if (data->expressionRewritten) {
            data->expressionFunction = scriptEngine->evaluate(data->expression, 
                                                              data->url, data->line);
        } else {
            QDeclarativeRewrite::RewriteBinding rewriteBinding;

            bool ok = true;
            const QString code = rewriteBinding(data->expression, &ok);
            if (!ok) {
                scriptEngine->popContext();
                return QVariant();
            }
            data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line);
        }

        scriptEngine->popContext();
        data->expressionFunctionValid = true;
    }

    QDeclarativeContextData *oldSharedContext = 0;
    QObject *oldSharedScope = 0;
    QObject *oldOverride = 0;
    if (data->isShared) {
        oldSharedContext = ep->sharedContext;
        oldSharedScope = ep->sharedScope;
        ep->sharedContext = data->context();
        ep->sharedScope = data->me;
    } else {
        oldOverride = ep->contextClass->setOverrideObject(data->expressionContext, secondaryScope);
    }

    QScriptValue svalue = data->expressionFunction.call();

    if (data->isShared) {
        ep->sharedContext = oldSharedContext;
        ep->sharedScope = oldSharedScope;
    } else {
        ep->contextClass->setOverrideObject(data->expressionContext, oldOverride);
    }

    if (isUndefined)
        *isUndefined = svalue.isUndefined() || scriptEngine->hasUncaughtException();

    // Handle exception
    if (scriptEngine->hasUncaughtException()) {
       exceptionToError(scriptEngine, data->error);
       scriptEngine->clearExceptions();
       return QVariant();
    } else {
        data->error = QDeclarativeError();
    }

    QVariant rv;

    if (svalue.isArray()) {
        int length = svalue.property(QLatin1String("length")).toInt32();
        if (length && svalue.property(0).isObject()) {
            QList<QObject *> list;
            for (int ii = 0; ii < length; ++ii) {
                QScriptValue arrayItem = svalue.property(ii);
                QObject *d = arrayItem.toQObject();
                list << d;
            }
            rv = QVariant::fromValue(list);
        }
    } else if (svalue.isObject() &&
               ep->objectClass->scriptClass(svalue) == ep->objectClass) {
        QObject *o = svalue.toQObject();
        int type = QMetaType::QObjectStar;
        // If the object is null, we extract the predicted type.  While this isn't
        // 100% reliable, in many cases it gives us better error messages if we
        // assign this null-object to an incompatible property
        if (!o) type = ep->objectClass->objectType(svalue);

        return QVariant(type, &o);
    }

    if (rv.isNull())
        rv = svalue.toVariant();

    return rv;
}
void tst_QScriptContext::getSetActivationObject()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.currentContext();
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));

    ctx->setActivationObject(QScriptValue());
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));
    QCOMPARE(ctx->engine(), &eng);

    QScriptValue obj = eng.newObject();
    ctx->setActivationObject(obj);
    QVERIFY(ctx->activationObject().equals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).equals(obj));

    {
        QScriptEngine eng2;
        QScriptValue obj2 = eng2.newObject();
        QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setActivationObject() failed: cannot set an object created in a different engine");
        QScriptValue was = ctx->activationObject();
        ctx->setActivationObject(obj2);
        QVERIFY(ctx->activationObject().equals(was));
    }

    ctx->setActivationObject(eng.globalObject());
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));
    QScriptValue fun = eng.newFunction(get_activationObject);
    eng.globalObject().setProperty("get_activationObject", fun);
    {
        QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)");
        QVERIFY(ret.isObject());
        QScriptValue arguments = ret.property("arguments");
        QEXPECT_FAIL("", "Getting arguments property of activation object doesn't work", Abort);
        QVERIFY(arguments.isObject());
        QCOMPARE(arguments.property("length").toInt32(), 3);
        QCOMPARE(arguments.property("0").toInt32(), 1);
        QCOMPARE(arguments.property("1").toInt32(), 1);
        QCOMPARE(arguments.property("2").toInt32(), 1);
    }
}
void tst_QScriptContext::pushAndPopContext()
{
    QScriptEngine eng;
    QScriptContext *topLevel = eng.currentContext();
    QCOMPARE(topLevel->engine(), &eng);

    QScriptContext *ctx = eng.pushContext();
    QVERIFY(ctx != 0);
    QCOMPARE(ctx->parentContext(), topLevel);
    QCOMPARE(eng.currentContext(), ctx);
    QCOMPARE(ctx->engine(), &eng);
    QCOMPARE(ctx->state(), QScriptContext::NormalState);
    QCOMPARE(ctx->isCalledAsConstructor(), false);
    QCOMPARE(ctx->argumentCount(), 0);
    QCOMPARE(ctx->argument(0).isUndefined(), true);
    QVERIFY(!ctx->argument(-1).isValid());
    QCOMPARE(ctx->argumentsObject().isObject(), true);
    QCOMPARE(ctx->activationObject().isObject(), true);
    QCOMPARE(ctx->callee().isValid(), false);
    QCOMPARE(ctx->thisObject().strictlyEquals(eng.globalObject()), true);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).equals(ctx->activationObject()));
    QVERIFY(ctx->scopeChain().at(1).equals(eng.globalObject()));

    QScriptContext *ctx2 = eng.pushContext();
    QCOMPARE(ctx2->parentContext(), ctx);
    QCOMPARE(eng.currentContext(), ctx2);

    eng.popContext();
    QCOMPARE(eng.currentContext(), ctx);
    eng.popContext();
    QCOMPARE(eng.currentContext(), topLevel);

    // popping the top-level context is not allowed
    QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::popContext() doesn't match with pushContext()");
    eng.popContext();
    QCOMPARE(eng.currentContext(), topLevel);

    {
        QScriptContext *ctx3 = eng.pushContext();
        ctx3->activationObject().setProperty("foo", QScriptValue(&eng, 123));
        QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123)));
        eng.evaluate("var bar = 'ciao'");
        QVERIFY(ctx3->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao")));
        eng.popContext();
    }

    {
        QScriptContext *ctx4 = eng.pushContext();
        QScriptValue obj = eng.newObject();
        obj.setProperty("prop", QScriptValue(&eng, 456));
        ctx4->setThisObject(obj);
        QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1");
        QCOMPARE(eng.currentContext(), ctx4);
        QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457)));
        eng.popContext();
    }

    // throwing an exception
    {
        QScriptContext *ctx5 = eng.pushContext();
        QScriptValue ret = eng.evaluate("throw new Error('oops')");
        QVERIFY(ret.isError());
        QVERIFY(eng.hasUncaughtException());
        QCOMPARE(eng.currentContext(), ctx5);
        eng.popContext();
    }
}
void tst_QScriptContext::popNativeContextScope()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.pushContext();
    QVERIFY(ctx->popScope().isObject()); // the activation object

    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));
    // This was different in 4.5: scope and activation were decoupled
    QVERIFY(ctx->activationObject().strictlyEquals(eng.globalObject()));

    QVERIFY(!eng.evaluate("var foo = 123; function bar() {}").isError());
    QVERIFY(eng.globalObject().property("foo").isNumber());
    QVERIFY(eng.globalObject().property("bar").isFunction());

    QScriptValue customScope = eng.newObject();
    ctx->pushScope(customScope);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(customScope));
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));
    QVERIFY(ctx->activationObject().strictlyEquals(eng.globalObject()));
    ctx->setActivationObject(customScope);
    QVERIFY(ctx->activationObject().strictlyEquals(customScope));
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(customScope));
    QEXPECT_FAIL("", "QTBUG-11012", Continue);
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));

    QVERIFY(!eng.evaluate("baz = 456; var foo = 789; function barbar() {}").isError());
    QEXPECT_FAIL("", "QTBUG-11012", Continue);
    QVERIFY(eng.globalObject().property("baz").isNumber());
    QVERIFY(customScope.property("foo").isNumber());
    QVERIFY(customScope.property("barbar").isFunction());

    QVERIFY(ctx->popScope().strictlyEquals(customScope));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QEXPECT_FAIL("", "QTBUG-11012", Continue);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    // Need to push another object, otherwise we crash in popContext() (QTBUG-11012)
    ctx->pushScope(customScope);
    eng.popContext();
}
void ScriptDebuggerPrivate::positionChange(qint64 scriptId,
                                           int lineNumber, int /*columnNumber*/)
{
    ScriptInfo *info = 0;
    bool enterInteractiveMode = false;

    if (m_bpManager->hasBreakpoints()) {
        // check if we hit a breakpoint
        info = m_scripts.value(scriptId);
        QScriptContext *ctx = engine()->currentContext();
        QScriptContextInfo ctxInfo(ctx);
        QScriptValue callee = ctx->callee();

        // try fileName:lineNumber
        int bpid = m_bpManager->findBreakpoint(info->fileName(), lineNumber);
        if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
            message(QString::fromLatin1("Breakpoint %0 at %1:%2")
                    .arg(bpid + 1).arg(info->fileName()).arg(lineNumber));
            if (m_bpManager->isBreakpointSingleShot(bpid))
                m_bpManager->removeBreakpoint(bpid);
        }
        if (bpid == -1) {
            // try function
            bpid = m_bpManager->findBreakpoint(callee);
            if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
                message(QString::fromLatin1("Breakpoint %0, %1()")
                        .arg(bpid + 1).arg(ctxInfo.functionName()));
                if (m_bpManager->isBreakpointSingleShot(bpid))
                    m_bpManager->removeBreakpoint(bpid);
            }
        }
        if ((bpid == -1) && !ctxInfo.functionName().isEmpty()) {
            // try functionName:fileName
            bpid = m_bpManager->findBreakpoint(ctxInfo.functionName(), ctxInfo.fileName());
            if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
                message(QString::fromLatin1("Breakpoint %0, %1():%2").arg(bpid + 1)
                        .arg(ctxInfo.functionName()).arg(ctxInfo.fileName()));
                if (m_bpManager->isBreakpointSingleShot(bpid))
                    m_bpManager->removeBreakpoint(bpid);
            }
        }

        enterInteractiveMode = (bpid != -1);
    }

    switch (mode()) {
    case Run:
        break;

    case StepInto:
        enterInteractiveMode = true;
        break;

    case StepOver:
        enterInteractiveMode = enterInteractiveMode || (m_stepDepth <= 0);
        break;
    }

    if (enterInteractiveMode) {
        if (!info)
            info = m_scripts.value(scriptId);
        Q_ASSERT(info);        
        message(QString::fromLatin1("%0\t%1").arg(lineNumber).arg(info->lineText(lineNumber)));
        interactive();
    }
}
bool ScriptDebuggerPrivate::executeCommand(const QString &command, const QStringList &args)
{
    if (command == QLatin1String("c")
        || command == QLatin1String("continue")) {
        setMode(Run);
        return true;
    } else if (command == QLatin1String("s")
               || command == QLatin1String("step")) {
        setMode(StepInto);
        return true;
    } else if (command == QLatin1String("n")
               || command == QLatin1String("next")) {
        setMode(StepOver);
        m_stepDepth = 0;
        return true;
    } else if (command == QLatin1String("f")
               || command == QLatin1String("frame")) {
        bool ok = false;
        int index = args.value(0).toInt(&ok);
        if (ok) {
            if (index < 0 || index >= frameCount()) {
                errorMessage("No such frame.");
            } else {
                setCurrentFrameIndex(index);
                QScriptContext *ctx = currentFrameContext();
                message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
            }
        }
    } else if (command == QLatin1String("bt")
               || command == QLatin1String("backtrace")) {
        QScriptContext *ctx = engine()->currentContext();
        int index = -1;
        while (ctx) {
            ++index;
            QString line = ctx->toString();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(line));
            ctx = ctx->parentContext();
        }
    } else if (command == QLatin1String("up")) {
        int index = currentFrameIndex() + 1;
        if (index == frameCount()) {
            errorMessage(QString::fromLatin1("Initial frame selected; you cannot go up."));
        } else {
            setCurrentFrameIndex(index);
            QScriptContext *ctx = currentFrameContext();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
        }
    } else if (command == QLatin1String("down")) {
        int index = currentFrameIndex() - 1;
        if (index < 0) {
            errorMessage(QString::fromLatin1("Bottom (innermost) frame selected; you cannot go down."));
        } else {
            setCurrentFrameIndex(index);
            QScriptContext *ctx = currentFrameContext();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
        }
    } else if (command == QLatin1String("b")
               || command == QLatin1String("break")) {
        QString str = args.value(0);
        int colonIndex = str.indexOf(QLatin1Char(':'));
        if (colonIndex != -1) {
            // filename:line form
            QString fileName = str.left(colonIndex);
            int lineNumber = str.mid(colonIndex+1).toInt();
            int id = m_bpManager->setBreakpoint(fileName, lineNumber);
            message(QString::fromLatin1("Breakpoint %0 at %1, line %2.").arg(id+1).arg(fileName).arg(lineNumber));
        } else {
            // function
            QScriptValue fun = engine()->globalObject().property(str);
            if (fun.isFunction()) {
                int id = m_bpManager->setBreakpoint(fun);
                message(QString::fromLatin1("Breakpoint %0 at %1().").arg(id+1).arg(str));
            }
        }
    } else if (command == QLatin1String("d")
               || command == QLatin1String("delete")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->removeBreakpoint(id);
    } else if (command == QLatin1String("disable")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->setBreakpointEnabled(id, false);
    } else if (command == QLatin1String("enable")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->setBreakpointEnabled(id, true);
    } else if (command == QLatin1String("list")) {
        QScriptContext *ctx = currentFrameContext();
        ScriptInfo *progInfo = scriptInfo(ctx);
        if (!progInfo) {
            errorMessage("No source text available for this frame.");
        } else {
            QScriptContextInfo ctxInfo(ctx);
            bool ok;
            int line = args.value(0).toInt(&ok);
            if (ok) {
                line = qMax(1, line - 5);
            } else {
                line = listLineNumber();
                if (line == -1)
                    line = qMax(progInfo->lineNumber(), ctxInfo.lineNumber() - 5);
            }
            for (int i = line; i < line + 10; ++i) {
                message(QString::fromLatin1("%0\t%1").arg(i).arg(progInfo->lineText(i)));
            }
            setListLineNumber(line + 10);
        }
    } else if (command == QLatin1String("info")) {
        if (args.size() < 1) {
        } else {
            QString what = args.value(0);
            if (what == QLatin1String("locals")) {
                QScriptValueIterator it(currentFrameContext()->activationObject());
                while (it.hasNext()) {
                    it.next();
                    QString line;
                    line.append(it.name());
                    line.append(QLatin1String(" = "));
                    line.append(safeValueToString(it.value()));
                    message(line);
                }
            }
        }
    } else if (command == QLatin1String("help")) {
        message("continue - continue execution\n"
                "step     - step into statement\n"
                "next     - step over statement\n"
                "list     - show where you are\n"
                "\n"
                "break    - set breakpoint\n"
                "delete   - remove breakpoint\n"
                "disable  - disable breakpoint\n"
                "enable   - enable breakpoint\n"
                "\n"
                "backtrace - show backtrace\n"
                "up       - one frame up\n"
                "down     - one frame down\n"
                "frame    - set frame\n"
                "\n"
                "info locals - show local variables");
    } else {
        errorMessage(QString::fromLatin1("Undefined command \"%0\". Try \"help\".")
                     .arg(command));
    }

    return false;
}
void tst_QScriptContext::pushAndPopScope()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.currentContext();
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    QVERIFY(ctx->popScope().strictlyEquals(eng.globalObject()));
    ctx->pushScope(eng.globalObject());
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    QScriptValue obj = eng.newObject();
    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(obj));
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));

    QVERIFY(ctx->popScope().strictlyEquals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    {
        QScriptValue ret = eng.evaluate("x");
        QVERIFY(ret.isError());
        eng.clearExceptions();
    }
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    // task 236685
    QScriptValue qobj = eng.newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::AutoCreateDynamicProperties);
    ctx->pushScope(qobj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(qobj));
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));
    {
        QScriptValue ret = eng.evaluate("print");
        QVERIFY(ret.isFunction());
    }
    ctx->popScope();

    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(obj));
    obj.setProperty("x", 123);
    {
        QScriptValue ret = eng.evaluate("x");
        QVERIFY(ret.isNumber());
        QCOMPARE(ret.toInt32(), 123);
    }
    QVERIFY(ctx->popScope().strictlyEquals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    ctx->pushScope(QScriptValue());
    QCOMPARE(ctx->scopeChain().size(), 1);

    QVERIFY(ctx->popScope().strictlyEquals(eng.globalObject()));
    QVERIFY(ctx->scopeChain().isEmpty());

    // Used to work with old back-end, doesn't with new one because JSC requires that the last object in
    // a scope chain is the Global Object.
    QTest::ignoreMessage(QtWarningMsg, "QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object");
    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 0);

    QScriptEngine eng2;
    QScriptValue obj2 = eng2.newObject();
    QTest::ignoreMessage(QtWarningMsg, "QScriptContext::pushScope() failed: cannot push an object created in a different engine");
    ctx->pushScope(obj2);
    QVERIFY(ctx->scopeChain().isEmpty());

    QVERIFY(!ctx->popScope().isValid());
}
QScriptValue include( QScriptContext *context, QScriptEngine *engine )
{
    // Check argument count, include() call in global context?
    const QScriptContextInfo contextInfo( context->parentContext() );
    if ( context->argumentCount() < 1 ) {
        context->throwError( i18nc("@info/plain", "One argument expected for <icode>include()</icode>") );
        return engine->undefinedValue();
    } else if ( context->parentContext() && context->parentContext()->parentContext() ) {
        QScriptContext *parentContext = context->parentContext()->parentContext();
        bool error = false;
        while ( parentContext ) {
            const QScriptContextInfo parentContextInfo( parentContext );
            if ( !parentContextInfo.fileName().isEmpty() &&
                 parentContextInfo.fileName() == contextInfo.fileName() )
            {
                // Parent context is in the same file, error
                error = true;
                break;
            }
            parentContext = parentContext->parentContext();
        }

        if ( error ) {
            context->throwError( i18nc("@info/plain", "<icode>include()</icode> calls must be in global context") );
            return engine->undefinedValue();
        }
    }

    // Check if this include() call is before all other statements
    QVariantHash includeData = context->callee().data().toVariant().toHash();
    if ( includeData.contains(contextInfo.fileName()) ) {
        const quint16 maxIncludeLine = includeData[ contextInfo.fileName() ].toInt();
        if ( contextInfo.lineNumber() > maxIncludeLine ) {
            context->throwError( i18nc("@info/plain", "<icode>include()</icode> calls must be the first statements") );
            return engine->undefinedValue();
        }
    }

    // Get argument and check that it's not pointing to another directory
    const QString fileName = context->argument(0).toString();
    if ( fileName.contains('/') ) {
        context->throwError( i18nc("@info/plain", "Cannot include files from other directories") );
        return engine->undefinedValue();
    }

    // Get path of the main script
    QString path;
    QScriptContext *fileInfoContext = context;
    do {
        path = QFileInfo( QScriptContextInfo(fileInfoContext).fileName() ).path();
        fileInfoContext = fileInfoContext->parentContext();
    } while ( path.isEmpty() || path == QLatin1String(".") );

    // Construct file path to the file to be included and check if the file is already included
    const QString filePath = path + '/' + fileName;
    QStringList includedFiles =
            engine->globalObject().property( "includedFiles" ).toVariant().toStringList();
    if ( includedFiles.contains(filePath) ) {
        kWarning() << "File already included" << filePath;
        return engine->undefinedValue();
    }

    // Try to open the file to be included
    QFile scriptFile( filePath );
    if ( !scriptFile.open(QIODevice::ReadOnly) ) {
        context->throwError( i18nc("@info/plain", "Cannot find file to be included: "
                                   "<filename>%1</filename>", filePath) );
        return engine->undefinedValue();
    }

    // Read the file
    QTextStream stream( &scriptFile );
    const QString program = stream.readAll();
    scriptFile.close();

    if ( !includeData.contains(scriptFile.fileName()) ) {
        includeData[ scriptFile.fileName() ] = maxIncludeLine( program );

        QScriptValue includeFunction = engine->globalObject().property("include");
        Q_ASSERT( includeFunction.isValid() );
        includeFunction.setData( qScriptValueFromValue(engine, includeData) );
        engine->globalObject().setProperty( "include", includeFunction,
                                            QScriptValue::KeepExistingFlags );
    }

    // Set script context
    QScriptContext *parent = context->parentContext();
    if ( parent ) {
        context->setActivationObject( parent->activationObject() );
        context->setThisObject( parent->thisObject() );
    }

    // Store included files in global property "includedFiles"
    includedFiles << filePath;
    includedFiles.removeDuplicates();
    QScriptValue::PropertyFlags flags = QScriptValue::ReadOnly | QScriptValue::Undeletable;
    engine->globalObject().setProperty( "includedFiles", engine->newVariant(includedFiles), flags );

    // Evaluate script
    return engine->evaluate( program, filePath );
}
Exemple #29
0
void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script)
{
    if (!engine)
        return;

    QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    const QString &code = script.code;
    const QString &url = script.file;
    const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas;

    Q_ASSERT(!url.isEmpty());

    if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) {

        QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url);
        if (iter == enginePriv->m_sharedScriptImports.end()) {
            QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);

            scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url));
            scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());

            QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
            scriptContext->pushScope(scope);

            scriptEngine->evaluate(code, url, 1);

            if (scriptEngine->hasUncaughtException()) {
                QDeclarativeError error;
                QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
                enginePriv->warning(error);
            }

            scriptEngine->popContext();

            iter = enginePriv->m_sharedScriptImports.insert(url, scope);
        }

        importedScripts.append(*iter);

    } else {

        QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);

        scriptContext->pushScope(enginePriv->contextClass->newUrlContext(this, 0, url));
        scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());

        QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
        scriptContext->pushScope(scope);

        scriptEngine->evaluate(code, url, 1);

        if (scriptEngine->hasUncaughtException()) {
            QDeclarativeError error;
            QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
            enginePriv->warning(error);
        }

        scriptEngine->popContext();

        importedScripts.append(scope);

    }
}
Exemple #30
0
QScriptValue DirClass::createInstance(const QScriptContext &context)
{
    return context.argumentCount() > 0
            ? newInstance(context.argument(0).toString())
            : newInstance();
}