Skip to content

Commit 1e68ad2

Browse files
committed
Documentation: functionality around setup_local_variables
- The commit also contains some lightweight code style changes and a function has been renamed
1 parent 0968e93 commit 1e68ad2

5 files changed

+163
-56
lines changed

src/java_bytecode/java_bytecode_convert_method.cpp

+48-11
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,11 @@ static bool operator==(const irep_idt &what, const patternt &pattern)
109109

110110
static 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 &parameters=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 &param : 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 &param : 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

src/java_bytecode/java_bytecode_convert_method_class.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,18 @@ class java_bytecode_convert_methodt:public messaget
6262
const size_t max_array_length;
6363
safe_pointer<ci_lazy_methodst> lazy_methods;
6464

65+
/// Fully qualified name of the method under translation.
66+
/// Initialized by `convert`.
67+
/// Example: "my.package.ClassName.myMethodName:(II)I"
6568
irep_idt method_id;
69+
70+
/// A copy of `method_id` :/
6671
irep_idt current_method;
72+
73+
/// Return type of the method under conversion.
74+
/// Initialized by `convert`.
6775
typet method_return_type;
76+
6877
java_string_library_preprocesst &string_preprocess;
6978

7079
/// Number of local variable slots used by the JVM to pass parameters upon
@@ -100,7 +109,7 @@ class java_bytecode_convert_methodt:public messaget
100109
variablet() : symbol_expr(), start_pc(0), length(0), is_parameter(false) {}
101110
};
102111

103-
protected:
112+
protected:
104113
typedef std::vector<variablet> variablest;
105114
expanding_vectort<variablest> variables;
106115
std::set<symbol_exprt> used_local_names;
@@ -154,14 +163,16 @@ class java_bytecode_convert_methodt:public messaget
154163
void pop_residue(std::size_t n);
155164
void push(const exprt::operandst &o);
156165

166+
/// Determines whether the `method` is a constructor or a static initializer,
167+
/// by checking whether its name equals either <init> or <clinit>
157168
bool is_constructor(const class_typet::methodt &method);
158169

159170
/// Returns true iff the slot index of the local variable of a method (coming
160171
/// from the LVT) is a parameter of that method. Assumes that
161172
/// `slots_for_parameters` is initialized upon call.
162173
bool is_parameter(const local_variablet &v)
163174
{
164-
return v.index < slots_for_parameters;
175+
return v.index<slots_for_parameters;
165176
}
166177

167178
struct converted_instructiont
@@ -186,12 +197,12 @@ class java_bytecode_convert_methodt:public messaget
186197
java_cfg_dominatorst;
187198

188199
protected:
189-
void find_initialisers(
200+
void find_initializers(
190201
local_variable_table_with_holest &vars,
191202
const address_mapt &amap,
192203
const java_cfg_dominatorst &doms);
193204

194-
void find_initialisers_for_slot(
205+
void find_initializers_for_slot(
195206
local_variable_table_with_holest::iterator firstvar,
196207
local_variable_table_with_holest::iterator varlimit,
197208
const address_mapt &amap,

src/java_bytecode/java_bytecode_language.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ bool java_bytecode_languaget::typecheck(
401401
if(c_it->second.parsed_class.name.empty())
402402
continue;
403403

404-
debug() << "Converting class " << c_it->first << eom;
404+
debug() << "Generating class/member symbols: " << c_it->first << eom;
405405

406406
if(java_bytecode_convert_class(
407407
c_it->second,

0 commit comments

Comments
 (0)