First, make sure you have read How Falcon Creates SWFs and How FalconJX Creates HTML/JS/CSS.

You don't really have to know much about compilers to fix bugs and add features to the compiler.  The compiler experts defined the architecture and did an initial implementation, and writing code at this point is mostly about following patterns.  This page contains information that might help you find the place to make your changes.

Changing SWF Output

Changing SWF output often requires debugging through the BURM, and is really painful.  Hopefully you will not need to change the SWF output ever.  Or how the BURM decides what the output ABC should be.  But the BURM does eventually decide that some set of ABC should be output for a particular identifier, or to initialize a constant, and calls one of dozens of methods in ABCGeneratingReducer where code that is much more understandable then adds some ABC to an InstructionList.  Finding out which method is going to be called is the painful part.  Again, hopefully you'll never need to go there.

Adding a New Compiler Option

The first thing to consider is whether to add the option to the Falcon compiler as well as FalconJX or not.  In general, options that only control JS/CSS/HTML output don't need to affect Falcon, but on the other hand, if Falcon also knows about the option, then folks can specify it in their IDE or -config.xml files and don't need to remember to add those options when doing the cross-compile.  And, the SWF compile that IDEs usually do automatically will pick up errors in the user's code sooner than if they wait until they try the cross-compile.  To modify the options for Falcon, change the Configuration class.  To change options only for FalconJX, change the JSGoogConfiguration class.

Changing JS Output

The first thing to consider is if you are changing the allowed syntax accepted by the compiler.  If so, then see the section about Changing AS or MXML.  Otherwise, you are probably debugging a problem in the JS output.  The key is to find the right piece of code.  If you understand the kinds of nodes in the AST, you can guess which sub-Emitter is going to get called, although there are exceptions where a BinaryOperatorNode finds a child MemberAccessExpressionNode and instead of calling the MemberAccessEmitter, it just generates some output JS itself, and similar exceptions to the rule.   If in doubt, a good place to start is the PackageHeaderEmitter, then step through the code as it goes back up to the Walker and back into other Emitters.

Keep in mind that semantic checks and some other errors are only detected during the SWF output, so if your scenario doesn't include SWF output, you may be running into an AST scenario that should be an error.

Also, you'll see a lot of calls to resolve() methods.  These can be slow, but are often necessary in order to understand what an identifier is referencing.  That's one of the trade-offs of not having to type 'this.' when accessing members.  However, it may be that more context should be pushed down as the tree is walked so fewer resolve calls are needed.  

Changing AS or MXML

It should be possible to add new language features to ActionScript and/or MXML.  Doing so requires changing the grammars the parsers use to create the AST.  Then, once the AST is set, you have to detect the AST pattern that represents the new language feature and generate the right JavaScript code.


  • No labels