I'm trying to use QScriptEngineAgent to gather detailed performance profiling for all script functions (not just API functions), but so far it doesn't work: i absolutely fail to obtain function name on functionEntry/functionExit events. It feels as if this functionality is either completely disabled on some level (some compile option?) or broken, or i'm doing something completely wrong: all ways of obtaining callee as QScriptValue result in a dead value (with NULL internal pointer) most of the time, QScriptContextInfo contains no info, and even line numbers are -1.

Does anybody have any idea? Here's what i'm trying to do (patch for master):

Doing a quick look at the code, and nothing jumps out as being incorrect, however, as you posted, it don't work.Looking up QString QScriptContextInfo::functionName() constReturns the name of the called function, or an empty string if the name is not available.

They don't say why it wouldn't be available.

Then trying QStringList QScriptContext::backtrace() const Returns a human-readable backtrace of this QScriptContext.

Each line is of the form <function-name>(<arguments>)@<file-name>:<line-number>.

That is, queue() and setTimer() already do profiling. This new function is different and necessary just because it calls the callee instantly, allowing the script to obtain the return value, and also to be sure no game objects get outdated, and also provide arbitrary number of arguments.

Note that callFunction()'s boolean return value was never checked anyway.

This approach makes it necessary to wrap every call of the function, rather than just its definition. It's possible to make a wrapper for the definition, but then if you queue the wrapper, it'd count performance twice (for different names, but still double overhead and poorly readable garbage in the stats).

An alternative is to implement profileStart("name") and profileEnd() calls, the first one would push name and ticks value into a stack, the second one would pop name and ticks and accumulate statistics. Then you'd have to put this inside the callee, on entry and every return (which may be many). Forgetting one of the returns, or throwing an exception, would break things quite a bit.

Would have still been easier with QScriptEngineAgent if only it worked.

No, it is a very different design, and does not have half of what we need, unfortunately. But they will keep supporting QtScript for all of Qt5, and hopefully by Qt6 something superior will replace both.

If you are currently porting over WZscript to JS, that is fine, and this has no impact on your work.

I have moved the other posts to another area for further discussion, since some people have misconstrued what I was saying, and started to come to conclusions that were not correct for what is going on currently.That was not my intention.

Once again, if you are currently porting over WZscript to JS, that is fine, and the talk that was being discussed has no impact on your work.

tl;dr: i successfully defined API functions for an engine, called them from scripts, tested string and integer and arbitrary-js-value arguments, called JS function from C++, obtained script return values, and handled an exception.

Creating API functions is pleasantly easy: instead of an arbitrary array of QScriptValue arguments, we receive our arguments already converted into C++ ints or strings. On the other hand, we'd have to deal with their fancy Q_OBJECT (etc.) preprocessors.

No idea about performance so far. I guess we cannot know until we try.

It seems there's no good way to implement SCRIPT_ASSERT - neither to interrupt current native function (as return type may vary; this is solvable, of course, but ugly, but not much more ugly than before), nor to throw a script exception from inside native function (might be missing something; also, if we give up on this, we let scripts crash the game and/or themselves on error).

Also, QJSEngine doesn't support variadic arguments; namely, there are at most 10 arguments to any Q_INVOKABLE method. This means we cannot support templates with unlimited number of turrets (there aren't many anyway), and also we have problems with functions like debug() and dump() (have to drop remaining arguments).