Skip to content

Commit b7c741c

Browse files
author
Matthias Güdemann
committed
Move add_array_types to java_utils
1 parent 0618f7d commit b7c741c

File tree

3 files changed

+185
-179
lines changed

3 files changed

+185
-179
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 0 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ class java_bytecode_convert_classt:public messaget
115115
void convert(const classt &c, const overlay_classest &overlay_classes);
116116
void convert(symbolt &class_symbol, const fieldt &f);
117117

118-
// see definition below for more info
119-
static void add_array_types(symbol_tablet &symbol_table);
120-
121118
static bool is_overlay_method(const methodt &method)
122119
{
123120
return method.has_annotation(ID_overlay_method);
@@ -717,182 +714,6 @@ void java_bytecode_convert_classt::convert(
717714
}
718715
}
719716

720-
/// Register in the \p symbol_table new symbols for the objects
721-
/// java::array[X] where X is byte, float, int, char...
722-
void java_bytecode_convert_classt::add_array_types(symbol_tablet &symbol_table)
723-
{
724-
const std::string letters="ijsbcfdza";
725-
726-
for(const char l : letters)
727-
{
728-
symbol_typet symbol_type=
729-
to_symbol_type(java_array_type(l).subtype());
730-
731-
const irep_idt &symbol_type_identifier=symbol_type.get_identifier();
732-
if(symbol_table.has_symbol(symbol_type_identifier))
733-
return;
734-
735-
java_class_typet class_type;
736-
// we have the base class, java.lang.Object, length and data
737-
// of appropriate type
738-
class_type.set_tag(symbol_type_identifier);
739-
// Note that non-array types don't have "java::" at the beginning of their
740-
// tag, and their name is "java::" + their tag. Since arrays do have
741-
// "java::" at the beginning of their tag we set the name to be the same as
742-
// the tag.
743-
class_type.set_name(symbol_type_identifier);
744-
745-
class_type.components().reserve(3);
746-
class_typet::componentt base_class_component(
747-
"@java.lang.Object", symbol_typet("java::java.lang.Object"));
748-
base_class_component.set_pretty_name("@java.lang.Object");
749-
base_class_component.set_base_name("@java.lang.Object");
750-
class_type.components().push_back(base_class_component);
751-
752-
class_typet::componentt length_component("length", java_int_type());
753-
length_component.set_pretty_name("length");
754-
length_component.set_base_name("length");
755-
class_type.components().push_back(length_component);
756-
757-
class_typet::componentt data_component(
758-
"data", java_reference_type(java_type_from_char(l)));
759-
data_component.set_pretty_name("data");
760-
data_component.set_base_name("data");
761-
class_type.components().push_back(data_component);
762-
763-
class_type.add_base(symbol_typet("java::java.lang.Object"));
764-
765-
INVARIANT(
766-
is_valid_java_array(class_type),
767-
"Constructed a new type representing a Java Array "
768-
"object that doesn't match expectations");
769-
770-
symbolt symbol;
771-
symbol.name=symbol_type_identifier;
772-
symbol.base_name=symbol_type.get(ID_C_base_name);
773-
symbol.is_type=true;
774-
symbol.type = class_type;
775-
symbol.mode = ID_java;
776-
symbol_table.add(symbol);
777-
778-
// Also provide a clone method:
779-
// ----------------------------
780-
781-
const irep_idt clone_name=
782-
id2string(symbol_type_identifier)+".clone:()Ljava/lang/Object;";
783-
code_typet::parametert this_param;
784-
this_param.set_identifier(id2string(clone_name)+"::this");
785-
this_param.set_base_name("this");
786-
this_param.set_this();
787-
this_param.type()=java_reference_type(symbol_type);
788-
const code_typet clone_type({this_param}, java_lang_object_type());
789-
790-
parameter_symbolt this_symbol;
791-
this_symbol.name=this_param.get_identifier();
792-
this_symbol.base_name=this_param.get_base_name();
793-
this_symbol.pretty_name=this_symbol.base_name;
794-
this_symbol.type=this_param.type();
795-
this_symbol.mode=ID_java;
796-
symbol_table.add(this_symbol);
797-
798-
const irep_idt local_name=
799-
id2string(clone_name)+"::cloned_array";
800-
auxiliary_symbolt local_symbol;
801-
local_symbol.name=local_name;
802-
local_symbol.base_name="cloned_array";
803-
local_symbol.pretty_name=local_symbol.base_name;
804-
local_symbol.type=java_reference_type(symbol_type);
805-
local_symbol.mode=ID_java;
806-
symbol_table.add(local_symbol);
807-
const auto &local_symexpr=local_symbol.symbol_expr();
808-
809-
code_blockt clone_body;
810-
811-
code_declt declare_cloned(local_symexpr);
812-
clone_body.move_to_operands(declare_cloned);
813-
814-
side_effect_exprt java_new_array(
815-
ID_java_new_array,
816-
java_reference_type(symbol_type));
817-
dereference_exprt old_array(this_symbol.symbol_expr(), symbol_type);
818-
dereference_exprt new_array(local_symexpr, symbol_type);
819-
member_exprt old_length(
820-
old_array, length_component.get_name(), length_component.type());
821-
java_new_array.copy_to_operands(old_length);
822-
code_assignt create_blank(local_symexpr, java_new_array);
823-
clone_body.move_to_operands(create_blank);
824-
825-
member_exprt old_data(
826-
old_array, data_component.get_name(), data_component.type());
827-
member_exprt new_data(
828-
new_array, data_component.get_name(), data_component.type());
829-
830-
/*
831-
// TODO use this instead of a loop.
832-
codet array_copy;
833-
array_copy.set_statement(ID_array_copy);
834-
array_copy.move_to_operands(new_data);
835-
array_copy.move_to_operands(old_data);
836-
clone_body.move_to_operands(array_copy);
837-
*/
838-
839-
// Begin for-loop to replace:
840-
841-
const irep_idt index_name=
842-
id2string(clone_name)+"::index";
843-
auxiliary_symbolt index_symbol;
844-
index_symbol.name=index_name;
845-
index_symbol.base_name="index";
846-
index_symbol.pretty_name=index_symbol.base_name;
847-
index_symbol.type = length_component.type();
848-
index_symbol.mode=ID_java;
849-
symbol_table.add(index_symbol);
850-
const auto &index_symexpr=index_symbol.symbol_expr();
851-
852-
code_declt declare_index(index_symexpr);
853-
clone_body.move_to_operands(declare_index);
854-
855-
code_fort copy_loop;
856-
857-
copy_loop.init()=
858-
code_assignt(index_symexpr, from_integer(0, index_symexpr.type()));
859-
copy_loop.cond()=
860-
binary_relation_exprt(index_symexpr, ID_lt, old_length);
861-
862-
side_effect_exprt inc(ID_assign);
863-
inc.operands().resize(2);
864-
inc.op0()=index_symexpr;
865-
inc.op1()=plus_exprt(index_symexpr, from_integer(1, index_symexpr.type()));
866-
copy_loop.iter()=inc;
867-
868-
dereference_exprt old_cell(
869-
plus_exprt(old_data, index_symexpr), old_data.type().subtype());
870-
dereference_exprt new_cell(
871-
plus_exprt(new_data, index_symexpr), new_data.type().subtype());
872-
code_assignt copy_cell(new_cell, old_cell);
873-
copy_loop.body()=copy_cell;
874-
875-
// End for-loop
876-
clone_body.move_to_operands(copy_loop);
877-
878-
member_exprt new_base_class(
879-
new_array, base_class_component.get_name(), base_class_component.type());
880-
address_of_exprt retval(new_base_class);
881-
code_returnt return_inst(retval);
882-
clone_body.move_to_operands(return_inst);
883-
884-
symbolt clone_symbol;
885-
clone_symbol.name=clone_name;
886-
clone_symbol.pretty_name=
887-
id2string(symbol_type_identifier)+".clone:()";
888-
clone_symbol.base_name="clone";
889-
clone_symbol.type=clone_type;
890-
clone_symbol.value=clone_body;
891-
clone_symbol.mode=ID_java;
892-
symbol_table.add(clone_symbol);
893-
}
894-
}
895-
896717
bool java_bytecode_convert_class(
897718
const java_class_loadert::parse_tree_with_overlayst &parse_trees,
898719
symbol_tablet &symbol_table,

jbmc/src/java_bytecode/java_utils.cpp

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,3 +445,185 @@ const std::unordered_set<std::string> cprover_methods_to_ignore
445445
"endThread",
446446
"getCurrentThreadID"
447447
};
448+
449+
/// Register in the \p symbol_table new symbols for the objects
450+
/// java::array[X] where X is byte, float, int, char...
451+
void add_array_types(symbol_tablet &symbol_table)
452+
{
453+
const std::string letters = "ijsbcfdzaa";
454+
455+
bool use_array_copy = false;
456+
457+
for(const char l : letters)
458+
{
459+
symbol_typet symbol_type = to_symbol_type(java_array_type(l).subtype());
460+
461+
const std::string identifier = use_array_copy
462+
? "java::array[Enum]"
463+
: id2string(symbol_type.get_identifier());
464+
const irep_idt &symbol_type_identifier = identifier;
465+
if(symbol_table.has_symbol(symbol_type_identifier))
466+
return;
467+
468+
java_class_typet class_type;
469+
// we have the base class, java.lang.Object, length and data
470+
// of appropriate type
471+
class_type.set_tag(symbol_type_identifier);
472+
// Note that non-array types don't have "java::" at the beginning of their
473+
// tag, and their name is "java::" + their tag. Since arrays do have
474+
// "java::" at the beginning of their tag we set the name to be the same as
475+
// the tag.
476+
class_type.set_name(symbol_type_identifier);
477+
478+
class_type.components().reserve(3);
479+
class_typet::componentt base_class_component(
480+
"@java.lang.Object", symbol_typet("java::java.lang.Object"));
481+
base_class_component.set_pretty_name("@java.lang.Object");
482+
base_class_component.set_base_name("@java.lang.Object");
483+
class_type.components().push_back(base_class_component);
484+
485+
class_typet::componentt length_component("length", java_int_type());
486+
length_component.set_pretty_name("length");
487+
length_component.set_base_name("length");
488+
class_type.components().push_back(length_component);
489+
490+
class_typet::componentt data_component(
491+
"data", java_reference_type(java_type_from_char(l)));
492+
data_component.set_pretty_name("data");
493+
data_component.set_base_name("data");
494+
class_type.components().push_back(data_component);
495+
496+
class_type.add_base(symbol_typet("java::java.lang.Object"));
497+
498+
INVARIANT(
499+
is_valid_java_array(class_type),
500+
"Constructed a new type representing a Java Array "
501+
"object that doesn't match expectations");
502+
503+
symbolt symbol;
504+
symbol.name = symbol_type_identifier;
505+
symbol.base_name = symbol_type.get(ID_C_base_name);
506+
symbol.is_type = true;
507+
symbol.type = class_type;
508+
symbol.mode = ID_java;
509+
symbol_table.add(symbol);
510+
511+
// Also provide a clone method:
512+
// ----------------------------
513+
514+
const irep_idt clone_name = identifier + +".clone:()Ljava/lang/Object;";
515+
code_typet::parametert this_param;
516+
this_param.set_identifier(id2string(clone_name) + "::this");
517+
this_param.set_base_name("this");
518+
this_param.set_this();
519+
this_param.type() = java_reference_type(symbol_type);
520+
const code_typet clone_type({this_param}, java_lang_object_type());
521+
522+
parameter_symbolt this_symbol;
523+
this_symbol.name = this_param.get_identifier();
524+
this_symbol.base_name = this_param.get_base_name();
525+
this_symbol.pretty_name = this_symbol.base_name;
526+
this_symbol.type = this_param.type();
527+
this_symbol.mode = ID_java;
528+
symbol_table.add(this_symbol);
529+
530+
const irep_idt local_name = id2string(clone_name) + "::cloned_array";
531+
auxiliary_symbolt local_symbol;
532+
local_symbol.name = local_name;
533+
local_symbol.base_name = "cloned_array";
534+
local_symbol.pretty_name = local_symbol.base_name;
535+
local_symbol.type = java_reference_type(symbol_type);
536+
local_symbol.mode = ID_java;
537+
symbol_table.add(local_symbol);
538+
const auto &local_symexpr = local_symbol.symbol_expr();
539+
540+
code_blockt clone_body;
541+
542+
code_declt declare_cloned(local_symexpr);
543+
clone_body.move_to_operands(declare_cloned);
544+
545+
side_effect_exprt java_new_array(
546+
ID_java_new_array, java_reference_type(symbol_type));
547+
dereference_exprt old_array(this_symbol.symbol_expr(), symbol_type);
548+
dereference_exprt new_array(local_symexpr, symbol_type);
549+
member_exprt old_length(
550+
old_array, length_component.get_name(), length_component.type());
551+
java_new_array.copy_to_operands(old_length);
552+
code_assignt create_blank(local_symexpr, java_new_array);
553+
clone_body.move_to_operands(create_blank);
554+
555+
member_exprt old_data(
556+
old_array, data_component.get_name(), data_component.type());
557+
member_exprt new_data(
558+
new_array, data_component.get_name(), data_component.type());
559+
560+
// if(l == 'a' && use_array_copy)
561+
// {
562+
// // TODO use this instead of a loop.
563+
// codet array_copy;
564+
// array_copy.set_statement(ID_array_copy);
565+
// array_copy.move_to_operands(new_data);
566+
// array_copy.move_to_operands(old_data);
567+
// clone_body.move_to_operands(array_copy);
568+
// }
569+
// else
570+
{
571+
// Begin for-loop to replace:
572+
573+
const irep_idt index_name = id2string(clone_name) + "::index";
574+
auxiliary_symbolt index_symbol;
575+
index_symbol.name = index_name;
576+
index_symbol.base_name = "index";
577+
index_symbol.pretty_name = index_symbol.base_name;
578+
index_symbol.type = length_component.type();
579+
index_symbol.mode = ID_java;
580+
symbol_table.add(index_symbol);
581+
const auto &index_symexpr = index_symbol.symbol_expr();
582+
583+
code_declt declare_index(index_symexpr);
584+
clone_body.move_to_operands(declare_index);
585+
586+
code_fort copy_loop;
587+
588+
copy_loop.init() =
589+
code_assignt(index_symexpr, from_integer(0, index_symexpr.type()));
590+
copy_loop.cond() =
591+
binary_relation_exprt(index_symexpr, ID_lt, old_length);
592+
593+
side_effect_exprt inc(ID_assign);
594+
inc.operands().resize(2);
595+
inc.op0() = index_symexpr;
596+
inc.op1() =
597+
plus_exprt(index_symexpr, from_integer(1, index_symexpr.type()));
598+
copy_loop.iter() = inc;
599+
600+
dereference_exprt old_cell(
601+
plus_exprt(old_data, index_symexpr), old_data.type().subtype());
602+
dereference_exprt new_cell(
603+
plus_exprt(new_data, index_symexpr), new_data.type().subtype());
604+
code_assignt copy_cell(new_cell, old_cell);
605+
copy_loop.body() = copy_cell;
606+
607+
// End for-loop
608+
clone_body.move_to_operands(copy_loop);
609+
}
610+
611+
member_exprt new_base_class(
612+
new_array, base_class_component.get_name(), base_class_component.type());
613+
address_of_exprt retval(new_base_class);
614+
code_returnt return_inst(retval);
615+
clone_body.move_to_operands(return_inst);
616+
617+
symbolt clone_symbol;
618+
clone_symbol.name = clone_name;
619+
clone_symbol.pretty_name = identifier + ".clone:()";
620+
clone_symbol.base_name = "clone";
621+
clone_symbol.type = clone_type;
622+
clone_symbol.value = clone_body;
623+
clone_symbol.mode = ID_java;
624+
symbol_table.add(clone_symbol);
625+
626+
if(l == 'a')
627+
use_array_copy = true;
628+
}
629+
}

jbmc/src/java_bytecode/java_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include <unordered_set>
1313

14+
#include <util/arith_tools.h>
1415
#include <util/message.h>
1516
#include <util/std_expr.h>
1617
#include <util/symbol_table.h>
@@ -110,6 +111,8 @@ resolve_inherited_componentt::inherited_componentt get_inherited_component(
110111

111112
bool is_non_null_library_global(const irep_idt &);
112113

114+
void add_array_types(symbol_tablet &symbol_table);
115+
113116
extern const std::unordered_set<std::string> cprover_methods_to_ignore;
114117

115118
#endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H

0 commit comments

Comments
 (0)