@@ -109,9 +109,11 @@ static bool operator==(const irep_idt &what, const patternt &pattern)
109109
110110static irep_idt strip_java_namespace_prefix (const irep_idt to_strip)
111111{
112- const auto to_strip_str=id2string (to_strip);
113- PRECONDITION (has_prefix (to_strip_str, " java::" ));
114- return to_strip_str.substr (6 , std::string::npos);
112+ const std::string to_strip_str=id2string (to_strip);
113+ const std::string prefix=" java::" ;
114+
115+ PRECONDITION (has_prefix (to_strip_str, prefix));
116+ return to_strip_str.substr (prefix.size (), std::string::npos);
115117}
116118
117119// name contains <init> or <clinit>
@@ -283,20 +285,26 @@ void java_bytecode_convert_methodt::convert(
283285 const symbolt &class_symbol,
284286 const methodt &m)
285287{
288+ // Construct the fully qualified method name
289+ // (e.g. "my.package.ClassName.myMethodName:(II)I") and query the symbol table
290+ // to retrieve the symbol (constructed by java_bytecode_convert_method_lazy)
291+ // associated to the method
286292 const irep_idt method_identifier=
287293 id2string (class_symbol.name )+" ." +id2string (m.name )+" :" +m.signature ;
288294 method_id=method_identifier;
289295
290296 const auto &old_sym=symbol_table.lookup (method_identifier);
291297
298+ // Obtain a std::vector of code_typet::parametert objects from the
299+ // (function) type of the symbol
292300 typet member_type=old_sym.type ;
293301 code_typet &code_type=to_code_type (member_type);
294302 method_return_type=code_type.return_type ();
295303 code_typet::parameterst ¶meters=code_type.parameters ();
296304
297305 // Determine the number of local variable slots used by the JVM to maintan the
298306 // formal parameters
299- slots_for_parameters = java_method_parameter_slots (code_type);
307+ slots_for_parameters= java_method_parameter_slots (code_type);
300308
301309 debug () << " Generating codet: class "
302310 << class_symbol.name << " , method "
@@ -312,49 +320,70 @@ void java_bytecode_convert_methodt::convert(
312320 if (!is_parameter (v))
313321 continue ;
314322
323+ // Construct a fully qualified name for the parameter v,
324+ // e.g. my.package.ClassName.myMethodName:(II)I::anIntParam, and then a
325+ // symbol_exprt with the parameter and its type
315326 typet t=java_type_from_string (v.signature );
316327 std::ostringstream id_oss;
317328 id_oss << method_id << " ::" << v.name ;
318329 irep_idt identifier (id_oss.str ());
319330 symbol_exprt result (identifier, t);
320331 result.set (ID_C_base_name, v.name );
321332
333+ // Create a new variablet in the variables vector; in fact this entry will
334+ // be rewritten below in the loop that iterates through the method
335+ // parameters; the only field that seem to be useful to write here is the
336+ // symbol_expr, others will be rewritten
322337 variables[v.index ].push_back (variablet ());
323338 auto &newv=variables[v.index ].back ();
324339 newv.symbol_expr =result;
325340 newv.start_pc =v.start_pc ;
326341 newv.length =v.length ;
327342 }
328343
329- // set up variables array
344+ // The variables is a expanding_vectort, and the loop above may have expanded
345+ // the vector introducing gaps where the entries are empty vectors. We now
346+ // make sure that the vector of each LV slot contains exactly one variablet,
347+ // possibly default-initialized
330348 std::size_t param_index=0 ;
331349 for (const auto ¶m : parameters)
332350 {
333351 variables[param_index].resize (1 );
334352 param_index+=java_local_variable_slots (param.type ());
335353 }
336- INVARIANT (param_index==slots_for_parameters,
354+ INVARIANT (
355+ param_index==slots_for_parameters,
337356 " java_parameter_count and local computation must agree" );
338357
339- // assign names to parameters
358+ // Assign names to parameters
340359 param_index=0 ;
341360 for (auto ¶m : parameters)
342361 {
343362 irep_idt base_name, identifier;
344363
364+ // Construct a sensible base name (base_name) and a fully qualified name
365+ // (identifier) for every parameter of the method under translation,
366+ // regardless of whether we have an LVT or not; and assign it to the
367+ // parameter object (which is stored in the type of the symbol, not in the
368+ // symbol table)
345369 if (param_index==0 && param.get_this ())
346370 {
371+ // my.package.ClassName.myMethodName:(II)I::this
347372 base_name=" this" ;
348373 identifier=id2string (method_identifier)+" ::" +id2string (base_name);
349374 }
350375 else
351376 {
352- // in the variable table?
377+ // if already present in the LVT ...
353378 base_name=variables[param_index][0 ].symbol_expr .get (ID_C_base_name);
354379 identifier=variables[param_index][0 ].symbol_expr .get (ID_identifier);
355380
381+ // ... then base_name will not be empty
356382 if (base_name.empty ())
357383 {
384+ // my.package.ClassName.myMethodName:(II)I::argNT, where N is the local
385+ // variable slot where the parameter is stored and T is a character
386+ // indicating the type
358387 const typet &type=param.type ();
359388 char suffix=java_char_from_type (type);
360389 base_name=" arg" +std::to_string (param_index)+suffix;
@@ -364,7 +393,7 @@ void java_bytecode_convert_methodt::convert(
364393 param.set_base_name (base_name);
365394 param.set_identifier (identifier);
366395
367- // add to symbol table
396+ // Build a new symbol for the parameter and add it to the symbol table
368397 parameter_symbolt parameter_symbol;
369398 parameter_symbol.base_name =base_name;
370399 parameter_symbol.mode =ID_java;
@@ -382,7 +411,8 @@ void java_bytecode_convert_methodt::convert(
382411
383412 // The parameter slots detected in this function should agree with what
384413 // java_parameter_count() thinks about this method
385- INVARIANT (param_index==slots_for_parameters,
414+ INVARIANT (
415+ param_index==slots_for_parameters,
386416 " java_parameter_count and local computation must agree" );
387417
388418 const bool is_virtual=!m.is_static && !m.is_final ;
@@ -406,6 +436,10 @@ void java_bytecode_convert_methodt::convert(
406436 method_symbol.location =m.source_location ;
407437 method_symbol.location .set_function (method_identifier);
408438
439+ // Set up the pretty name for the method entry in the symbol table.
440+ // The pretty name of a constructor includes the base name of the class
441+ // instead of the internal method name "<init>". For regular methods, it's
442+ // just the base name of the method.
409443 if (method.get_base_name ()==" <init>" )
410444 method_symbol.pretty_name =id2string (class_symbol.pretty_name )+" ." +
411445 id2string (class_symbol.base_name )+" ()" ;
@@ -416,17 +450,20 @@ void java_bytecode_convert_methodt::convert(
416450 method_symbol.type =member_type;
417451 if (is_constructor (method))
418452 method_symbol.type .set (ID_constructor, true );
453+
419454 current_method=method_symbol.name ;
420455 method_has_this=code_type.has_this ();
421456 if ((!m.is_abstract ) && (!m.is_native ))
422457 method_symbol.value =convert_instructions (m, code_type, method_symbol.name );
423458
424459 // Replace the existing stub symbol with the real deal:
425460 const auto s_it=symbol_table.symbols .find (method.get_name ());
426- INVARIANT (s_it!=symbol_table.symbols .end (),
461+ INVARIANT (
462+ s_it!=symbol_table.symbols .end (),
427463 " the symbol was there earlier on this function; it must be there now" );
428464 symbol_table.symbols .erase (s_it);
429465
466+ // Insert the method symbol in the symbol table
430467 symbol_table.add (method_symbol);
431468}
432469
0 commit comments