Exemplo n.º 1
0
		int bitTest(int bitSizes[], bool sign) {
    		int start = sizeof(T) * 8;

    		int bitVals[4] = {0, 0, 0, 0};
    		int num;
    		T test = 0;
    		union {
        		T total;
        		S b;
    		}bitRep;

    		if (sign) {
        		bitVals[0] = (1 << (bitSizes[0] - 1)) - 1;
        		bitVals[1] = -(1 << (bitSizes[1] - 1));
        		bitVals[2] = 0;
        		bitVals[3] = (1 << (bitSizes[3] - 1)) + (1 << bitSizes[3]/2);;
    		} else {
       			bitVals[0] = (1 << bitSizes[0]) + (1 << bitSizes[0]/2);
        		bitVals[1] = 0;
        		bitVals[2] = (1 << (bitSizes[2]/2)) - 1;
        		bitVals[3] = (1 << bitSizes[3]) - 1;
    		}   

    		for (unsigned int i = 0; i < 4; i++) {

        		start -= bitSizes[i];
        		test = insert_bitfield_any((T) test, bitVals[i], sizeof(T), start, bitSizes[i]);
        		//std::cout << "Test: " << (int)test << std::endl;
        		if (sign) {
        			num = extract_bitfield_any((T) test, sizeof(T), start, bitSizes[i]);
        		} else {
        			num = extract_unsigned_bitfield_any((T) test, sizeof(T), 0, (start+bitSizes[i]));
        		}
        		if (bitVals[i] > num) {
        			/* bit value inserted is too large for bit member, ensure correct behavior */
        			EXPECT_EQ(num, bitVals[i] - (1 << bitSizes[i]));
        		} else if (bitVals[i] < num) {
        			EXPECT_EQ(num, -2*(1 << bitSizes[i]) + bitVals[i]);
        		} else {
        			EXPECT_EQ(num, bitVals[i]);
        		}
        	}
        	
			bitRep.b.var1 = bitVals[0];
        	bitRep.b.var2 = bitVals[1];
        	bitRep.b.var3 = bitVals[2];
        	bitRep.b.var4 = bitVals[3];
        
			EXPECT_EQ(test, bitRep.total);

        	//printf("Decimal: %d %d %d %d\n", bitVals[0], bitVals[1], bitVals[2], bitVals[3]);
        	return 0;
		}
int Trick::MemoryManager::assign_recursive(void* base_addr, ATTRIBUTES* attr, int curr_dim, int offset, V_TREE* v_tree, UCFn* cf) {

   char* assign_addr;
   int remaining_dimensions = attr->num_index - curr_dim;

   if ( remaining_dimensions == 0 ) {

      switch (attr->type) {

           case TRICK_CHARACTER :
           case TRICK_UNSIGNED_CHARACTER :
               assign_addr = (char*)base_addr + offset * sizeof(char);
               if (v_tree && v_tree->v_data) {
                   *(char*)assign_addr = vval_char(v_tree->v_data);
               } else {
                   *(char*)assign_addr = '\0';
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(char*)" << (void*)assign_addr
                             << " = ";
                   if (isprint(*(char*)assign_addr)) {
                       std::cout << *(char*)assign_addr;
                   } else {
                       std::cout << (int)*(char*)assign_addr;
                   }
                   std::cout << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_WCHAR :
               assign_addr = (char*)base_addr + offset * sizeof(wchar_t);
               if (v_tree && v_tree->v_data) {
                   *(wchar_t*)assign_addr = vval_char(v_tree->v_data);
               } else {
                   *(wchar_t*)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(wchar_t*)" << (void*)assign_addr
                             << " = " << *(wchar_t*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_SHORT :
           case TRICK_UNSIGNED_SHORT :
               assign_addr = (char*)base_addr + offset * sizeof(short);
               if (v_tree && v_tree->v_data) {
                   *(short *)assign_addr = vval_short(v_tree->v_data);
               } else {
                   *(short *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(short*)" << (void*)assign_addr
                             << " = " << *(short*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_INTEGER :
           case TRICK_UNSIGNED_INTEGER :
               assign_addr = (char*)base_addr + offset * sizeof(int);
               if (v_tree && v_tree->v_data) {
                   int input_value;
                   input_value = vval_int(v_tree->v_data);
                   if (cf == NULL) {
                       *(int *)assign_addr = input_value;
                   } else {
                       *(int *)assign_addr = input_value * cf->C[1] + cf->C[0];
                   }
               } else {
                   *(int *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(int*)" << (void*)assign_addr
                             << " = " << *(int*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_BOOLEAN :
               assign_addr = (char*)base_addr + offset * sizeof(bool);
               if (v_tree && v_tree->v_data) {
                   *(bool *)assign_addr = (vval_short(v_tree->v_data)!=0);
               } else {
                   *(bool *)assign_addr = false;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(bool*)" << (void*)assign_addr
                             << " = " << *(bool*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_ENUMERATED : 
               if (v_tree && v_tree->v_data) {
                   if ((size_t)attr->size == sizeof(int)) {
                       assign_addr = (char*)base_addr + offset * sizeof(int);
                       *(int *)assign_addr = vval_int(v_tree->v_data);
                       if (debug_level) {
                           std::cout << std::endl << "Assignment (Enum): *(int*)" << (void*)assign_addr
                                     << " = " << *(int*)assign_addr << ";" << std::endl;
                           std::cout.flush();
                       }
                   } else if ((size_t)attr->size == sizeof(short)) {
                       assign_addr = (char*)base_addr + offset * sizeof(short);
                       *(short *)assign_addr = vval_short(v_tree->v_data);
                       if (debug_level) {
                           std::cout << std::endl << "Assignment (Enum): *(short*)" << (void*)assign_addr
                                     << " = " << *(short*)assign_addr << ";" << std::endl;
                           std::cout.flush();
                       }
                   } else {
                       std::stringstream message;
                       message << "Enumeration of size " << attr->size << " is not supported.";
                       emitError(message.str());
                   }
               } else {
                   emitError("v_tree data appears to be corrupted.");
               }
               break;
           case TRICK_LONG :
           case TRICK_UNSIGNED_LONG :
               assign_addr = (char*)base_addr + offset * sizeof(long);
               if (v_tree && v_tree->v_data) {
                   long input_value; 
                   input_value = vval_long(v_tree->v_data);
                   if (cf == NULL) {
                       *(long *)assign_addr = input_value;
                   } else {
                       *(long *)assign_addr = input_value * cf->C[1] + cf->C[0];
                   }
               } else {
                   *(long *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(long*)" << (void*)assign_addr
                             << " = " << *(long*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_FLOAT :
               assign_addr = (char*)base_addr + offset * sizeof(float);
               if (v_tree && v_tree->v_data) {
                   float input_value;
                   input_value = vval_float(v_tree->v_data);
                   if (cf == NULL) {  // There is no units conversion.
                       *(float *)assign_addr = input_value;
                   } else { // There is units conversion.
                       *(float *)assign_addr = input_value * cf->C[1] + cf->C[0];
                   }
               } else {
                   *(float *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(float*)" << (void*)assign_addr
                             << " = " << *(float*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_DOUBLE :
               assign_addr = (char*)base_addr + offset * sizeof(double);
               if (v_tree && v_tree->v_data) {
                   double input_value;
                   input_value = vval_double(v_tree->v_data);
                   if (cf == NULL) {
                       *(double *)assign_addr = input_value;
                   } else {
                       *(double *)assign_addr = input_value * cf->C[1] + cf->C[0];
                   }
               } else {
                   *(double *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(double*)" << (void*)assign_addr
                             << " = " << *(double*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_LONG_LONG :
           case TRICK_UNSIGNED_LONG_LONG :
               assign_addr = (char*)base_addr + offset * sizeof(long long);
               if (v_tree && v_tree->v_data) {
                   *(long long *)assign_addr = vval_longlong(v_tree->v_data);
               } else {
                   *(long long *)assign_addr = 0;
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(long long*)" << (void*)assign_addr
                             << " = " << *(long long*)assign_addr << ";" << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_BITFIELD :
           case TRICK_UNSIGNED_BITFIELD : {
                   int input_value; 
                   assign_addr = (char*)base_addr + offset * (size_t)attr->size;
                   if (v_tree && v_tree->v_data) {
                       input_value = vval_int(v_tree->v_data);
                   } else {
                       input_value = 0;
                   }
                   if (attr->size == sizeof(int)) {
                       *(unsigned int*)assign_addr = insert_bitfield_any(
                           *(unsigned int*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size);
                   } else if (attr->size == sizeof(short)) {
                       *(unsigned short*)assign_addr = insert_bitfield_any(
                           *(unsigned short*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size);
                   } else if (attr->size == sizeof(char)) {
                       *(unsigned char*)assign_addr = insert_bitfield_any(
                           *(unsigned char*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size);
                   } else {
                       std::stringstream message;
                       message << "Unhandled bitfield struct size (" << attr->size << ") in bitfield assignment.";
                       emitError(message.str());
                   }
                   if (debug_level) {
                       std::cout << std::endl << "Assignment: "
                                 << "Within the " << attr->size << " byte struct at " << (void*)assign_addr
                                 << ", the bitfield ["<< attr->index[0].start << ".."
                                 << attr->index[0].start + attr->index[0].size - 1
                                 << "] = " << input_value << ";"
                                 << std::endl;
                       std::cout.flush();
                   }
               } break;
           case TRICK_FILE_PTR :
               if (debug_level) {
                   std::cout << std::endl << "Assignment: TRICK_FILE_PTR assignments not yet implemented."
                             << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_VOID_PTR :
               if (debug_level) {
                   std::cout << std::endl << "Assignment: TRICK_VOID_PTR assignments not yet implemented."
                             << std::endl;
                   std::cout.flush();
               }
               break;
           case TRICK_STRING :
               assign_addr = (char*)base_addr + offset * sizeof(char*);
               if (v_tree && v_tree->v_data) {
                   *(std::string*)assign_addr = vval_string(v_tree->v_data);
               } else {
                   *(std::string*)assign_addr = "";
               }
               if (debug_level) {
                   std::cout << std::endl << "Assignment: *(std::string)" << (void*)assign_addr
                             << " = \"" << *(std::string*)assign_addr << "\";" << std::endl;
                   std::cout.flush();
               }
               break;
           default:
               std::stringstream message;
               message << "Unhandled Type (" << attr->type << ") in assignment.";
               emitError(message.str());
               return (1);
               break;
      }

   } else if ( remaining_dimensions > 0 ) {

       int size_of_curr_dim;

       size_of_curr_dim = attr->index[curr_dim].size ;
       assign_addr = (char*)base_addr + offset * sizeof(void*);

       if ( size_of_curr_dim == 0) { // the remaining dimensions are pointer dimensions.
           if (v_tree && v_tree->v_data) {

               if ((remaining_dimensions == 1) && (v_tree->v_data->type == TRICK_STRING)) { 
                   *(char**)assign_addr = mm_strdup( vval_string(v_tree->v_data));
               } else {
                   *(void**)assign_addr = vval_voidp(v_tree->v_data);
               }

           } else {
               *(void**)assign_addr = 0;
           }

           if (debug_level) {
               std::cout << std::endl << "Assignment: *(void**)" << (void*)assign_addr
                         << " = " << *(void**)assign_addr << ";" << std::endl;
               std::cout.flush();
           }

       } else { // next dimension is fixed.

           if ((attr->type == TRICK_CHARACTER) &&
               (remaining_dimensions == 1) &&
               (v_tree) &&
               (v_tree->v_data)
              ) {

               if ((v_tree->v_data->type == TRICK_STRING) &&
                   (v_tree->v_data->value.cp != NULL)) {

                   int rhs_len = (int)strlen(v_tree->v_data->value.cp) + 1;
                   if (rhs_len <= size_of_curr_dim ) {
                       strcpy((char*)assign_addr, v_tree->v_data->value.cp);
                   } else {
                       emitError("Memory Manager: char array is too small for the attempted string assignment.");
                       return (1);
                   }
               } else {
                   *(char*)assign_addr = '\0';
               }
               
           } else if ( (attr->type == TRICK_WCHAR) &&
                       (remaining_dimensions == 1)) { 

               if ((v_tree) &&
                   (v_tree->v_data->type == TRICK_WSTRING) &&  
                   (v_tree->v_data->value.wcp != NULL)) {

                       int rhs_len = (int)wcslen(v_tree->v_data->value.wcp) + 1;
                       if (rhs_len <= size_of_curr_dim ) {
                           wcscpy((wchar_t*)assign_addr, v_tree->v_data->value.wcp);
                       } else {
                           std::stringstream message;
                           message << "wchar_t array at [" << (void*)assign_addr
                                   << "] is to small for the attempted string assignment." ;
                           emitError(message.str());
                           return (1);
                       }
               } else if ((v_tree) &&
                          (v_tree->v_data->type == TRICK_STRING) && 
                          (v_tree->v_data->value.cp != NULL)) {

                       int rhs_len = (int)ncs_to_wcs_len(v_tree->v_data->value.cp) + 1;
                       if (rhs_len <= size_of_curr_dim ) {
                           ncs_to_wcs( v_tree->v_data->value.cp, (wchar_t*)assign_addr, rhs_len);
                       } else {
                           std::stringstream message;
                           message << "wchar_t array at [" << (void*)assign_addr
                                   << "] is too small for the attempted string assignment." ;
                           emitError(message.str());
                           return (1);
                       }
               } else {
                   *(wchar_t*)assign_addr = (wchar_t) NULL;
               }
           
           } else {
               int ii;
               V_TREE* curr_vt_node;
               if (v_tree) {
                   curr_vt_node = v_tree->down;
               } else {
                   curr_vt_node =  NULL;
               }               

               for (ii=0; ii < size_of_curr_dim; ii++) {
                   int ret;
                   ret = assign_recursive (base_addr,
                                           attr,
                                           curr_dim+1,
                                           offset * size_of_curr_dim + ii,
                                           curr_vt_node,
                                           cf);

                   if (ret !=0) {
                       return(1);
                   }

                   if (curr_vt_node) {
                     curr_vt_node = curr_vt_node->next;
                   }
               }
           }
       }
   } else {
        emitError("This is bad. In assign_recursive(), remaining_dimensions is negative.");
        return (1);
   }
   return (0);
}
Exemplo n.º 3
0
void Trick::MemoryManager::clear_rvalue( void* base_address, ATTRIBUTES* attr, int curr_dim, int offset) {

    char* final_address;
    int remaining_dimensions = attr->num_index - curr_dim;

    /** @par Detailed Description: */

    /** @par
        If we're referencing a singleton then calculate the address
        from the (base) address, the offset and the data-type. Then
        set the value at that address to nil.
     */
    if (remaining_dimensions ==0) {

        switch (attr->type) {
           case TRICK_CHARACTER :
           case TRICK_UNSIGNED_CHARACTER :
               final_address = (char*)base_address + offset * sizeof(char);
               *(char*)final_address = '\0';
               break;
           case TRICK_BOOLEAN:
               final_address = (char*)base_address + offset * sizeof(bool);
               *(bool*)final_address = false;
               break;
           case TRICK_WCHAR :
               final_address = (char*)base_address + offset * sizeof(wchar_t);
               *(wchar_t*)final_address = 0;
               break;
           case TRICK_SHORT :
           case TRICK_UNSIGNED_SHORT :
               final_address = (char*)base_address + offset * sizeof(short);
               *(short*)final_address = 0;
               break;
           case TRICK_INTEGER :
           case TRICK_UNSIGNED_INTEGER :
               final_address = (char*)base_address + offset * sizeof(int);
               *(int*)final_address = 0;
               break;
           case TRICK_ENUMERATED :
               if ((size_t)attr->size == sizeof(int)) {
                   final_address = (char*)base_address + offset * sizeof(int);
                   *(int*)final_address = 0;
               } else if ((size_t)attr->size == sizeof(short)) {
                   final_address = (char*)base_address + offset * sizeof(short);
                   *(short*)final_address = 0;
               } else {
                   emitError("INTERNAL-ERROR - Unexpected size of ENUMERATION type.") ;
               }
               break;
           case TRICK_LONG :
           case TRICK_UNSIGNED_LONG :
               final_address = (char*)base_address + offset * sizeof(long);
               *(long*)final_address = 0;
               break;
           case TRICK_FLOAT :
               final_address = (char*)base_address + offset * sizeof(float);
               *(float*)final_address = 0.0;
               break;
           case TRICK_DOUBLE :
               final_address = (char*)base_address + offset * sizeof(double);
               *(double*)final_address = 0.0;
               break;
           case TRICK_LONG_LONG :
           case TRICK_UNSIGNED_LONG_LONG :
               final_address = (char*)base_address + offset * sizeof(long long);
               *(long long*)final_address = 0;
               break;
           case TRICK_BITFIELD :
           case TRICK_UNSIGNED_BITFIELD :
               final_address = (char*)base_address + offset * (size_t)attr->size;
               if (attr->size == sizeof(int)) {
                   *(unsigned int*)final_address = insert_bitfield_any(
                       *(unsigned int*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size);
               } else if (attr->size == sizeof(short)) {
                   *(unsigned short*)final_address = insert_bitfield_any(
                       *(unsigned short*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size);
               } else if (attr->size == sizeof(char)) {
                   *(unsigned char*)final_address = insert_bitfield_any(
                       *(unsigned char*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size);
               } else {
                   std::stringstream message;
                   message << "INTERNAL - Unhandled bitfield struct size (" << attr->size << ") in bitfield assignment.";
                   emitError(message.str());
               }
               break;
           case TRICK_FILE_PTR :
               final_address = (char*)base_address + offset * sizeof(void*);
               *(void**)final_address = (void*)NULL;
               break;
           case TRICK_STRING :
               final_address = (char*)base_address + offset * sizeof(void*);
               *(std::string*)final_address = "";
               break;
           case TRICK_STL :
               final_address = (char*)base_address + offset * attr->size ;
               if ( attr->clear_stl ) {
                   (*attr->clear_stl)(final_address) ;
               }
               break;
           default :
               std::stringstream message;
               message << "Unhandled Type (" << (int)attr->type << ").";
               emitError(message.str());
               break;
        }

    /** @par
        If on the otherhand we are referencing an array, then we must consider two cases.
     */
    } else if (remaining_dimensions > 0) {
       int extent;

       extent = attr->index[curr_dim].size ;

       /**  @par
            If the array is unconstrained (i.e., it's a pointer) then we just need to check
            whether the pointer is NULL.
        */
       if ( extent == 0) {
           final_address = (char*)base_address;
           *(void**)final_address = NULL;

       /** @par
           If the array (at this dimension) is constrained (i.e., it's a fixed array )
           then it is nil if and only if each of it's sub-elements (at the next dimension,
           which can themselves be arrays) are nil. So, for each of the elements in current
           dimension, we recursively call is_nil_valued() on each of the sub-elements to
           find out whether this array is nil valued and return the result.
           */
       } else {
           int ii;

           for (ii=0; ii < extent; ii++) {
               clear_rvalue( base_address, attr, curr_dim + 1, offset * extent + ii);
           }
       }

    } else {
        std::stringstream message;
        message << "This is bad. Remaining dimensions are negative!?.";
        emitError(message.str());
    }
}