void BitVector::read(const char *location) { _has_count = false; _count = 0; const char *follow = location; suif_assert((*follow == '0') && (follow[1] == 'x')); follow += 2; bool sign_extend = (*follow == '.'); while (*follow == '.') ++follow; const char *end = follow; while (*end != 0) ++end; suif_assert(end > follow); remove_reference(_block); size_t hex_digits_per_word = sizeof(BitVector::ChunkT) * 2; bool infinity_is_one = (sign_extend ? ((*follow > '7') || (*follow < '0')) : false); size_t word_count = ((end - follow) + hex_digits_per_word - 1) / hex_digits_per_word; _block = new BitVectorBlock(word_count, infinity_is_one, word_count); size_t word_num = word_count; if (((end - follow) % hex_digits_per_word) > 0) { BitVector::ChunkT high_word = (infinity_is_one ? ~0lu : 0lu); while (((end - follow) % hex_digits_per_word) > 0) { unsigned char new_half_byte = convert_from_hex(*follow); suif_assert(new_half_byte != 16); high_word = (high_word << 4) | new_half_byte; ++follow; } --word_num; _block->_data[word_num] = high_word; } while (follow < end) { BitVector::ChunkT this_word = 0; for (size_t digit_num = 0; digit_num < hex_digits_per_word; ++digit_num) { unsigned char new_half_byte = convert_from_hex(*follow); suif_assert(new_half_byte != 16); this_word = (this_word << 4) | new_half_byte; ++follow; } --word_num; _block->_data[word_num] = this_word; } assert(follow == end); assert(word_num == 0); _block->unpad(); }
void BitVectorBlock::expand_data(size_t new_data_length) { suif_assert(new_data_length >= 0); if (new_data_length <= _data_length) return; if (new_data_length > _data_space) { BitVector::ChunkT *new_data = new BitVector::ChunkT[new_data_length]; for (size_t chunk_num = 0; chunk_num < _data_length; ++chunk_num) new_data[chunk_num] = _data[chunk_num]; if (_data != NULL) delete[] _data; _data = new_data; _data_space = new_data_length; } BitVector::ChunkT mask = 0; if (_infinity_bit_is_one) mask = ~0; for (size_t chunk_num = _data_length; chunk_num < new_data_length; ++chunk_num) { _data[chunk_num] = mask; } _data_length = new_data_length; }
/* * Derives a new vtbl from the parent's vtbl. * Methods whose is_dispatched field is false are ignored. */ vtbl_t* SingleInheritanceVtbls:: derive_vtbl( vtbl_t* parent_vtbl, SingleInheritanceClassType* current_class ) { suif_assert( current_class ); if( ! current_class->get_methods_are_complete() ) handle_incomplete_class( current_class ); if ( parent_vtbl == NULL ) parent_vtbl = new vtbl_t(); // copy the parent vtbl vtbl_t* current_vtbl = new vtbl_t( *parent_vtbl ); list<InstanceMethodSymbol* > method_list = collect_stos<InstanceMethodSymbol,InstanceMethodSymbol>( current_class->get_instance_method_symbol_table() ); for ( unsigned i = 0 ; i < method_list.size() ; i++ ) { InstanceMethodSymbol* msym = method_list[i]; if ( msym->get_is_dispatched() ) insert_method( msym, current_vtbl ); } // insert vtbl in map _vtbls.enter_value( current_class, current_vtbl ); return current_vtbl; }
void SuifEnv::error( SuifObject* obj, const char* file_name, int line_number, const char* module_name, const char* description, va_list args ) { suif_assert( _error_subsystem ); _error_subsystem->error( obj, file_name, line_number, module_name, description, args ); }
void SuifEnv::warning( const char* file_name, int line_number, const char* module_name, const char* description, va_list args ) { suif_assert( _error_subsystem ); _error_subsystem->warning( file_name, line_number, module_name, description, args ); }
WalkingMaps::WalkingMaps(const WalkingMaps &other) : _done(false), _skip(false), _pre_map(0), _children_map(0), _post_map(0), _process_map(0), _user_state(0) { suif_assert(false); }
void SuifEnv::information( const char* file_name, int line_number, const char* module_name, int verbosity_level, const char* description, va_list args ) { suif_assert( _error_subsystem ); _error_subsystem->information( file_name, line_number, module_name, verbosity_level, description, args ); }
static DataType *unqualify_data_type(Type *t) { while (is_kind_of<QualifiedType>(t)) { t = to<QualifiedType>(t)->get_base_type(); } if (is_kind_of<DataType>(t)) return(to<DataType>(t)); suif_assert( false ); return 0; }
//---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void SuifPrinterModule::print(ostream& output, const SuifObject*rootNode) { suif_assert(rootNode != NULL); //const MetaClass *type = rootNode->get_meta_class(); int _indent = 2; print2(output, ObjectWrapper(rootNode), emptyLString, _indent); output <<endl; }
Statement *while_statement_walker::dismantle_while_statement(WhileStatement *the_while){ Statement *result = 0; Expression *condition = the_while->get_condition(); // we are going to reuse the condition so we must remove it // from the if statement first to avoid ownership conflicts // the_while->set_condition(SourceOp()); // remove_source_op(condition); remove_suif_object(condition); Statement *body = the_while->get_body(); CodeLabelSymbol *break_label = the_while->get_break_label(); CodeLabelSymbol *continue_label = the_while->get_continue_label(); // likewise of these parts - remove from if. the_while->set_body(0); the_while->set_break_label(0); the_while->set_continue_label(0); if (body != 0) { StatementList *replacement = create_statement_list(body->get_suif_env()); result = replacement; suif_assert(continue_label != 0); UnaryExpression* negated_condition = create_unary_expression(body->get_suif_env(), condition->get_result_type(), k_logical_not, condition ); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label)); replacement-> append_statement(create_branch_statement(body->get_suif_env(), negated_condition, break_label)); replacement->append_statement(body); suif_assert(break_label != 0); replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_label)); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label)); } the_while->get_parent()->replace(the_while,result); return result; }
BitVector::ChunkT BitVector::get_chunk(size_t chunk_num) const { suif_assert(chunk_num >= 0); if (chunk_num >= _block->_data_length) { return (_block->_infinity_bit_is_one ? ~(BitVector::ChunkT)0 : (BitVector::ChunkT)0); } return _block->_data[chunk_num]; }
bool BitVector::get_bit(size_t bit_num) const { suif_assert(bit_num >= 0); size_t chunk_num = bit_num / (size_t)BITS_PER_WORD; if (chunk_num >= _block->_data_length) return _block->_infinity_bit_is_one; BitVector::ChunkT mask = ((BitVector::ChunkT)1) << (bit_num % (size_t)BITS_PER_WORD); return (((_block->_data[chunk_num] & mask) == 0) ? false : true); }
void BitVector::set_chunk(size_t chunk_num, BitVector::ChunkT new_chunk) { suif_assert(chunk_num >= 0); make_changable(); if (chunk_num >= _block->_data_length) _block->expand_data(chunk_num + 1); _block->_data[chunk_num] = new_chunk; size_t bit_num = (chunk_num + 1) * (size_t)BITS_PER_WORD; if (bit_num > _block->_num_significant_bits) _block->_num_significant_bits = bit_num; _block->unpad(); }
SuifEnv::SuifEnv(const SuifEnv &other) : input_sub_system( 0 ), output_subsystem( 0 ), cloneSubSystem( 0 ), _dll_subsystem( 0 ), _module_subsystem( 0 ), _error_subsystem( 0 ), _print_subsystem( 0 ), _type_builder( 0 ), _object_factory( 0 ), factories( new list<RealObjectFactory*> ), _file_set_block( 0 ), rudimentaryAddressMap( 0 ) { suif_assert(false); }
static void handle_static_children_suif_object(WalkingMaps *walk, SuifObject *obj) { // use the object iterator to find all suiffobjects. // check to see that the parent is ME for (Iter<SuifObject> iter = collect_instance_objects<SuifObject>(obj); iter.is_valid(); iter.next()) { // list<SuifObject *>::iterator iter = the_list->begin(); // for (; iter != the_list->end(); iter++) { SuifObject *child = &iter.current(); if (child == 0 ) continue; suif_assert(child->get_parent() == obj); walk->get_process_map()->apply(child); if (walk->is_done()) return; } }
void BitVector::set_bit(size_t bit_num, bool new_value) { suif_assert(bit_num >= 0); if ((bit_num >= _block->_num_significant_bits) && (new_value == _block->_infinity_bit_is_one)) { return; } make_changable(); size_t chunk_num = bit_num / (size_t)BITS_PER_WORD; if (chunk_num >= _block->_data_length) _block->expand_data(chunk_num + 1); BitVector::ChunkT mask = ((BitVector::ChunkT)1) << (bit_num % (size_t)BITS_PER_WORD); if (new_value) _block->_data[chunk_num] |= mask; else _block->_data[chunk_num] &= ~mask; if (bit_num >= _block->_num_significant_bits) _block->_num_significant_bits = bit_num + 1; _block->unpad(); }
void SGraphBit::set_node_successors(SGraphNode node, const BitVector *t) { suif_assert(is_node_member(node)); BitVector *bv = retrieve_bv(node); (*bv) = (*t); }
WalkingMaps& WalkingMaps::operator=(const WalkingMaps &other) { suif_assert(false); return(*this); }
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){ suif_hash_map<ParameterSymbol*, Type*> params; TypeBuilder *tb = (TypeBuilder*) get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); // collect all procedure parameters of pointer type into params list for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator(); iter.is_valid(); iter.next()) { ParameterSymbol* par_sym = iter.current(); Type* par_type = tb->unqualify_type(par_sym->get_type()); if(is_kind_of<PointerType>(par_type)){ // put NULLs into the map at first, // they will later be overwritten params[par_sym] = NULL; } } if(params.size()==0) return; // nothing to do // walk thru all AREs and look for arrays that are in the param list {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { ArrayReferenceExpression* are = &iter.current(); if(is_kind_of<UnaryExpression>(are->get_base_array_address())){ UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address()); if(ue->get_opcode() == k_convert){ if(is_kind_of<LoadVariableExpression>(ue->get_source())){ LoadVariableExpression* lve = to<LoadVariableExpression>(ue->get_source()); VariableSymbol* array = lve->get_source(); for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin(); iter!=params.end();iter++) { ParameterSymbol* par_sym = (*iter).first; if(par_sym == array){ // match! Type* array_type; suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.find(par_sym); if(iter==params.end() || (*iter).second==NULL){ //array_type = to<PointerType>(ue->get_result_type())->get_reference_type(); array_type = tb->get_qualified_type(ue->get_result_type()); params[par_sym] = array_type; //printf("%s has type ",par_sym->get_name().c_str()); //array_type->print_to_default(); }else{ array_type = params[par_sym].second; suif_assert(is_kind_of<QualifiedType>(array_type)); } array->replace(array->get_type(), array_type); remove_suif_object(ue); remove_suif_object(lve); lve->replace(lve->get_result_type(), tb->unqualify_type(array_type)); // put the LoadVar directly under ARE are->set_base_array_address(lve); //are->print_to_default(); } } } else { suif_warning(ue->get_source(), ("Expecting a LoadVariableExpression here")); } } else { suif_warning(ue, ("Disallow converts in AREs for " "things other than procedure parameters")); } } } } }
SuifEnv& SuifEnv::operator=(const SuifEnv &) { suif_assert(false); return(*this); }
~hash_bin_type(void) { suif_assert((next == 0) && (_ref_count == 0)); }
void DismantleStructuredReturns::do_file_set_block( FileSetBlock* file_set_block ) { suif_map<CProcedureType *,QualifiedType *> type_map; list<ArrayReferenceExpression*> ref_exprs; SuifEnv *env = 0; TypeBuilder *tb = 0; VoidType *vt = 0; for (Iter<ProcedureSymbol> iter = object_iterator<ProcedureSymbol>(file_set_block); iter.is_valid(); iter.next()) { ProcedureSymbol *sym = &iter.current(); Type *type = sym->get_type(); if (!is_kind_of<CProcedureType>(type)) continue; CProcedureType *cp_type = to<CProcedureType>(type); type = cp_type->get_result_type(); if (!env) { env = type->get_suif_env(); tb = (TypeBuilder*) env->get_object_factory(TypeBuilder::get_class_name()); vt = tb->get_void_type(); } suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); QualifiedType *qtype; if (t_iter == type_map.end()) { if (!is_kind_of<GroupType>(type) && !is_kind_of<ArrayType>(type)) continue; qtype = tb->get_qualified_type( tb->get_pointer_type(to<DataType>(type))); cp_type->set_result_type(vt); cp_type->insert_argument(0,qtype); type_map.enter_value(cp_type,qtype); } else { qtype = (*t_iter).second; } ProcedureDefinition *def = sym->get_definition(); if (!def) continue; ParameterSymbol *par = create_parameter_symbol(env,qtype); def->get_symbol_table()->append_symbol_table_object(par); def->insert_formal_parameter(0,par); // Convert all returns into assigned and returns for (Iter<ReturnStatement> ret_iter = object_iterator<ReturnStatement>(def->get_body()); ret_iter.is_valid(); ret_iter.next()) { ReturnStatement *ret = &ret_iter.current(); Expression *retval = ret->get_return_value(); ret->set_return_value(0); retval->set_parent(0); insert_statement_before(ret, create_store_statement(env,retval,create_var_use(par))); } } // Change all calls to the new form for (Iter<CallStatement> cs_iter = object_iterator<CallStatement>(file_set_block); cs_iter.is_valid(); cs_iter.next()) { CallStatement *call = &cs_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); call->set_destination(0); } for (Iter<CallExpression> ce_iter = object_iterator<CallExpression>(file_set_block); ce_iter.is_valid(); ce_iter.next()) { CallExpression *call = &ce_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); ; suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); Statement *loc = get_expression_owner(call); call->get_parent()->replace(call,create_var_use(var)); call->set_parent(0); suif_assert(vt != 0); call->set_result_type(vt); EvalStatement *es = create_eval_statement(env); insert_statement_before(loc,es); // Would be better to turn this into a call statement es->append_expression(call); } }
void SuifEnv::write( const String& outputFileName ) const { suif_assert( output_subsystem ); output_subsystem->write( outputFileName ); }
FileSetBlock *SuifEnv::read_more( const String& inputFileName ) const { suif_assert( input_sub_system ); return input_sub_system->read( inputFileName ); }
void SGraphBit::add_edge(const SGraphEdge &edge) { suif_assert(is_node_member(edge.from())); suif_assert(is_node_member(edge.to())); retrieve_bv(edge.from())->set_bit(edge.to(), true); }
/** Convert ArrayReferenceExpression \a top_array to a MultiDimArrayExpression. */ void OneDimArrayConverter:: convert_array_expr2multi_array_expr(ArrayReferenceExpression* top_array){ Expression* expr = top_array; unsigned int i = 0; suif_vector<Expression*> lower_bounds; suif_vector<Expression*> upper_bounds; list<Expression*> indices; IInteger bit_size, bit_alignment; suif_vector<ArrayReferenceExpression *> exprs; do{ ArrayReferenceExpression* are = to<ArrayReferenceExpression>(expr); expr = are->get_base_array_address(); exprs.push_back(are); } while(is_kind_of<ArrayReferenceExpression>(expr)); // collect bounds and indeces for (unsigned int exp_ind = 0; exp_ind < exprs.size();exp_ind++) { ArrayReferenceExpression* are = exprs[exp_ind]; DataType* type = are->get_base_array_address()->get_result_type(); ArrayType* array_type; if(is_kind_of<ArrayType>(type)){ array_type = to<ArrayType>(type); }else{ array_type = to<ArrayType>( unwrap_ptr_ref_type(type)->get_base_type()); } bit_size = array_type->get_element_type()-> get_base_type()->get_bit_size(); bit_alignment = array_type->get_element_type()-> get_base_type()->get_bit_alignment(); // What happens to ArrayType?? Does it become garbage? suif_assert(array_type->get_lower_bound()); suif_assert(array_type->get_upper_bound()); // clone bounds and add to the lists lower_bounds.push_back(array_type->get_lower_bound()); upper_bounds.push_back(array_type->get_upper_bound()); // save the index Expression* index = are->get_index(); remove_suif_object(index); index->set_parent(NULL); indices.push_back(index); suif_assert(upper_bounds[i]); suif_assert(lower_bounds[i]); suif_assert(indices[i]); i++; } // Build the offset for the expression. We have to traverse upwards to do this Expression *top_expr_base = exprs[exprs.size()-1]->get_base_array_address(); DataType* top_expr_base_type = top_expr_base->get_result_type(); ArrayType* top_array_type; if(is_kind_of<ArrayType>(top_expr_base_type)){ top_array_type = to<ArrayType>(top_expr_base_type); }else{ top_array_type = to<ArrayType>(tb->unqualify_data_type(unwrap_ptr_ref_type( top_expr_base_type))); } Expression* inc = create_int_constant(suif_env, 1); Expression* offset = create_int_constant(suif_env, 0); suif_vector<Expression *> elements; for (unsigned int ind = 0;ind < lower_bounds.size(); ind ++) { Expression *lower = lower_bounds[ind]; Expression *upper = upper_bounds[ind]; offset = build_dyadic_expression(k_add, offset, build_dyadic_expression( k_multiply, deep_suif_clone(inc), deep_suif_clone(lower))); Expression *element = build_dyadic_expression(k_add, build_dyadic_expression(k_subtract, deep_suif_clone(upper), deep_suif_clone(lower)), create_int_constant(suif_env,1)); inc = build_dyadic_expression(k_multiply, inc, deep_suif_clone(element)); elements.push_back(element); } // Now, inc and offset are ready // retrieve the multi-type MultiDimArrayType* multi_type; suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter = type_map->find(top_array_type); #ifdef CONVERT_TYPES suif_assert_message((type_iter != type_map->end()), ("Array type never translated")); #else if(type_iter == type_map->end()){ multi_type = array_type2multi_array_type(top_array_type); }else #endif //CONVERT_TYPES multi_type = (*type_iter).second; remove_suif_object(top_expr_base); // add a convert to the necessary type top_expr_base = create_unary_expression(suif_env, tb->get_pointer_type(multi_type), k_convert, top_expr_base); //top_expr_base->print_to_default(); // construct the expression to be returned MultiDimArrayExpression* mae = create_multi_dim_array_expression(suif_env, top_array->get_result_type(), top_expr_base, offset); // now when we have the expression, set the indices for (list<Expression*>::iterator ind_iter = indices.begin(); ind_iter!=indices.end(); ind_iter++) { Expression* index = *ind_iter; //printf("%p \t", index);index->print_to_default(); mae->append_index(index); } for (suif_vector<Expression *>::iterator eiter = elements.begin(); eiter != elements.end(); eiter ++) { Expression* element = *eiter; mae->append_element(element); } replace_expression(top_array, mae); }