I am trying to create a basic performance profiler for QtScript using the QScriptEngineAgent
in order to capture function entries and exits. I have successfully set up the callback for
QScriptEngineAgent::functionEntry()
. My question is, can I retrieve the name of the function being called as a string within this callback?
Although I understand that not all script functions necessarily have names, even in simple cases it doesn't seem to be working. Despite attempts with QScriptContextInfo
, it does not provide the function name. Trying to access arguments.callee.name
also failed.
Below is an outline of my implementation attempts, which I am testing on qt-5.3.2/linux.
tmp.pro
:
TEMPLATE = app
TARGET = tmp
INCLUDEPATH += .
QT += core script
SOURCES += main.cpp
main.cpp
:
#include <QCoreApplication>
#include <QScriptEngine>
#include <QScriptEngineAgent>
#include <QScriptContextInfo>
#include <QDebug>
class MyAgent: public QScriptEngineAgent {
private:
void functionEntry(qint64 scriptId) {
qDebug() << "functionEntry" << scriptId;
QScriptContext *context = engine()->currentContext();
// Attempting to retrieve the function name from context info
QScriptContextInfo contextInfo(context);
qDebug() << contextInfo.functionName();
// Trying to access the function name through arguments.callee.name
QScriptValue callee = context->callee();
qDebug() << callee.property("name").toString();
// Checking if function.toString() provides any useful information
qDebug() << callee.toString();
// Printing out details of the current context
qDebug() << context->toString();
}
public:
MyAgent(QScriptEngine *eng) : QScriptEngineAgent(eng) {
qDebug() << "engine" << eng;
}
};
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
QScriptEngine eng;
MyAgent agent(&eng);
eng.setAgent(&agent);
qDebug() << "agent " << eng.agent();
eng.evaluate("function foo() { return 6 * 7; }"
"function bar() { return foo(); }");
QScriptValue bar = eng.globalObject().property("bar");
// Confirming that callee is printed correctly here
qDebug() << "call " << bar.property("name").toString() << bar.toString();
QScriptValue ret = bar.call();
qDebug() << "answer" << ret.toNumber();
return 0;
}
This is a sample of the output, which does not meet my expectations as I would like to see "foo" and "bar" instead of empty strings:
engine QScriptEngine(0x7fffc55c4560)
agent 0x7fffc55c4570
functionEntry 140300485581200
""
""
""
"<global>() at -1"
functionEntry -1
""
""
""
"<global>() at -1"
call "bar" "function bar() { return foo(); }"
functionEntry 140300485581200
""
""
""
"<global>() at -1"
functionEntry 140300485581200
""
""
""
"<global>() at -1"
answer 42