MerlinVR / UdonSharp

An experimental compiler for compiling C# to Udon assembly
MIT License
678 stars 89 forks source link

Compiler pipeline rewrite #106

Closed MerlinVR closed 3 years ago

MerlinVR commented 3 years ago

0.x primarily did a weak two pass compile, where the first pass collected all methods, properties, and fields on U# behaviour types so that the compiler could have awareness of what symbols it has access to. And the second pass was primarily an emit phase that also figured out what everything was and bound types in the same pass.

This was problematic since it made a number of optimizations difficult to do and it had a very flat understanding of types and dependencies. All it could represent decently was a collection of UdonSharpBehaviours that referenced each other directly.

1.0's pipeline instead splits out compilation into multiple larger phases with more defined purposes.

  1. Roslyn AST parse of all relevant script files
  2. Run a Roslyn compilation on all linked AST files along with Unity assemblies to build a semantic view of the whole compilation
  3. UdonSharp runs its bind phase which constructs a bound node representation of user code. This phase preforms basic optimizations like constant folding and collects all symbols that can potentially be referenced in Udon so that we can build a list of all code needed AOT, including uses of generic types, implementers of interface and virtual types, static methods and variables that are referenced, etc
  4. UdonSharp runs its emit phase, which collects all dependencies of a given Udon program and emits udon assembly instructions from the bound nodes for all dependencies
  5. UdonSharp does a link phase where all user methods, properties, and fields on UdonSharpBehaviours get their references hooked up for the internal SetProgramVariable/SendCustomEvent calls
  6. All UdonSharp programs get assembled from the assembly instructions
  7. Heaps get initialized, behaviours get linked when needed, etc