void java_bytecode_convert_classt::convert(
  symbolt &class_symbol,
  const fieldt &f)
{
  typet field_type=java_type_from_string(f.signature);

  // is this a static field?
  if(f.is_static)
  {
    // Create the symbol; we won't add to the struct type.
    symbolt new_symbol;

    new_symbol.is_static_lifetime=true;
    new_symbol.is_lvalue=true;
    new_symbol.is_state_var=true;
    new_symbol.name=id2string(class_symbol.name)+"."+id2string(f.name);
    new_symbol.base_name=f.name;
    new_symbol.type=field_type;
    new_symbol.pretty_name=id2string(class_symbol.pretty_name)+
      "."+id2string(f.name);
    new_symbol.mode=ID_java;
    new_symbol.is_type=false;
    const namespacet ns(symbol_table);
    new_symbol.value=
      zero_initializer(
        field_type,
        class_symbol.location,
        ns,
        get_message_handler());

    // Do we have the static field symbol already?
    const auto s_it=symbol_table.symbols.find(new_symbol.name);
    if(s_it!=symbol_table.symbols.end())
      symbol_table.symbols.erase(s_it); // erase, we stubbed it

    if(symbol_table.add(new_symbol))
      assert(false && "failed to add static field symbol");
  }
  else
  {
    class_typet &class_type=to_class_type(class_symbol.type);

    class_type.components().push_back(class_typet::componentt());
    class_typet::componentt &component=class_type.components().back();

    component.set_name(f.name);
    component.set_base_name(f.name);
    component.set_pretty_name(f.name);
    component.type()=field_type;

    if(f.is_private)
      component.set_access(ID_private);
    else if(f.is_protected)
      component.set_access(ID_protected);
    else if(f.is_public)
      component.set_access(ID_public);
  }
}
Exemple #2
0
void java_bytecode_parsert::get_class_refs()
{
  // Get the class references for the benefit of a dependency
  // analysis.

  for(const auto &c : constant_pool)
  {
    switch(c.tag)
    {
    case CONSTANT_Class:
      get_class_refs_rec(c.expr.type());
      break;

    case CONSTANT_NameAndType:
      {
        typet t=java_type_from_string(id2string(pool_entry(c.ref2).s));
        get_class_refs_rec(t);
      }
      break;

    default: {}
    }
  }

  for(const auto &m : parse_tree.parsed_class.fields)
  {
    typet t=java_type_from_string(m.signature);
    get_class_refs_rec(t);
  }

  for(const auto &m : parse_tree.parsed_class.methods)
  {
    typet t=java_type_from_string(m.signature);
    get_class_refs_rec(t);
    for(const auto &var : m.local_variable_table)
    {
      typet var_type=java_type_from_string(var.signature);
      get_class_refs_rec(var_type);
    }
  }
}
void java_bytecode_convertt::convert(
  symbolt &class_symbol,
  const fieldt &f)
{
  class_typet &class_type=to_class_type(class_symbol.type);

  typet member_type=java_type_from_string(f.signature);

  class_type.components().push_back(class_typet::componentt());
  class_typet::componentt &component=class_type.components().back();

  component.set_name(f.name);
  component.set_base_name(f.name);
  component.set_pretty_name(f.name);
  component.type()=member_type;
  
  if(f.is_private)
    component.set_access(ID_private);
  else if(f.is_protected)
    component.set_access(ID_protected);
  else if(f.is_public)
    component.set_access(ID_public);

  // is this a static field?
  if(f.is_static)
  {
    // create the symbol
    symbolt new_symbol;

    new_symbol.is_static_lifetime=true;
    new_symbol.is_lvalue=true;
    new_symbol.is_state_var=true;
    new_symbol.name=id2string(class_symbol.name)+"."+id2string(f.name);
    new_symbol.base_name=f.name;
    new_symbol.type=member_type;
    new_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+id2string(f.name);
    new_symbol.mode=ID_java;
    new_symbol.is_type=false;  
    new_symbol.value=gen_zero(member_type);

    if(symbol_table.add(new_symbol))
    {
      error() << "failed to add static field symbol" << eom;
      throw 0;
    }
  }
}
void java_bytecode_convertt::convert(
  symbolt &class_symbol,
  const methodt &m)
{
  class_typet &class_type=to_class_type(class_symbol.type);

  typet member_type=java_type_from_string(m.signature);

  assert(member_type.id()==ID_code);

  const irep_idt method_identifier=
    id2string(class_symbol.name)+"."+id2string(m.name)+":"+m.signature;

  code_typet &code_type=to_code_type(member_type);
  method_return_type=code_type.return_type();
  code_typet::parameterst &parameters=code_type.parameters();

  // do we need to add 'this' as a parameter?
  if(!m.is_static)
  {
    code_typet::parametert this_p;
    const empty_typet empty;
    const pointer_typet object_ref_type(empty);
    this_p.type()=object_ref_type;
    this_p.set_this();
    parameters.insert(parameters.begin(), this_p);
  }

  variables.clear();

  // Do the parameters and locals in the variable table,
  // which is only available when compiled with -g
  for(const auto & v : m.local_variable_table)
  {
    typet t=java_type_from_string(v.signature);
    irep_idt identifier=id2string(method_identifier)+"::"+id2string(v.name);
    symbol_exprt result(identifier, t);
    result.set(ID_C_base_name, v.name);
    variables[v.index].symbol_expr=result;
  }

  // set up variables array
  for(std::size_t i=0, param_index=0;
      i < parameters.size(); ++i)
  {
    variables[param_index];
    param_index+=get_variable_slots(parameters[i]);
  }

  // assign names to parameters
  for(std::size_t i=0, param_index=0;
      i < parameters.size(); ++i)
  {
    irep_idt base_name, identifier;

    if(i==0 && parameters[i].get_this())
    {
      base_name="this";
      identifier=id2string(method_identifier)+"::"+id2string(base_name);
      parameters[i].set_base_name(base_name);
      parameters[i].set_identifier(identifier);
    }
    else
    {
      // in the variable table?
      base_name=variables[param_index].symbol_expr.get(ID_C_base_name);
      identifier=variables[param_index].symbol_expr.get(ID_identifier);
      
      if(base_name.empty())
      {
        const typet &type=parameters[i].type();
        char suffix=java_char_from_type(type);
        base_name="arg"+i2string(param_index)+suffix;
        identifier=id2string(method_identifier)+"::"+id2string(base_name);
      }
      
      parameters[i].set_base_name(base_name);
      parameters[i].set_identifier(identifier);
    }

    // add to symbol table
    parameter_symbolt parameter_symbol;
    parameter_symbol.base_name=base_name;
    parameter_symbol.mode=ID_java;
    parameter_symbol.name=identifier;
    parameter_symbol.type=parameters[i].type();
    symbol_table.add(parameter_symbol);

    // add as a JVM variable
    unsigned slots=get_variable_slots(parameters[i]);
    variables[param_index].symbol_expr=parameter_symbol.symbol_expr();
    param_index+=slots;
  }

  class_type.methods().push_back(class_typet::methodt());
  class_typet::methodt &method=class_type.methods().back();

  method.set_base_name(m.base_name);
  method.set_name(method_identifier);

  const bool is_virtual=!m.is_static && !m.is_final;

  method.set(ID_abstract, m.is_abstract);
  method.set(ID_is_virtual, is_virtual);

  if(is_contructor(method))
    method.set(ID_constructor, true);

  method.type()=member_type;

  // we add the symbol for the method

  symbolt method_symbol;

  method_symbol.name=method.get_name();
  method_symbol.base_name=method.get_base_name();
  method_symbol.mode=ID_java;
  method_symbol.name=method.get_name();
  method_symbol.base_name=method.get_base_name();

  if(method.get_base_name()=="<init>")
    method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+
                              id2string(class_symbol.base_name)+"()";
  else
    method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+
                              id2string(method.get_base_name())+"()";

  method_symbol.type=member_type;
  current_method=method_symbol.name;
  method_has_this=code_type.has_this();

  tmp_vars.clear();
  method_symbol.value=convert_instructions(m.instructions, code_type);
  
  // do we have the method symbol already?
  const auto s_it=symbol_table.symbols.find(method.get_name());
  if(s_it!=symbol_table.symbols.end())
    symbol_table.symbols.erase(s_it); // erase, we stubbed it
    
  symbol_table.add(method_symbol);
}
Exemple #5
0
typet java_type_from_string(const std::string &src)
{
  if(src.empty())
    return nil_typet();

  switch(src[0])
  {
  case '(': // function type
    {
      std::size_t e_pos=src.rfind(')');
      if(e_pos==std::string::npos) return nil_typet();
      code_typet result;
      result.return_type()=
        java_type_from_string(std::string(src, e_pos+1, std::string::npos));
        
      for(std::size_t i=1; i<src.size() && src[i]!=')'; i++)
      {
        code_typet::parametert param;
        
        size_t start=i;
        
        while(i<src.size())
        {
          if(src[i]=='L')
          {
            i=src.find(';', i); // ends on ;
            break;
          }
          else if(src[i]=='[')
            i++;
          else
            break;
        }
        
        std::string sub_str=src.substr(start, i-start+1);
        param.type()=java_type_from_string(sub_str);

        if(param.type().id()==ID_symbol)
          param.type()=java_reference_type(param.type());
        
        result.parameters().push_back(param);
      }
        
      return result;
    }

  case '[': // array type
    {
      if(src.size()<=2) return nil_typet();
      typet subtype=java_type_from_string(src.substr(1, std::string::npos));
      return java_reference_type(java_array_type(subtype));
    }
    
  case 'F': return java_float_type();    
  case 'D': return java_double_type();
  case 'I': return java_int_type();
  case 'C': return java_char_type();
  case 'Z': return java_boolean_type();
  case 'V': return java_void_type();  
  case 'J': return java_long_type();  

  case 'L':
    {
      // ends on ;
      if(src[src.size()-1]!=';') return nil_typet();
      std::string identifier="java::"+src.substr(1, src.size()-2);

      for(unsigned i=0; i<identifier.size(); i++)
        if(identifier[i]=='/') identifier[i]='.';

      reference_typet result;
      result.subtype()=symbol_typet(identifier);

      return result;
    }
  
  default:
    return nil_typet();
  }
}
Exemple #6
0
 const typet type_entry(u2 index)
 {
   return java_type_from_string(id2string(pool_entry(index).s));
 }
Exemple #7
0
exprt::operandst java_build_arguments(
  const symbolt &function,
  code_blockt &init_code,
  symbol_tablet &symbol_table,
  bool assume_init_pointers_not_null,
  unsigned max_nondet_array_length,
  message_handlert &message_handler)
{
  const code_typet::parameterst &parameters=
    to_code_type(function.type).parameters();

  exprt::operandst main_arguments;
  main_arguments.resize(parameters.size());

  for(std::size_t param_number=0;
      param_number<parameters.size();
      param_number++)
  {
    bool is_this=(param_number==0) &&
                 parameters[param_number].get_this();
    bool is_default_entry_point(config.main.empty());
    bool is_main=is_default_entry_point;
    if(!is_main)
    {
      bool named_main=has_suffix(config.main, ".main");
      const typet &string_array_type=
        java_type_from_string("[Ljava.lang.String;");
      bool has_correct_type=
        to_code_type(function.type).return_type().id()==ID_empty &&
        (!to_code_type(function.type).has_this()) &&
        parameters.size()==1 &&
        parameters[0].type().full_eq(string_array_type);
      is_main=(named_main && has_correct_type);
    }

    bool allow_null=(!is_main) && (!is_this) && !assume_init_pointers_not_null;

    main_arguments[param_number]=
      object_factory(
        parameters[param_number].type(),
        init_code,
        allow_null,
        symbol_table,
        max_nondet_array_length,
        function.location,
        message_handler);

    const symbolt &p_symbol=
      symbol_table.lookup(parameters[param_number].get_identifier());

    // record as an input
    codet input(ID_input);
    input.operands().resize(2);
    input.op0()=
      address_of_exprt(
        index_exprt(
          string_constantt(p_symbol.base_name),
          from_integer(0, index_type())));
    input.op1()=main_arguments[param_number];
    input.add_source_location()=function.location;

    init_code.move_to_operands(input);
  }

  return main_arguments;
}