Virtual Machine Code Generation (virtual.ml)

After closure conversion, we will generate SPARC assembly. However, since it is too hard to generate the real SPARC assembly with no preparation, we first generate some virtual machine code similar to SPARC assembly. Its main "virtual" aspects are:

This virtual assembly is defined in sparcAsm.ml. SparcAsm.exp corresponds to each instruction of SPARC (except if). Instruction sequence SparcAsm.t is either Ans, which returns a value at the end of a function, or variable definition Let. The other instructions Forget, Save, and Restore will be explained later.

Virtual.f, Virtual.h, and Virtual.g are the three functions that translate closure-converted programs to virtual machine code. Virtual.f translates the whole program (the list of top-level functions and the expression of main routine), Virtual.h translates each top-level function, and Virtual.g translates an expression. The point of these translations is to make explicit the memory accesses for creating, reading from, and writing to closures, tuples, and arrays. Data structures such as closures, tuples, and arrays are allocated in a memory region called the heap, whose address is remembered in special register SparcAsm.reg_hp.

For example, in the case of array read Closure.Get, the offset is shifted according to the size of the element to be loaded. In tuple creation Closure.Tuple, each element is stored with floating-point numbers aligned (8-byte), and the starting address is used as the tuple's value. Closure creation Closure.MakeCls stores the address (label) of the function's body with the values of its free variables, also taking care of alignment, and uses the starting address as the closure's value. Accordingly, at the beginning of each top-level function, we load the values of free variables from the closure. In this process, we assume that every function closure-based application (AppCls) sets the closure's address to register SparcAsm.reg_cl.

By the way, since SPARC assembly does not support floating-point immediates, we need to create a constant table on memory. For this purpose, Virtual.g records floating-point constants to global variable Virtual.data, which are incorporated by Virtual.f into the whole program SparcAsm.Prog.

Next