function_parameter_accessor.cc

Go to the documentation of this file.
00001 /*!
00002         \file
00003         \brief Function parameter acessor.
00004         \author jaz
00005 */
00006 #include <lestes/md/functions/function_parameter_accessor.g.hh>
00007 #include <lestes/md/types/tm_data_type_base.g.hh>
00008 #include <lestes/md/registers/tm_register.g.hh>
00009 #include <lestes/md/types/ss_type2tm_type.g.hh>
00010 #include <lestes/md/mem/memory_allocator_bases.g.hh>
00011 #include <lestes/backend_v2/intercode/pi.g.hh>
00012 #include <lestes/backend_v2/intercode/pi_mem_factory.g.hh>
00013 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00014 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00015 #include <lestes/lang/cplus/sem/ss_type2id.g.hh>
00016 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00017 #include <lestes/lang/cplus/sem/visitor.v.g.hh>
00018 
00019 package(lestes);
00020 package(md);
00021 package(functions);
00022 
00023 using namespace ::lestes::backend_v2::intercode;
00024 using namespace ::lestes::md::types;
00025 using namespace ::lestes::md::registers;
00026 using namespace ::lestes::lang::cplus::sem;
00027 
00028 typedef map<ulint, srp<pi_mem_factory> > params_map_type;
00029 typedef list<srp<ss_type> > ss_type_list_type;
00030 
00031 /*!
00032         \brief Gets parameter with given index.
00033         
00034         Note:
00035          - index starts from 0
00036          
00037         \param index The index.
00038         \return Memory space with parameter.
00039 */
00040 ptr< pi_mem_factory > function_parameter_accessor::get_parameter(ulint index)
00041 {
00042         //Gen parameter with given index.
00043         params_map_type::iterator it = params_get()->find(index);
00044         
00045         if ( it!=params_get()->end() ) {
00046                 //Parameter has already been accessed. Return cached result.
00047                 return it->second;
00048         }
00049         
00050         //Get ss_type of the function. It contains also list of parameter types.
00051         ptr<ss_function> fnc_type = function_get()->type_get().dncast<ss_function>();
00052 
00053         //Get offset of the 1st parameter.
00054         t_size offset = 64;
00055         
00056         if ( get_ret_val() ) {
00057                 offset = ret_val_end_offset;
00058         }
00059 
00060         if ( get_this() ) {
00061                 offset = this_end_offset;
00062         }
00063         
00064         ptr<tm_data_type_base> param_dt_type;
00065         ulint param_index = 0;
00066         ss_type_list_type::iterator it1;
00067         for(it1=fnc_type->params_get()->begin(); it1!=fnc_type->params_get()->end(); it1++, param_index++) {
00068                 param_dt_type = (*it1)->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance());
00069                 
00070                 if ( param_index == index ) {
00071                         break;
00072                 }
00073                 
00074                 if ( param_dt_type->bitwidth_get() % 32 == 0 ) {
00075                         offset += param_dt_type->bitwidth_get();
00076                 } else {
00077                         offset += (param_dt_type->bitwidth_get()/32 +1)*32;
00078                 }
00079         }
00080         
00081         lassert(param_dt_type);
00082 
00083         //Create factory representing space where the parameter is located.
00084         ptr<pi_mem_factory> ret_val = pi_mf_stack::create(NULL,param_dt_type, offset);
00085         
00086         //Add parameter factory to parameter cache.
00087         (*params_get())[index] = ret_val;
00088         
00089         return ret_val; 
00090 }
00091 
00092 /*!
00093         \brief Gets secret "this" parameter.
00094         
00095         \return If function is member function then it returns memory space with "this" parameter. NULL otherwise. 
00096 */
00097 ptr< pi_mem_factory > function_parameter_accessor::get_this()
00098 {
00099         if ( this_par_get() ) {
00100                 //Parameter has already been accessed. Return cached result.
00101                 return this_par_get();
00102         }
00103 
00104         if ( ss_type2id::instance()->process(function_get()->type_get()) != ss_type2id::MEMBER_FUNCTION ) {
00105                 //The function is NOT member function.
00106                 return NULL;
00107         }
00108         
00109         //Get type of this pointer.
00110         ptr<ss_member_function> fnc_type = function_get()->type_get().dncast<ss_member_function>();     
00111         ptr<tm_data_type_base> this_type = fnc_type->this_type_get()->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance());
00112         
00113         /*
00114                 Initial offset is 64, because EIP is pushed on the stack during call instruction
00115                 and EBP is pushed during function prologue.
00116         */
00117         t_size offset = 64;
00118         
00119         if ( !fnc_type->is_void() ) {
00120                 //Get return type.
00121                 ptr<tm_data_type_base> ret_type = fnc_type->returns_get()->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance());
00122         
00123                 if ( !ret_type->return_reg_get() ) {
00124                         //Type is not returned in register.
00125                         offset += 32;
00126                 }
00127         }
00128         
00129         this_end_offset = offset+32;
00130         this_par_set(pi_mf_stack::create(NULL,this_type, offset));
00131         return this_par_get();
00132 }
00133 
00134 
00135 /*!
00136         \brief Gets secret parameter with pointer to space for returning value from the function.       
00137         
00138         \return If function returns non-void type then it returns memory space with pointer. NULL otherwise. 
00139 */
00140 ptr< pi_mem_factory > function_parameter_accessor::get_ret_val()
00141 {
00142         if ( ret_val_par_get() ) {
00143                 //Parameter has already been accessed. Return cached result.
00144                 return ret_val_par_get();
00145         }
00146         
00147         //Get ss_type of function.
00148         ptr<ss_function> fnc_type = function_get()->type_get().dncast<ss_function>();
00149         
00150         if ( fnc_type->returns_get()->is_void() ) {
00151                 //Function returns void.
00152                 return NULL;
00153         }
00154         lassert(fnc_type->returns_get());
00155         
00156         //Get returned type.
00157         ptr<tm_data_type_base> type = fnc_type->returns_get()->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance());
00158         
00159         ptr<pi_mem_factory> ret_val;
00160         if (type->return_reg_get() ){
00161                 /*
00162                         Type is returned in register.
00163                 */
00164                 ret_val = pi_mf_preg::create(NULL, type, pi_preg::create(NULL, type)); 
00165                 ret_val_end_offset = 64;
00166         } else {
00167                 /*
00168                         Type is returned in memory as 1st parameter.
00169                         Starting offset is 64, because of EIP and EBP are pushed on the stack during call instruction.
00170                 */
00171                 ret_val = pi_mf_stack::create(NULL,type, 64);
00172                 ret_val_end_offset = 96;
00173         }
00174         
00175         ret_val_par_set(ret_val);
00176         return ret_val_par_get();
00177 }
00178 
00179 ptr< function_parameter_accessor > function_parameter_accessor::instance(ptr<ss_function_declaration> function)
00180 {
00181         map< srp< ss_function_declaration >, srp< function_parameter_accessor > >::iterator it;
00182         it = singleton_instances_get()->find(function);
00183         
00184         if ( it!=singleton_instances_get()->end() ) {
00185                 return it->second;
00186         } else {
00187                 ptr< function_parameter_accessor > new_instance = function_parameter_accessor::create(function);
00188                 singleton_instances_get()->insert(::std::pair<srp< ss_function_declaration >, srp< function_parameter_accessor> >(function,new_instance));
00189                 return new_instance;
00190         }
00191         
00192         return NULL;    
00193 }
00194 
00195 
00196 
00197 end_package(functions);
00198 end_package(md);
00199 end_package(lestes);
00200 

Generated on Mon Feb 12 18:22:34 2007 for lestes by doxygen 1.5.1-20070107