Runtime Environment and Symbol Table
Runtime Environment and Symbol Table
2. Backpatching
Backpatching is a compiler technique that postpones the assignment of jump targets in
intermediate code, allowing for more flexible code generation. Instead of immediately filling
in the target addresses for jumps (like in if statements or loops), backpatching uses placeholder
addresses. These placeholders are then updated or "backpatched" later with the actual target
addresses once they become known.
3. Run-Time Environment
A program as a source code is merely a collection of text (code, statements etc.) and to make it
alive, it requires actions to be performed on the target machine. A program needs memory
resources to execute instructions. A program contains names for procedures, identifiers etc.,
that require mapping with the actual memory location at runtime.
By runtime, we mean a program in execution. Runtime environment is a state of the target
machine, which may include software libraries, environment variables, etc., to provide services
to the processes running in the system.
Runtime support system is a package, mostly generated with the executable program itself and
facilitates the process communication between the process and the runtime environment. It
takes care of memory allocation and de-allocation while the program is being executed.
Three types runtime environment management:
i. Static storage allocation
o In static allocation, names are bound to storage locations.
o If memory is created at compile time then the memory will be created in static area and
only once.
o Static allocation supports the dynamic data structure that means memory is created only
at compile time and deallocated after program completion.
o The drawback with static storage allocation is that the size and position of data objects
should be known at compile time.
o Another drawback is restriction of the recursion procedure.
ii. Stack Storage Allocation
o In static storage allocation, storage is organized as a stack.
o An activation record is pushed into the stack when activation begins and it is popped
when the activation end.
o Activation record contains the locals so that they are bound to fresh storage in each
activation record. The value of locals is deleted when the activation ends.
o It works on the basis of last-in-first-out (LIFO) and this allocation supports the
recursion process.
iii. Heap Storage Allocation
o Heap allocation is the most flexible allocation scheme.
o Allocation and deallocation of memory can be done at any time and at any place
depending upon the user's requirement.
o Heap allocation is used to allocate memory to the variables dynamically and when the
variables are no more used then claim it back.
o Heap storage allocation supports the recursion process.
4. Symbol table
Symbol table is an important data structure created and maintained by compilers in order to
store information about the occurrence of various entities such as variable names, function
names, objects, classes, interfaces, etc. Symbol table is used by both the analysis and the
synthesis parts of a compiler.
Application of symbol table:
• To store the names of all entities in a structured form at one place.
• To verify if a variable has been declared.
• To implement type checking, by verifying assignments and expressions in the source
code are semantically correct.
• To determine the scope of a name (scope resolution).
A symbol table is simply a table which can be either linear or a hash table. It maintains an entry
for each name in the following format:
<symbol name, type, attribute>
For example, if a symbol table has to store information about the following variable
declaration:
static int interest;
then it should store the entry such as:
<interest, int, static>
The attribute clause contains the entries related to the name.
Implementation process of symbol table:
• Linear (sorted or unsorted) list
• Binary Search Tree
• Hash table
Features of symbol table:
1. Lexical Analysis: New table entries are created in the table, For example, entries about
tokens.
2. Syntax Analysis: Adds the information about attribute type,, dimension, scope line of
reference, use, etc in the table.
3. Semantic Analysis: Checks for semantics in the table, i.e., verifies that expressions and
assignments are semantically accurate (type checking) and updates the table
appropriately.
4. Intermediate Code generation: The symbol table is used to determine how much and
what type of run-time is allocated, as well as to add temporary variable data.
5. Code Optimization: Uses information from the symbol table for machine-dependent
optimization.
6. Target Code generation: Uses the address information of the identifier in the table to
generate code.
Operations Functions
insert To insert a name in a symbol table and return a pointer to its entry
void pro_one()
{
int one_1;
int one_2;
{ \
int one_3; |_ inner scope 1
int one_4; |
} /
int one_5;
{ \
int one_6; |_ inner scope 2
int one_7; |
} /
}
void pro_two()
{
int two_1;
int two_2;
{ \
int two_3; |_ inner scope 3
int two_4; |
} /
int two_5;
}
...