Error Stack Column number

Sundararajan Athijegannathan sundararajan.athijegannathan at oracle.com
Fri Dec 2 11:25:58 UTC 2016


Note that nashorn always compiles to bytecode - no parallel side data
structure for JS stacks or "interpreter stack" here.

That said (if this can be done without hurting performance) we'd be
happy to accept contributions.

-Sundar


On 12/2/2016 4:34 PM, Art Fiedler wrote:
> Without knowing all the internals of nashorn. I don't know if an internal
> calling tree exists or how complicated it would be to build, but it seems
> the runtime could track function calls and maintain its own stack.
>
> CallNode before code is generated has the token/linenumber where it came
> from, store a unique id of the callnode, with filename, line, column, in
> the runtime. Then as a call node is executed push to the call stack the id
> of the call node, and pop when call is complete... when the stack is
> requested capture the current threads callnode id list (maybe use a thread
> local?) match it up with the stored callnode id info map... merge/overwrite
> stackelements in the stack trace gathered from Throwable.
>
> Well, that's what just rolled off my head of how it could possibly be done.
>
> -Arthur Fiedler
>
> On Fri, Dec 2, 2016 at 4:09 AM, Sundararajan Athijegannathan <
> sundararajan.athijegannathan at oracle.com> wrote:
>
>> StackTraceElement being final is not the only issue here. How do to pass
>> around & populate column numbers for the script frames?  That is the
>> main issue here..
>>
>> -Sundar
>>
>> On 12/2/2016 3:00 PM, Art Fiedler wrote:
>>> Yeah I almost mentioned that StackTraceElement doesn't provide a column
>>> number to populate but removed that comment, thinking "well,
>>> StackTraceElement could just be extended for NashornStackTraceElement",
>> but
>>> now looking at it I notice it's final. ugh. But it doesn't technically
>> mean
>>> an array of StackTraceElement's cant be converted to
>>> NashornStackTraceElement's after getting the stack from the jvm, then
>>> matching up script frames and populating additional information.
>>>
>>> -Arthur Fiedler
>>>
>>> On Fri, Dec 2, 2016 at 2:59 AM, Sundararajan Athijegannathan <
>>> sundararajan.athijegannathan at oracle.com> wrote:
>>>
>>>> Error has columnNumber property - but as you've noted it is not always
>>>> available :(  If the error is thrown from script code anywhere via
>>>> ECMAScript throw statement, we do populate column number - because
>>>> nashorn could compile the code appropriately to put column number!
>>>>
>>>> But, there are places in nashorn runtime code where ECMAScript errors
>>>> are thrown. For example, RangeError thrown from deep inside nashorn
>>>> runtime Java code! From those places, we can only recover java stack
>>>> trace & populate properties of ECMA error object.  As java
>>>> StackTraceElement objects do not have column number, we can't populate
>>>> column number.
>>>>
>>>> -Sundar
>>>>
>>>> On 12/2/2016 2:06 PM, Art Fiedler wrote:
>>>>> Your right it's still not standard even in the EMCAScript 2016, it just
>>>>> seems to
>>>>> be the commonality. When thinking java yes line only makes sense as
>>>>> typically
>>>>> one who writes java does not minify the code. When thinking javascript
>>>>> however
>>>>> minified code is quite normal and myfile:1 might mean 5000 other lines
>> as
>>>>> well.
>>>>>
>>>>> I looked into the source some to see if it actually is feasible to
>> build
>>>> my
>>>>> own
>>>>> stacktrace with file:line:column, however in the current state it seems
>>>>> impossible! Nashorn actually uses java.lang.Throwable.getStackTrace()
>> to
>>>>> get the
>>>>> stack and that ends up being native. The only place you can get the
>>>>> columnNumber
>>>>> is for the specific location the error was thrown. Keyword "thrown".
>>>>>
>>>>> If you noticed my previous sample new Error().columnNumber === -1 since
>>>>> columnNumber is not populated... however if you throw & catch then...
>>>>>     try { throw new Error(); }
>>>>>     catch(e) { /* e.columnNumber === 6 */ }
>>>>>
>>>>> In my case with console.count(), the need for columnNumber is not the
>>>>> location
>>>>> of new Error() either, since the console.count() function would need
>> the
>>>>> callers file:line:col as that is where console.count() is called from.
>>>>>
>>>>> In the end I still think if the stack element is from a script it
>> should
>>>>> include
>>>>> the column number like node.js, ff, edge all seem to be doing. Since a
>>>> line
>>>>> only
>>>>> is useless when the script is minified. However considering that
>> nashorn
>>>> is
>>>>> not
>>>>> providing the stackTrace directly, I could see why the team may not
>> want
>>>> to
>>>>> include the columnNumber. If you do however know of another way to get
>>>> the
>>>>> callers file:line:col please let me know. My second thought was to
>> check
>>>>> arguments.callee.caller for that info but no dice.
>>>>>
>>>>> -Arthur Fiedler
>>>>>
>>>>> We do not aim to provide complete compatibility with other JS
>>>>>> implementations on the non-standard properties such as "stack". stack
>>>>>> tries to mimic whatever is done for Java code (no column number for
>>>>>> eg.). But, as you've noted there are enough information on Error
>> objects
>>>>>> via other properties like lineNumber, columnNumber, fileName. It
>> should
>>>>>> be possible to write a simple utility function to format stack string
>> as
>>>>>> desired for specific applications.
>>>>>>
>>>>>> Thanks,
>>>>>> -Sundar
>>>>>>
>>



More information about the nashorn-dev mailing list