-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scopes: Make Original Source's column
relative
#75
base: main
Are you sure you want to change the base?
Conversation
column
relativecolumn
relative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me! I'll let Simon and Holger weigh in as they've been leading the proposal and own the proof of concept implementations!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a great idea given how most authored code is formatted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the idea behind absolute columns was that the column would be "reset" for every line, just as it's done in the mappings
field, and then it will be absolute most of the time anyway (because original code rarely has more than one scope starting in the same line).
But while "resetting" the column for every line makes sense for locations in the generated code (because it will usually be minified), it doesn't make sense for locations in the original code, as demonstrated in the PR description.
So I agree with the change in this PR.
I tried using relative columns here and found that the encoded original scopes got larger rather than smaller. import {Logger} from './module.js';
function inner(x) {
Logger.log(x);
}
function outer(x) {
inner(x);
}
outer(42);
outer(null); has the following scopes (leaving out the global scope; note that I put the scope start at the
So the absolute columns to encode would be
|
This was my expectation, and that it fixes this issue makes it even better. It also matches what V8 does when using the Error.prepareStackTrace = function (_error, frames) {
for (const f of frames) {
console.log({
lineNumber: f.getLineNumber(),
columnNumber: f.getColumnNumber(),
enclosingLineNumber: f.getEnclosingLineNumber(),
enclosingColumnNumber: f.getEnclosingColumnNumber(),
fileName: f.getFileName(),
});
}
};
function foo() {
throw new Error("bar");
}
foo(); The {
lineNumber: 14,
columnNumber: 9,
enclosingLineNumber: 13,
enclosingColumnNumber: 1,
fileName: '/Users/jridgewell/tmp/callsite/index.js'
}
{
lineNumber: 16,
columnNumber: 1,
enclosingLineNumber: 1,
enclosingColumnNumber: 1,
fileName: '/Users/jridgewell/tmp/callsite/index.js'
}
… (Chrome uses 1-based line/columns) |
A little more to support this: |
I couldn't find any documentation for these methods, but it looks like they just return the beginning of the function declaration, I don't know if this is supposed to be the beginning of the function's scope.
It's not that simple, from MDN:
and
So in |
If you wanna check the locations that we send over CDP from V8, one easy way to do this in DevTools directly:
For Holgers example V8 indeed emits 2 scopes:
|
Why does the parameter scope end at the closing |
Because parameters are still visible inside the function body — the function body scope is nested inside the scope that also includes params. |
Is this good to merge? It looks like it got 👍🏻 but then there was a side question? |
Perhaps we should do #76 first and then check if this change would make the encoding more efficient on average. |
Take the following code (while large nesting isn't super common, it does happen):
This would have scopes:
The absolute columns that we need to encode would give us:
[0, 4, 8, 12, 16, 17, 13, 9, 5, 1]
. As VLQ, we haveA,I,Q,Y,gB,iB,a,S,K,C
. Notice thegB
andiB
2-byte VLQ encodings for16
and17
columns. Because VLQ can only use 5 bits of every byte, and the first byte also needs to encode the sign, we only have 4 bits of data to encode the column in one byte.There's an easy alternative that can use 1 byte for all of these: relative encodings, just like
line
. That would mean we just need to encode[0, 4, 4, 4, 4, 1, -4, -4, -4, -4]
, orA,I,I,I,I,C,J,J,J,J
.