QScriptValue QScriptDebuggerBackendPrivate::qsassert(QScriptContext *context, QScriptEngine *engine) { QScriptValue arg = context->argument(0); if (arg.toBoolean()) return arg; QScriptContextInfo info(context->parentContext()); QString msg; QString fileName = info.fileName(); if (fileName.isEmpty()) fileName = QString::fromLatin1("<anonymous script, id=%0>").arg(info.scriptId()); msg.append(fileName); msg.append(QLatin1Char(':')); msg.append(QString::number(info.lineNumber())); msg.append(QString::fromLatin1(": Assertion failed")); for (int i = 1; i < context->argumentCount(); ++i) { if (i == 1) msg.append(QLatin1Char(':')); msg.append(QLatin1Char(' ')); msg.append(context->argument(i).toString()); } QScriptValue err = context->throwError(msg); err.setProperty(QString::fromLatin1("name"), QScriptValue(engine, QString::fromLatin1("AssertionError"))); return err; }
static void breakpointDataFromScriptValue(const QScriptValue &in, QScriptBreakpointData &out) { QScriptValue scriptId = in.property(QString::fromLatin1("scriptId")); if (scriptId.isValid()) out.setScriptId((qint64)scriptId.toNumber()); out.setFileName(in.property(QString::fromLatin1("fileName")).toString()); out.setLineNumber(in.property(QString::fromLatin1("lineNumber")).toInt32()); QScriptValue enabled = in.property(QString::fromLatin1("enabled")); if (enabled.isValid()) out.setEnabled(enabled.toBoolean()); QScriptValue singleShot = in.property(QString::fromLatin1("singleShot")); if (singleShot.isValid()) out.setSingleShot(singleShot.toBoolean()); out.setIgnoreCount(in.property(QString::fromLatin1("ignoreCount")).toInt32()); out.setCondition(in.property(QString::fromLatin1("condition")).toString()); }
QScriptDebuggerValue::QScriptDebuggerValue(const QScriptValue &value) : d_ptr(0) { if (value.isValid()) { d_ptr = new QScriptDebuggerValuePrivate; if (value.isUndefined()) d_ptr->type = UndefinedValue; else if (value.isNull()) d_ptr->type = NullValue; else if (value.isNumber()) { d_ptr->type = NumberValue; d_ptr->numberValue = value.toNumber(); } else if (value.isBoolean()) { d_ptr->type = BooleanValue; d_ptr->booleanValue = value.toBoolean(); } else if (value.isString()) { d_ptr->type = StringValue; d_ptr->stringValue = new QString(value.toString()); } else { Q_ASSERT(value.isObject()); d_ptr->type = ObjectValue; d_ptr->objectId = value.objectId(); } d_ptr->ref.ref(); } }
void TimerClass::setProperty(QScriptValue &object, const QScriptString &name, uint /*id*/, const QScriptValue &value) { QTimer *timer = qscriptvalue_cast<QTimer*>(object.data()); qDebug() << "Value after de-varianting setProperty: " << timer << name; if (!timer) return; if (name == _interval) { timer->setInterval(value.toInt32()); } else if (name == _singleShot) { timer->setSingleShot(value.toBoolean()); } }
/*! \reimp */ void QScriptDebuggerAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber) { Q_D(QScriptDebuggerAgent); if (engine()->processEventsInterval() == -1) { // see if it's time to call processEvents() if ((++d->statementCounter % 25000) == 0) { if (!d->processEventsTimer.isNull()) { if (d->processEventsTimer.elapsed() > 30) { QCoreApplication::processEvents(); d->processEventsTimer.restart(); } } else { d->processEventsTimer.start(); } } } // check breakpoints { QList<int> lst = d->resolvedBreakpoints.value(scriptId); for (int i = 0; i < lst.size(); ++i) { int id = lst.at(i); QScriptBreakpointData &data = d->breakpoints[id]; if (!data.isEnabled()) continue; if (data.lineNumber() != lineNumber) continue; if (!data.condition().isEmpty()) { // ### careful, evaluate() can cause an exception // ### disable callbacks in nested evaluate? QScriptDebuggerAgentPrivate::State was = d->state; d->state = QScriptDebuggerAgentPrivate::NoState; QScriptValue ret = engine()->evaluate( data.condition(), QString::fromLatin1("Breakpoint %0 condition checker").arg(id)); if (!ret.isError()) d->state = was; if (!ret.toBoolean()) continue; } if (!data.hit()) continue; d->hitBreakpointId = id; d->state = QScriptDebuggerAgentPrivate::BreakpointState; } } switch (d->state) { case QScriptDebuggerAgentPrivate::NoState: case QScriptDebuggerAgentPrivate::SteppingOutState: case QScriptDebuggerAgentPrivate::ReturningByForceState: // Do nothing break; case QScriptDebuggerAgentPrivate::SteppingIntoState: if (--d->stepCount == 0) { d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->stepped(scriptId, lineNumber, columnNumber, QScriptValue()); } break; case QScriptDebuggerAgentPrivate::SteppingOverState: if ((d->stepDepth > 0) || (--d->stepCount != 0)) break; // fallthrough case QScriptDebuggerAgentPrivate::SteppedOverState: d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult); break; case QScriptDebuggerAgentPrivate::SteppedOutState: d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult); break; case QScriptDebuggerAgentPrivate::RunningToLocationState: if (((lineNumber == d->targetLineNumber) || (d->targetLineNumber == -1)) && (scriptId == d->targetScriptId)) { d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->locationReached(scriptId, lineNumber, columnNumber); } break; case QScriptDebuggerAgentPrivate::InterruptingState: d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->interrupted(scriptId, lineNumber, columnNumber); break; case QScriptDebuggerAgentPrivate::BreakpointState: d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->breakpoint(scriptId, lineNumber, columnNumber, d->hitBreakpointId); if (d->breakpoints.value(d->hitBreakpointId).isSingleShot()) deleteBreakpoint(d->hitBreakpointId); break; case QScriptDebuggerAgentPrivate::ReturnedByForceState: d->state = QScriptDebuggerAgentPrivate::NoState; if (d->backend) d->backend->forcedReturn(scriptId, lineNumber, columnNumber, d->returnValue); break; case QScriptDebuggerAgentPrivate::SteppedIntoState: case QScriptDebuggerAgentPrivate::ReachedLocationState: case QScriptDebuggerAgentPrivate::InterruptedState: // ### deal with the case when code is evaluated while we're already paused // Q_ASSERT(false); break; } }
void tst_QScriptClass::extension() { QScriptEngine eng; { TestClass cls(&eng); cls.setCallableMode(TestClass::NotCallable); QVERIFY(!cls.supportsExtension(QScriptClass::Callable)); QVERIFY(!cls.supportsExtension(QScriptClass::HasInstance)); } // Callable { TestClass cls(&eng); cls.setCallableMode(TestClass::CallableReturnsSum); QVERIFY(cls.supportsExtension(QScriptClass::Callable)); QScriptValue obj = eng.newObject(&cls); obj.setProperty("one", QScriptValue(&eng, 1)); obj.setProperty("two", QScriptValue(&eng, 2)); obj.setProperty("three", QScriptValue(&eng, 3)); { QScriptValueList args; args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5); QScriptValue ret = obj.call(obj, args); QCOMPARE(ret.toNumber(), qsreal(15)); } cls.setCallableMode(TestClass::CallableReturnsArgument); { QScriptValue ret = obj.call(obj, QScriptValueList() << 123); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 123); } { QScriptValue ret = obj.call(obj, QScriptValueList() << true); QVERIFY(ret.isBoolean()); QCOMPARE(ret.toBoolean(), true); } { QScriptValue ret = obj.call(obj, QScriptValueList() << QString::fromLatin1("ciao")); QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("ciao")); } { QScriptValue objobj = eng.newObject(); QScriptValue ret = obj.call(obj, QScriptValueList() << objobj); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(objobj)); } { QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue()); QVERIFY(ret.isUndefined()); } cls.setCallableMode(TestClass::CallableReturnsInvalidVariant); { QScriptValue ret = obj.call(obj); QVERIFY(ret.isUndefined()); } } // HasInstance { TestClass cls(&eng); cls.setHasInstance(true); QVERIFY(cls.supportsExtension(QScriptClass::HasInstance)); QScriptValue obj = eng.newObject(&cls); obj.setProperty("foo", QScriptValue(&eng, 123)); QScriptValue plain = eng.newObject(); QVERIFY(!plain.instanceOf(obj)); eng.globalObject().setProperty("HasInstanceTester", obj); eng.globalObject().setProperty("hasInstanceValue", plain); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QVERIFY(ret.isBoolean()); QVERIFY(!ret.toBoolean()); } plain.setProperty("foo", QScriptValue(&eng, 456)); QVERIFY(!plain.instanceOf(obj)); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QVERIFY(ret.isBoolean()); QVERIFY(!ret.toBoolean()); } plain.setProperty("foo", obj.property("foo")); QVERIFY(plain.instanceOf(obj)); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QVERIFY(ret.isBoolean()); QVERIFY(ret.toBoolean()); } } }
void tst_QScriptClass::extension() { QScriptEngine eng; { TestClass cls(&eng); cls.setCallableMode(TestClass::NotCallable); QVERIFY(!cls.supportsExtension(QScriptClass::Callable)); QVERIFY(!cls.supportsExtension(QScriptClass::HasInstance)); QScriptValue obj = eng.newObject(&cls); QVERIFY(!obj.call().isValid()); QCOMPARE((int)cls.lastExtensionType(), -1); QVERIFY(!obj.instanceOf(obj)); QCOMPARE((int)cls.lastExtensionType(), -1); } // Callable { TestClass cls(&eng); cls.setCallableMode(TestClass::CallableReturnsSum); QVERIFY(cls.supportsExtension(QScriptClass::Callable)); QScriptValue obj = eng.newObject(&cls); eng.globalObject().setProperty("obj", obj); obj.setProperty("one", QScriptValue(&eng, 1)); obj.setProperty("two", QScriptValue(&eng, 2)); obj.setProperty("three", QScriptValue(&eng, 3)); // From C++ cls.clearReceivedArgs(); { QScriptValueList args; args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5); QScriptValue ret = obj.call(obj, args); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isNumber()); QCOMPARE(ret.toNumber(), qsreal(15)); } // From JS cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("obj(4, 5)"); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isNumber()); QCOMPARE(ret.toNumber(), qsreal(15)); } cls.setCallableMode(TestClass::CallableReturnsArgument); // From C++ cls.clearReceivedArgs(); { QScriptValue ret = obj.call(obj, QScriptValueList() << 123); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 123); } cls.clearReceivedArgs(); { QScriptValue ret = obj.call(obj, QScriptValueList() << true); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isBoolean()); QCOMPARE(ret.toBoolean(), true); } { QScriptValue ret = obj.call(obj, QScriptValueList() << QString::fromLatin1("ciao")); QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("ciao")); } { QScriptValue objobj = eng.newObject(); QScriptValue ret = obj.call(obj, QScriptValueList() << objobj); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(objobj)); } { QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue()); QVERIFY(ret.isUndefined()); } // From JS cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("obj(123)"); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 123); } cls.setCallableMode(TestClass::CallableReturnsInvalidVariant); { QScriptValue ret = obj.call(obj); QVERIFY(ret.isUndefined()); } cls.setCallableMode(TestClass::CallableReturnsThisObject); // From C++ { QScriptValue ret = obj.call(obj); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(obj)); } // From JS { QScriptValue ret = eng.evaluate("obj()"); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(eng.globalObject())); } cls.setCallableMode(TestClass::CallableReturnsCallee); // From C++ { QScriptValue ret = obj.call(); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(obj)); } // From JS { QScriptValue ret = eng.evaluate("obj()"); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(obj)); } cls.setCallableMode(TestClass::CallableReturnsArgumentsObject); // From C++ { QScriptValue ret = obj.call(obj, QScriptValueList() << 123); QVERIFY(ret.isObject()); QVERIFY(ret.property("length").isNumber()); QCOMPARE(ret.property("length").toInt32(), 1); QVERIFY(ret.property(0).isNumber()); QCOMPARE(ret.property(0).toInt32(), 123); } // From JS { QScriptValue ret = eng.evaluate("obj(123)"); QVERIFY(ret.isObject()); QVERIFY(ret.property("length").isNumber()); QCOMPARE(ret.property("length").toInt32(), 1); QVERIFY(ret.property(0).isNumber()); QCOMPARE(ret.property(0).toInt32(), 123); } // construct() // From C++ cls.clearReceivedArgs(); cls.setCallableMode(TestClass::CallableReturnsGlobalObject); { QScriptValue ret = obj.construct(); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(eng.globalObject())); } // From JS cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("new obj()"); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isObject()); QVERIFY(ret.strictlyEquals(eng.globalObject())); } // From C++ cls.clearReceivedArgs(); cls.setCallableMode(TestClass::CallableInitializesThisObject); { QScriptValue ret = obj.construct(); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isQObject()); QCOMPARE(ret.toQObject(), (QObject*)&eng); } // From JS cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("new obj()"); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isQObject()); QCOMPARE(ret.toQObject(), (QObject*)&eng); } } // HasInstance { TestClass cls(&eng); cls.setHasInstance(true); QVERIFY(cls.supportsExtension(QScriptClass::HasInstance)); QScriptValue obj = eng.newObject(&cls); obj.setProperty("foo", QScriptValue(&eng, 123)); QScriptValue plain = eng.newObject(); QVERIFY(!plain.instanceOf(obj)); eng.globalObject().setProperty("HasInstanceTester", obj); eng.globalObject().setProperty("hasInstanceValue", plain); cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QCOMPARE(cls.lastExtensionType(), QScriptClass::HasInstance); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptValueList>()); QScriptValueList lst = qvariant_cast<QScriptValueList>(cls.lastExtensionArgument()); QCOMPARE(lst.size(), 2); QVERIFY(lst.at(0).strictlyEquals(obj)); QVERIFY(lst.at(1).strictlyEquals(plain)); QVERIFY(ret.isBoolean()); QVERIFY(!ret.toBoolean()); } plain.setProperty("foo", QScriptValue(&eng, 456)); QVERIFY(!plain.instanceOf(obj)); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QVERIFY(ret.isBoolean()); QVERIFY(!ret.toBoolean()); } plain.setProperty("foo", obj.property("foo")); QVERIFY(plain.instanceOf(obj)); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); QVERIFY(ret.isBoolean()); QVERIFY(ret.toBoolean()); } } }