Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get javascript caller source line number in SpiderMonkey JSNative callback?

I want to implement a C++ function working like console.log. I need to know javascript caller's source line position in C++. I search MDN JSAPI/JS Debugger API documents but no result.

A concept usage in javascript.

console.log("blahblahblah");

And expected logic in C++.

JSBool consoleLog(JSContext *cx, unsigned argc, jsval *vp) {
    // expect to get caller info including filename, lineno.

    // write "blahblahblah" and caller info in my log system.

    return JS_TRUE;
}

==============

UPDATE

I finally find a way to get filename and lineno. Error handling code is omitted.

#include "jsdbgapi.h"

JSBool consoleLog(JSContext *cx, unsigned argc, jsval *vp) {
    JSScript *script;
    unsigned int lineno;
    JS_DescribeScriptedCaller(cx, &script, &lineno);
    const char *filename = JS_GetScriptFilename(cx, script);

    // use filename and lineno to write log...

    return JS_TRUE;
}
like image 560
huandu Avatar asked Nov 13 '22 06:11

huandu


1 Answers

Generally you have to use the currently active function frame on the JS stack, accessible through cx -- that would tell you about the script and currently executing bytecode. Though I can't remember the exact API off the top of my head, there's some function that will produce lineno from that data (don't be avoid to forgo the docs and start reading jscntxt.h and friends, seeing as how the docs can be outdated -- they're not auto-generated).

There's also a caveat in that JSNatives conceptually execute in their caller's stack frame, so calling consoleLog from another JSNative it won't say something like <native code>. It'll only effectively do what you want when invoked from a JS-code caller.

like image 77
cdleary Avatar answered Nov 14 '22 22:11

cdleary