dotgnu-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[DotGNU]my hacking notes


From: Gomi Kapoor
Subject: [DotGNU]my hacking notes
Date: Thu, 1 Apr 2004 18:59:19 +0100 (BST)

Hi all,
While I am trying to understand the code of Portable
.NET, I am attempting to write down a few things. I
feel these notes would be helpful to other beginners
like me. (the first one of them, please find attached
with this mail.  It contains a small description of
how the switch-case loop is split across different
files).

If you feel it is good, is there a place where I can
host such small write
ups? (or make it part of pnet/doc) 

Regards,
Gomi Kapoor

________________________________________________________________________
Yahoo! India Insurance Special: Be informed on the best policies, services, 
tools and more. 
Go to: http://in.insurance.yahoo.com/licspecial/index.html
Splitting a huge switch-case loop across mutiple files:
========= = ==== =========== ==== ====== ======= =====
The Portable .NET's CIL (Common Intermediate Language) Verifier, 
CVM interpreter and the Unroller are implemented in the 
pnet/engine directory.

The verifier is implemented in verify_* files, the CVM interpreter 
in cvm_* files and the unroller in unroll_* files.

Interestingly all of them, involve implementing a huge switch-case
loop and hence follow a similar coding style, which we discuss here.

Instead of writing the whole huge switch-case loop in just a single 
file, it is split across many files as follows.

Let's say we have a  file(loop.c), which has the actual switch-loop 
implemented and other files like loop_part1.c, loop_part2.c, where 
the relavent cases are implemented in those files. The whole loop is
built by including those part files in the main file as follows:

In file loop_part1.c, we have
case LOOP_PART1_INST1:
        //...
        break;
case LOOP_PART1_INST2:
        //...
        break;
case LOOP_PART1_INST3:
        //...
        break;

In the loop_part2.c, we have
case LOOP_PART2_INST1:
        //...
        break;
case LOOP_PART2_INST2:
        //...
        break;
case LOOP_PART2_INST3:
        //...
        break;

and finally in the file loop.c, we have
void loop()
{
        switch(...)
        {
                case LOOP_INST1:
                        //...
                        break;
                case LOOP_INST2:
                        //...
                        break;
                #include "loop_part1.c"
                #include "loop_part2.c"
        }
}

But one potential problem with the above implementation is, it is not
possible to declare any local variables in the ``part'' files. All of
them have to be in the main file and it becomes a bit difficult to 
manage in such a situation. Similar is the case if we need to have
helper functions in the part files.

These issues are addressed by using macros as shown below. 

In the part files, write the code can be written as follows:
loop_part1.c:
#if LOOP_GLOBALS
        //here goes the global variables and the helper functions
#endif

#if LOOP_LOCALS
        // Here goes the local varibales of the loop function
        // needed by the case
#endif

#if LOOP_MAIN
        //Here goes the actual code for the cases
#endif

And in the main file, loop.c we can have:

#define LOOP_GLOBALS
#include "loop_part1.c"
#include "loop_part2.c"
#undef LOOP_GLOBALS

void loop(...)
{
#define LOOP_LOCALS
        #include "loop_part1.c"
        #include "loop_part2.c"
#undef LOOP_LOCALS

        switch(...)
        {
                case LOOP_INST1:
                                //.....
                                break;
                        .....
                #define LOOP_MAIN
                        #include "loop_part1.c"
                        #include "loop_part2.c"
                #undef LOOP_MAIN
        }
}
In the case of verifier:
 Main file      :       verify.c (and the function is _ILVerify)
 Part files     :       verify_ann.c
                                verify_arith.c
                                verify_branch.c
                                verify_call.c
                                verify_const.c
                                verify_conv.c
                                verify_except.c
                                verify_obj.c
                                verify_ptr.c
                                verify_stack.c
                                verify_var.c
 Global Macro: IL_VERIFY_GLOBALS
 Local Macro : IL_VERIFY_LOCALS
 Cases Macro : IL_VERIFY_CODE


In the case of CVM interpreter:
 Main file      :       cvm.c (and the function is _ILCVMInterpreter)
 Part files     :       cvm_var.c
                                cvm_ptr.c
                                cvm_stack.c
                                cvm_arith.c
                                cvm_conv.c
                                cvm_const.c
                                cvm_branch.c
                                cvm_call.c
                                cvm_except.c
                                cvm_compare.c
                                cvm_inline.c
 Global Macro: IL_CVM_GLOBALS
 Local Macro : IL_CVM_LOCALS
 Cases Macro : IL_CVM_MAIN, IL_CVM_WIDE, IL_CVM_PREFIX

In the case of unroller:
 Main file      :       unroll.c (and the function is _ILCVMUnrollMethod)
 Part files     :       unroll_arith.c
                                unroll_branch.c
                                unroll_const.c
                                unroll_conv.c
                                unroll_ptr.c
                                unroll_var.c
 Global Macro: IL_UNROLL_GLOBAL
 Local Macro : -
 Cases Macro : IL_UNROLL_CASES

                              -*-*-*

reply via email to

[Prev in Thread] Current Thread [Next in Thread]