Skip to content

Commit 56b7266

Browse files
author
owen-jones-diffblue
authored
Merge pull request #2947 from owen-jones-diffblue/doc/overlay-classes
Add brief documentation of overlay classes
2 parents 5d8326f + 4130006 commit 56b7266

File tree

9 files changed

+104
-7
lines changed

9 files changed

+104
-7
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.cprover;
2+
3+
/**
4+
* Ignored methods are documented above
5+
* `java_bytecode_convert_classt::is_ignored_method`.
6+
*/
7+
public @interface IgnoredMethodImplementation {
8+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
package org.cprover;
22

3+
/**
4+
* Overlay classes are documented above `is_overlay_class()` in
5+
* jbmc/src/java_bytecode/java_class_loader.cpp.
6+
*/
37
public @interface OverlayClassImplementation {
48
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
package org.cprover;
22

3+
/**
4+
* Overlay methods are documented above
5+
* `java_bytecode_convert_classt::is_overlay_method`.
6+
*/
37
public @interface OverlayMethodImplementation {
48
}
Binary file not shown.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import org.cprover.OverlayClassImplementation;
2+
import org.cprover.IgnoredMethodImplementation;
3+
4+
@OverlayClassImplementation
5+
public class Test
6+
{
7+
@IgnoredMethodImplementation
8+
public static void main(String[] args)
9+
{
10+
assert(true);
11+
}
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
Test.class
3+
--classpath `../../../../scripts/format_classpath.sh . annotations . ignored-method` --verbosity 10
4+
^Ignoring method: 'java::Test\.main:\(\[Ljava/lang/String;\)V'$
5+
^VERIFICATION FAILED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
^Skipping class Test marked with OverlayClassImplementation but found before original definition$
10+
^Adding symbol from overlay class: method 'java::Test\.main:\(\[Ljava/lang/String;\)V'$

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,44 @@ class java_bytecode_convert_classt:public messaget
118118
// see definition below for more info
119119
static void add_array_types(symbol_tablet &symbol_table);
120120

121+
/// Check if a method is an overlay method by searching for
122+
/// `ID_overlay_method` in its list of annotations.
123+
///
124+
/// An overlay method is a method with the annotation
125+
/// \@OverlayMethodImplementation. They should only appear in
126+
/// [overlay classes](\ref java_class_loader.cpp::is_overlay_class). They
127+
/// will be loaded by JBMC instead of the method with the same signature
128+
/// in the underlying class. It is an error if there is no method with the
129+
/// same signature in the underlying class. It is an error if a method in
130+
/// an overlay class has the same signature as a method in the underlying
131+
/// class and it isn't marked as an overlay method or an
132+
/// [ignored method](\ref java_bytecode_convert_classt::is_ignored_method).
133+
///
134+
/// \param method: a `methodt` object from a java bytecode parse tree
135+
/// \return true if the method is an overlay method, else false
121136
static bool is_overlay_method(const methodt &method)
122137
{
123138
return method.has_annotation(ID_overlay_method);
124139
}
125140

141+
/// Check if a method is an ignored method by searching for
142+
/// `ID_ignored_method` in its list of annotations.
143+
///
144+
/// An ignored method is a method with the annotation
145+
/// \@IgnoredMethodImplementation. They will be ignored by JBMC. They are
146+
/// intended for use in
147+
/// [overlay classes](\ref java_class_loader.cpp::is_overlay_class), in
148+
/// particular for methods which must exist in the overlay class so that
149+
/// it will compile, e.g. default constructors, but which we do not want
150+
/// to overlay the corresponding method in the
151+
/// underlying class. It is an error if a method in
152+
/// an overlay class has the same signature as a method in the underlying
153+
/// class and it isn't marked as an
154+
/// [overlay method](\ref java_bytecode_convert_classt::is_overlay_method)
155+
/// or an ignored method.
156+
///
157+
/// \param method: a `methodt` object from a java bytecode parse tree
158+
/// \return true if the method is an ignored method, else false
126159
static bool is_ignored_method(const methodt &method)
127160
{
128161
return method.has_annotation(ID_ignored_method);
@@ -468,11 +501,16 @@ void java_bytecode_convert_classt::convert(
468501
{
469502
for(const methodt &method : overlay_class.get().methods)
470503
{
471-
if(is_ignored_method(method))
472-
continue;
473504
const irep_idt method_identifier =
474505
qualified_classname + "." + id2string(method.name)
475506
+ ":" + method.descriptor;
507+
if(is_ignored_method(method))
508+
{
509+
debug()
510+
<< "Ignoring method: '" << method_identifier << "'"
511+
<< eom;
512+
continue;
513+
}
476514
if(method_bytecode.contains_method(method_identifier))
477515
{
478516
// This method has already been discovered and added to method_bytecode
@@ -511,11 +549,16 @@ void java_bytecode_convert_classt::convert(
511549
}
512550
for(const methodt &method : c.methods)
513551
{
514-
if(is_ignored_method(method))
515-
continue;
516552
const irep_idt method_identifier=
517553
qualified_classname + "." + id2string(method.name)
518554
+ ":" + method.descriptor;
555+
if(is_ignored_method(method))
556+
{
557+
debug()
558+
<< "Ignoring method: '" << method_identifier << "'"
559+
<< eom;
560+
continue;
561+
}
519562
if(method_bytecode.contains_method(method_identifier))
520563
{
521564
// This method has already been discovered while parsing an overlay

jbmc/src/java_bytecode/java_class_loader.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,25 @@ java_class_loadert::parse_tree_with_overlayst &java_class_loadert::operator()(
6969
}
7070

7171
/// Check if class is an overlay class by searching for `ID_overlay_class` in
72-
/// its list of annotations. TODO(nathan) give a short explanation about what
73-
/// overlay classes are.
74-
/// \param c: a `classt` object from a java byte code parse tree
72+
/// its list of annotations.
73+
///
74+
/// An overlay class is a class with the annotation
75+
/// \@OverlayClassImplementation. They serve the following purpose. When the JVM
76+
/// searches the classpath for a particular class, it uses the first match,
77+
/// and ignores any later matches. JBMC, however, will take account of later
78+
/// matches as long as they are overlay classes. The
79+
/// first match is then referred to as the underlying class. The
80+
/// overlay classes can change the methods of the underlying class in the
81+
/// following ways: adding a field (by having a new field), adding a method
82+
/// (by having a new method) or
83+
/// [changing the definition of a method](\ref java_bytecode_convert_classt::is_overlay_method).
84+
/// It is an error if a method in an overlay class has the same signature as
85+
/// a method in the underlying class and it isn't marked as an
86+
/// [overlay method](\ref java_bytecode_convert_classt::is_overlay_method)
87+
/// or an
88+
/// [ignored method](\ref java_bytecode_convert_classt::is_ignored_method).
89+
///
90+
/// \param c: a `classt` object from a java bytecode parse tree
7591
/// \return true if parsed class is an overlay class, else false
7692
static bool is_overlay_class(const java_bytecode_parse_treet::classt &c)
7793
{

0 commit comments

Comments
 (0)