Script CallStack information in a method callback

Nov 20, 2013 at 1:26 PM
Hi guys,

I was wondering what would be the fastest way to dump a script callstack information from within a method callback for information purposes.

To give an example, lets say we'd wanna run something bigger and not enable debugging /JIT but rather have some information with script call stack attached.

We'd create a class like:
    public class Log
    {
        public void Info(string text)
        {
            Console.WriteLine(text);
            Console.WriteLine(GetScriptCallStack());
        }
    }
Then add _jsEngine.AddHostObject("Log", new Log());

I'd be interested in how to implement the GetScriptCallStack for JScript specifically or more generally considering the jsEngine can be accessed from that method.

Any ideas? I'm thinking either calee or somehow accessing the IDebug* implementation of the WindowsScript class?

Thank you

Andi
Coordinator
Nov 20, 2013 at 9:33 PM
Hi Andi! Thanks for your question.

If you're using JScript and you don't want to enable debugging, then callee/caller is your only option as far as we can tell. Here's a basic sample (with thanks to StackOverflow):
public class Log
{
    private readonly dynamic _getStack;
    public Log(ScriptEngine engine) {
        _getStack = engine.Evaluate(@"(function () {
            var stack = '';
            var func = arguments.callee.caller;
            while (func) {
                var scan = /\W*function\s+([\w\$]+)\(/.exec(func.toString());
                var name = scan ? scan[1] : '[anonymous]';
                stack += '  at ' + name + '\n';
                func = func.caller;
            }
            return stack;
        }).valueOf()");
    }
    public void Info(string text) {
        Console.WriteLine(text);
        Console.WriteLine(_getStack());
    }
}
Good luck!
Nov 21, 2013 at 1:21 PM
Thanks guys, this looks good, the downside being it doesn't identify the file names in which the methods are located in in case of multiple files used. If i were to use the
WindowsScriptEngineFlags.EnableDebugging flag would this allow the usage of the debug interfaces somehow? and if so any idea how? (i'm thinking members can be called out trough reflection easy enough, but i can't figure out what exactly gives out the current information)
Coordinator
Nov 21, 2013 at 7:06 PM
Enabling debugging makes richer call stack information available, but ClearScript doesn't have a convenient API for retrieving it. You could deliberately throw a script error, catch the exception, and parse the call stack out of IScriptEngineException.ErrorDetails, but we don't recommend it. We're tracking this here.