Replies: 7 comments 7 replies
-
Question: How do we get sourcemaps to work? Do we need to a |
Beta Was this translation helpful? Give feedback.
-
Questions: Do we need another allocator for the HIR? |
Beta Was this translation helpful? Give feedback.
-
Question: At what point do we start resolving imports and exports and start building module graphs? Memory arena is getting in the way if we want to start sharing data. |
Beta Was this translation helpful? Give feedback.
-
I'm really excited about this discussion as it's a topic I'm very interested in although I don't have much experience with Rust. Wanted to add a couple of thoughts and opinions gained over the years on working on JS tooling over the years in hopes that it might be helpful somehow. Symbol tableI've been dabbling a lot with various bundling and minification techniques for JS with some homegrown js-based compilers. A limitation that I ran into with current tools is that they're mostly focused on file based optimization techniques. Babel for example operates on every file individually and has non concept of the program as a whole. But things like treeshaking act on the knowledge of the program as a whole to be able to drop unused functions. This matters for AST design, because in babel an {
"type": "Identifier",
"name": "fooBar",
// ...
} No picture two files with clashing variable names. We want to bundle them into one file like it's typically done for frontend code. // a.js
const a = "I'm file A";
console.log(a); // a2.js
const a = "I'm the other A file";
console.log(a); When merged together you have to rename one of the variables. // merged.js
const a = "I'm file A";
console.log(a);
const a_2 = "I'm the other A file";
console.log(a_2); But where does this renaming happen? Merging files is a very common operation of bundlers. This is where a symbol table makes this process a lot easier. Taking inspiration from {
"type": "Identifier",
"name": SOME_GLOBAL_UNIQUE_ID,
// ...
}
// Symbol table pseudo code (id -> actual name)
{
SOME_GLOBAL_UNIQUE_ID: "a"
} With this little change the process of bundling gets a lot easier as the files can be concatenated as is. Once merged, we only have to walk the scope tree and lookup names in the symbol table. If we come across a name that we've already used in the current scope, we can simply change it. We have to do that final pass anyway with a minifier because reusing the same identifier names compresses better. Basically instead of this:
we only need to do this with a symbol table:
We save one rename pass which can be quite a bit of work in large projects with 20k modules.
|
Beta Was this translation helpful? Give feedback.
-
I have concerns about how much we can abstract away from AST to HIR. Take the example in OP
ArrowFunctionExpression will not have
Consider the typical output where webpack uses extensively for hacking
This will make HIR object encode their |
Beta Was this translation helpful? Give feedback.
-
This means that you remove any type info? |
Beta Was this translation helpful? Give feedback.
-
I decided to remove the HIR from oxc. #917 HIR is a wonderful idea for compiling to lower languages, but after sitting on it for a few months I found that it only adds confusion and uncertainties to both myself and future contributors. It also adds too much burden to maintainers if we plan to support more downstream tools. |
Beta Was this translation helpful? Give feedback.
-
Background:
Our current AST is cumbersome to work with for compiler authors (me and future collaborators).
I want to an HIR that should enable easier implementations of type checker, linter, transpiler, and minifier. It should be:
ArrowFunctionExpression
andFunctionExpression
ParenthesizedExpression
IterationStatement
instead offor
,while
, anddo while
statementsBeta Was this translation helpful? Give feedback.
All reactions