I am reading the famous book Crafting Interpreters
by Bob Nystrom
and I am on chapter-24 Calls and Functions
. He builds a single-pass compiler in which functions need to be declared before usage so having function objects holding the same status as local variables makes sense. My language has multiple-pass compiler where functions can be used before it's declared and so I can't have functions as local variables living on the stack.
I want to know how production-grade compilers store these function objects and how they generate instructions at compile time for function call which are not yet declared.
One of the simplest solution I can think of is to define a separate dedicated array for function objects which I can simulate during compile-time resolution phase and emit bytecode instruction to call the function like CALL index arity
where index
would be index to the array of function objects. The array of function objects would get filled during bytecode generation of function declaration nodes.
One problem with this kind of approach is that I totally lost the scope information as all function objects are in single straight array even those which would have not been alive once we are past it's scope. This will pose problems when I will wire up the garbage-collector.