|
19 | 19 | #include "java_bytecode_convert_method.h"
|
20 | 20 | #include "java_bytecode_language.h"
|
21 | 21 |
|
| 22 | +#include <util/arith_tools.h> |
22 | 23 | #include <util/namespace.h>
|
23 | 24 | #include <util/std_expr.h>
|
24 | 25 |
|
@@ -311,6 +312,122 @@ void java_bytecode_convert_classt::add_array_types()
|
311 | 312 | symbol.is_type=true;
|
312 | 313 | symbol.type=struct_type;
|
313 | 314 | symbol_table.add(symbol);
|
| 315 | + |
| 316 | + // Also provide a clone method: |
| 317 | + // ---------------------------- |
| 318 | + |
| 319 | + const irep_idt clone_name= |
| 320 | + id2string(symbol_type.get_identifier())+".clone:()Ljava/lang/Object;"; |
| 321 | + code_typet clone_type; |
| 322 | + clone_type.return_type()= |
| 323 | + pointer_typet(symbol_typet("java::java.lang.Object")); |
| 324 | + code_typet::parametert this_param; |
| 325 | + this_param.set_identifier(id2string(clone_name)+"::this"); |
| 326 | + this_param.set_base_name("this"); |
| 327 | + this_param.set_this(); |
| 328 | + this_param.type()=pointer_typet(symbol_type); |
| 329 | + clone_type.parameters().push_back(this_param); |
| 330 | + |
| 331 | + parameter_symbolt this_symbol; |
| 332 | + this_symbol.name=this_param.get_identifier(); |
| 333 | + this_symbol.base_name=this_param.get_base_name(); |
| 334 | + this_symbol.pretty_name=this_symbol.base_name; |
| 335 | + this_symbol.type=this_param.type(); |
| 336 | + this_symbol.mode=ID_java; |
| 337 | + symbol_table.add(this_symbol); |
| 338 | + |
| 339 | + const irep_idt local_name= |
| 340 | + id2string(clone_name)+"::cloned_array"; |
| 341 | + auxiliary_symbolt local_symbol; |
| 342 | + local_symbol.name=local_name; |
| 343 | + local_symbol.base_name="cloned_array"; |
| 344 | + local_symbol.pretty_name=local_symbol.base_name; |
| 345 | + local_symbol.type=pointer_typet(symbol_type); |
| 346 | + local_symbol.mode=ID_java; |
| 347 | + symbol_table.add(local_symbol); |
| 348 | + const auto &local_symexpr=local_symbol.symbol_expr(); |
| 349 | + |
| 350 | + code_blockt clone_body; |
| 351 | + |
| 352 | + code_declt declare_cloned(local_symexpr); |
| 353 | + clone_body.move_to_operands(declare_cloned); |
| 354 | + |
| 355 | + side_effect_exprt java_new_array( |
| 356 | + ID_java_new_array, |
| 357 | + pointer_typet(symbol_type)); |
| 358 | + dereference_exprt old_array(this_symbol.symbol_expr(), symbol_type); |
| 359 | + dereference_exprt new_array(local_symexpr, symbol_type); |
| 360 | + member_exprt old_length(old_array, comp1.get_name(), comp1.type()); |
| 361 | + java_new_array.copy_to_operands(old_length); |
| 362 | + code_assignt create_blank(local_symexpr, java_new_array); |
| 363 | + clone_body.move_to_operands(create_blank); |
| 364 | + |
| 365 | + |
| 366 | + member_exprt old_data(old_array, comp2.get_name(), comp2.type()); |
| 367 | + member_exprt new_data(new_array, comp2.get_name(), comp2.type()); |
| 368 | + |
| 369 | + /* |
| 370 | + // TODO use this instead of a loop. |
| 371 | + codet array_copy; |
| 372 | + array_copy.set_statement(ID_array_copy); |
| 373 | + array_copy.move_to_operands(new_data); |
| 374 | + array_copy.move_to_operands(old_data); |
| 375 | + clone_body.move_to_operands(array_copy); |
| 376 | + */ |
| 377 | + |
| 378 | + // Begin for-loop to replace: |
| 379 | + |
| 380 | + const irep_idt index_name= |
| 381 | + id2string(clone_name)+"::index"; |
| 382 | + auxiliary_symbolt index_symbol; |
| 383 | + index_symbol.name=index_name; |
| 384 | + index_symbol.base_name="index"; |
| 385 | + index_symbol.pretty_name=index_symbol.base_name; |
| 386 | + index_symbol.type=comp1.type(); |
| 387 | + index_symbol.mode=ID_java; |
| 388 | + symbol_table.add(index_symbol); |
| 389 | + const auto &index_symexpr=index_symbol.symbol_expr(); |
| 390 | + |
| 391 | + code_declt declare_index(index_symexpr); |
| 392 | + clone_body.move_to_operands(declare_index); |
| 393 | + |
| 394 | + code_fort copy_loop; |
| 395 | + |
| 396 | + copy_loop.init()= |
| 397 | + code_assignt(index_symexpr, from_integer(0, index_symexpr.type())); |
| 398 | + copy_loop.cond()= |
| 399 | + binary_relation_exprt(index_symexpr, ID_lt, old_length); |
| 400 | + |
| 401 | + side_effect_exprt inc(ID_assign); |
| 402 | + inc.operands().resize(2); |
| 403 | + inc.op0()=index_symexpr; |
| 404 | + inc.op1()=plus_exprt(index_symexpr, from_integer(1, index_symexpr.type())); |
| 405 | + copy_loop.iter()=inc; |
| 406 | + |
| 407 | + dereference_exprt old_cell( |
| 408 | + plus_exprt(old_data, index_symexpr), old_data.type().subtype()); |
| 409 | + dereference_exprt new_cell( |
| 410 | + plus_exprt(new_data, index_symexpr), new_data.type().subtype()); |
| 411 | + code_assignt copy_cell(new_cell, old_cell); |
| 412 | + copy_loop.body()=copy_cell; |
| 413 | + |
| 414 | + // End for-loop |
| 415 | + clone_body.move_to_operands(copy_loop); |
| 416 | + |
| 417 | + member_exprt new_base_class(new_array, comp0.get_name(), comp0.type()); |
| 418 | + address_of_exprt retval(new_base_class); |
| 419 | + code_returnt return_inst(retval); |
| 420 | + clone_body.move_to_operands(return_inst); |
| 421 | + |
| 422 | + symbolt clone_symbol; |
| 423 | + clone_symbol.name=clone_name; |
| 424 | + clone_symbol.pretty_name= |
| 425 | + id2string(symbol_type.get_identifier())+".clone:()"; |
| 426 | + clone_symbol.base_name="clone"; |
| 427 | + clone_symbol.type=clone_type; |
| 428 | + clone_symbol.value=clone_body; |
| 429 | + clone_symbol.mode=ID_java; |
| 430 | + symbol_table.add(clone_symbol); |
314 | 431 | }
|
315 | 432 | }
|
316 | 433 |
|
|
0 commit comments