mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
ea1a18ec169f459bc5b389c35af197db268cbe31
The approach is very similar to what BuildHIR does to resolve break and continue targets during IR construction: * We annotate goto targets as either a break or a continue (during HIR construction). This is necessary to reconstruct the right kind in codegen. * Codegen continues to work by traversing the IR as if it were a tree, relying on the `fallthrough` branches of if/switch to be able to visit the consequent/alternate recursively and then emit the fallthrough branch. * We track a Set of blocks that are scheduled to be emitted by some parent in the tree. Nested ifs may all have the same fallthrough branch, which we only want to emit once. This set helps us to know that a parent is already going to emit some block, such that children can skip it. * We also keep a stack of break targets that are in scope, and use this to convert gotos appropriately, as either a break, continue, or nothing at all (for example a switch case that falls through has no explicit syntax to model this fall-through, the only option is to emit nothing for the goto). * Then, if/switch have to carefully check whether each branch should be emitted or not. For example, if the alternate is already scheduled to be emitted (by a parent), then we emit a block with a break statement instead. * Switch in particular is tricky, because we need to know that subsequent cases are scheduled, but only for preceding blocks. So we visit the cases in reverse order (not surprisingly, we do the same thing during IR construction for similar reasons!). The bookkeeping is a bit finicky but this works reliably. There are some cases where we could try to emit an unlabeled break instead of a labeled break, or avoid emitting a label at all (if nothing will explicitly break to that label), but overall the generated code is readable enough that i'm inclined to ship and iterate. I'm open to feedback though, as always!
Description
Languages
JavaScript
67.1%
TypeScript
29.4%
HTML
1.5%
CSS
1.1%
C++
0.6%
Other
0.2%