Hi, all!

i just came up with a useful hack for v8 and thought i'd share it...

To rewind for just a moment: some months ago i posted code for an
InvocationCallback which returns an array of objects which hold info about
the v8 stack frames, and that code is a prerequisite for this hack. That
code is here:

http://code.google.com/p/v8-juice/source/browse/branches/edge/src/include/v8/juice/juice.h#157
http://code.google.com/p/v8-juice/source/browse/branches/edge/src/lib/juice/juice.cc#255

(those line numbers are subject to change at any time, of course)

That can be dropped into any v8 client, but requires that the user replace
the CastFromJS() calls with their preferred JS-to-T conversion API.

An interesting trick we can do with the stack frame info is get the current
line number of a JS script from within that script...

Here's the code (it assumes the above function is bound to JS as
getStackrace()):

function getCallLocation(){
    var li = getStacktrace(2); // get only the last 2 frames
    return li ? li[1] : {}; // return the previous frame
}
print("This is line "+getCallLocation().line);
print("This is line "+getCallLocation().line);

The output might be (depends on your script, of course):

This is line 6
This is line 7

This can be used to implement assert()-like functions which can report where
the assert() was called (as opposed to throwing an exception which traces
back to the assert() function itself). As an example:

// if (got != expect) then this function throws and reports the line number
// where the asserteq() call was made.
function asserteq(got,expect,msg)
{
    msg = msg || (got+' == '+expect);
    var st = getStacktrace(2);
    if( got != expect ) {
        msg = 'Assertion failed at line '+st[1].line+': '+msg+
            '\nStacktrace: '+JSON.stringify(st,0,4);
        throw new Error(msg );
    }
    else
    {
        print("Assertion OK: "+msg);
    }
}

asserteq( 1, 1 );
asserteq( 3, 4, "intentional assertion" );



That produces (with the inclusion of a little bit of error handling code
(not shown)):


Assertion OK: 1 == 1
Error: Assertion failed at line 182: Intentional error.
Stacktrace: [
    {
        "column": 14,
        "functionName": "asserteq",
        "line": 46,
        "scriptName": "./test.js",
        "isConstructor": false,
        "isEval": false
    },
    {
        "column": 5,
        "functionName": "",
        "line": 182,
        "scriptName": "./test.js",
        "isConstructor": false,
        "isEval": false
    },
...
]


Happy Hacking!

-- 
----- stephan beal
http://wanderinghorse.net/home/stephan/

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to