30
30
#include " java_bytecode_convert_method_class.h"
31
31
#include " bytecode_info.h"
32
32
#include " java_types.h"
33
+ #include " java_utils.h"
33
34
#include " java_string_library_preprocess.h"
34
35
35
36
#include < limits>
@@ -106,25 +107,10 @@ static bool operator==(const irep_idt &what, const patternt &pattern)
106
107
return pattern==what;
107
108
}
108
109
109
- const size_t SLOTS_PER_INTEGER (1u );
110
- const size_t INTEGER_WIDTH (64u );
111
- static size_t count_slots (
112
- const size_t value,
113
- const code_typet::parametert ¶m)
114
- {
115
- const std::size_t width (param.type ().get_unsigned_int (ID_width));
116
- return value+SLOTS_PER_INTEGER+width/INTEGER_WIDTH;
117
- }
118
-
119
- static size_t get_variable_slots (const code_typet::parametert ¶m)
120
- {
121
- return count_slots (0 , param);
122
- }
123
-
124
110
static irep_idt strip_java_namespace_prefix (const irep_idt to_strip)
125
111
{
126
112
const auto to_strip_str=id2string (to_strip);
127
- assert (has_prefix (to_strip_str, " java::" ));
113
+ PRECONDITION (has_prefix (to_strip_str, " java::" ));
128
114
return to_strip_str.substr (6 , std::string::npos);
129
115
}
130
116
@@ -308,12 +294,22 @@ void java_bytecode_convert_methodt::convert(
308
294
method_return_type=code_type.return_type ();
309
295
code_typet::parameterst ¶meters=code_type.parameters ();
310
296
297
+ // Determine the number of local variable slots used by the JVM to maintan the
298
+ // formal parameters
299
+ slots_for_parameters = java_method_parameter_slots (code_type);
300
+
301
+ debug () << " Generating codet: class "
302
+ << class_symbol.name << " , method "
303
+ << m.name << eom;
304
+
305
+ // We now set up the local variables for the method parameters
311
306
variables.clear ();
312
307
313
- // find parameter names in the local variable table:
308
+ // Find parameter names in the local variable table:
314
309
for (const auto &v : m.local_variable_table )
315
310
{
316
- if (v.start_pc !=0 ) // Local?
311
+ // Skip this variable if it is not a method parameter
312
+ if (!is_parameter (v))
317
313
continue ;
318
314
319
315
typet t=java_type_from_string (v.signature );
@@ -335,8 +331,10 @@ void java_bytecode_convert_methodt::convert(
335
331
for (const auto ¶m : parameters)
336
332
{
337
333
variables[param_index].resize (1 );
338
- param_index+=get_variable_slots (param);
334
+ param_index+=java_local_variable_slots (param. type () );
339
335
}
336
+ INVARIANT (param_index==slots_for_parameters,
337
+ " java_parameter_count and local computation must agree" );
340
338
341
339
// assign names to parameters
342
340
param_index=0 ;
@@ -348,8 +346,6 @@ void java_bytecode_convert_methodt::convert(
348
346
{
349
347
base_name=" this" ;
350
348
identifier=id2string (method_identifier)+" ::" +id2string (base_name);
351
- param.set_base_name (base_name);
352
- param.set_identifier (identifier);
353
349
}
354
350
else
355
351
{
@@ -364,10 +360,9 @@ void java_bytecode_convert_methodt::convert(
364
360
base_name=" arg" +std::to_string (param_index)+suffix;
365
361
identifier=id2string (method_identifier)+" ::" +id2string (base_name);
366
362
}
367
-
368
- param.set_base_name (base_name);
369
- param.set_identifier (identifier);
370
363
}
364
+ param.set_base_name (base_name);
365
+ param.set_identifier (identifier);
371
366
372
367
// add to symbol table
373
368
parameter_symbolt parameter_symbol;
@@ -377,41 +372,34 @@ void java_bytecode_convert_methodt::convert(
377
372
parameter_symbol.type =param.type ();
378
373
symbol_table.add (parameter_symbol);
379
374
380
- // add as a JVM variable
381
- std::size_t slots=get_variable_slots (param);
375
+ // Add as a JVM local variable
382
376
variables[param_index][0 ].symbol_expr =parameter_symbol.symbol_expr ();
383
377
variables[param_index][0 ].is_parameter =true ;
384
378
variables[param_index][0 ].start_pc =0 ;
385
379
variables[param_index][0 ].length =std::numeric_limits<size_t >::max ();
386
- variables[param_index][0 ].is_parameter =true ;
387
- param_index+=slots;
388
- assert (param_index>0 );
380
+ param_index+=java_local_variable_slots (param.type ());
389
381
}
390
382
383
+ // The parameter slots detected in this function should agree with what
384
+ // java_parameter_count() thinks about this method
385
+ INVARIANT (param_index==slots_for_parameters,
386
+ " java_parameter_count and local computation must agree" );
387
+
391
388
const bool is_virtual=!m.is_static && !m.is_final ;
392
389
393
- #if 0
394
- class_type.methods().push_back(class_typet::methodt());
395
- class_typet::methodt &method=class_type.methods().back();
396
- #else
390
+ // Construct a methodt, which lives within the class type; this object is
391
+ // never used for anything useful and could be removed
397
392
class_typet::methodt method;
398
- #endif
399
-
400
393
method.set_base_name (m.base_name );
401
394
method.set_name (method_identifier);
402
-
403
395
method.set (ID_abstract, m.is_abstract );
404
396
method.set (ID_is_virtual, is_virtual);
405
-
397
+ method. type ()=member_type;
406
398
if (is_constructor (method))
407
399
method.set (ID_constructor, true );
408
400
409
- method.type ()=member_type;
410
-
411
401
// we add the symbol for the method
412
-
413
402
symbolt method_symbol;
414
-
415
403
method_symbol.name =method.get_name ();
416
404
method_symbol.base_name =method.get_base_name ();
417
405
method_symbol.mode =ID_java;
@@ -430,15 +418,13 @@ void java_bytecode_convert_methodt::convert(
430
418
method_symbol.type .set (ID_constructor, true );
431
419
current_method=method_symbol.name ;
432
420
method_has_this=code_type.has_this ();
433
-
434
- tmp_vars.clear ();
435
421
if ((!m.is_abstract ) && (!m.is_native ))
436
- method_symbol.value =convert_instructions (
437
- m, code_type, method_symbol.name );
422
+ method_symbol.value =convert_instructions (m, code_type, method_symbol.name );
438
423
439
424
// Replace the existing stub symbol with the real deal:
440
425
const auto s_it=symbol_table.symbols .find (method.get_name ());
441
- assert (s_it!=symbol_table.symbols .end ());
426
+ INVARIANT (s_it!=symbol_table.symbols .end (),
427
+ " the symbol was there earlier on this function; it must be there now" );
442
428
symbol_table.symbols .erase (s_it);
443
429
444
430
symbol_table.add (method_symbol);
@@ -1138,6 +1124,12 @@ codet java_bytecode_convert_methodt::convert_instructions(
1138
1124
}
1139
1125
}
1140
1126
1127
+ // Clean the list of temporary variables created by a call to `tmp_variable`.
1128
+ // These are local variables in the goto function used to represent temporary
1129
+ // values of the JVM operand stack, newly allocated objects before the
1130
+ // constructor is called, ...
1131
+ tmp_vars.clear ();
1132
+
1141
1133
// Now that the control flow graph is built, set up our local variables
1142
1134
// (these require the graph to determine live ranges)
1143
1135
setup_local_variables (method, address_map);
0 commit comments