Skip to content

Commit 4d48e6a

Browse files
Adds summary for remove_exceptions.
1 parent 4bca13b commit 4d48e6a

File tree

1 file changed

+153
-2
lines changed

1 file changed

+153
-2
lines changed

jbmc/src/java_bytecode/README.md

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,160 @@ for(tmp_index = 0; tmp_index < dim_size; ++tmp_index)
248248

249249
`remove_java_new` is then recursively applied to the new `subarray`.
250250

251-
\section java-bytecode-remove-exceptions remove_exceptions
251+
\section java-bytecode-remove-exceptions Remove exceptions
252252

253-
To be documented.
253+
When `remove_exceptions` is called on the goto model, the goto model contains
254+
complex instructions such as `CATCH-POP`, `CATCH-PUSH` and `THROW`. In order to
255+
analyze the goto model, the instructions must be simplified to use more basic
256+
instructions - this is called "lowering". This class lowers the `CATCH` and
257+
`THROW` instructions.
258+
259+
Exceptions that have been thrown, but not yet caught are stored the global
260+
`@inflight_exception`. When they have been caught, the global
261+
`@inflight_exception` is set back to null and ready for the next exception.
262+
263+
\subsection Throw
264+
265+
Consider a simple method `testException(I)V`:
266+
267+
```java
268+
public void testException(int i) throws Exception {
269+
if (i < 0) {
270+
throw new Exception();
271+
}
272+
field = i;
273+
}
274+
```
275+
276+
The goto for `testException(I)V` before `remove_exceptions` (removing comments
277+
and replacing irrelevant parts with `...`) is:
278+
279+
```
280+
com.diffblue.regression.TestExceptions.testException(int) /* java::com.diffblue.regression.TestExceptions.testException:(I)V */
281+
IF i >= 0 THEN GOTO 3
282+
struct java.lang.Exception *new_tmp0;
283+
new_tmp0 = new struct java.lang.Exception;
284+
IF !(new_tmp0 == null) THEN GOTO 1
285+
286+
...
287+
288+
1: SKIP
289+
new_tmp0 . java.lang.Exception.<init>:()V();
290+
291+
...
292+
293+
2: SKIP
294+
THROW: throw(new_tmp0)
295+
dead new_tmp0;
296+
297+
...
298+
299+
```
300+
where there is a `THROW` instruction to be replaced.
301+
302+
After passing the goto model through `remove_exceptions`, it is:
303+
304+
```
305+
com.diffblue.regression.TestExceptions.testException(int) /* java::com.diffblue.regression.TestExceptions.testException:(I)V */
306+
IF i >= 0 THEN GOTO 4
307+
struct java.lang.Exception *new_tmp0;
308+
new_tmp0 = new struct java.lang.Exception;
309+
IF !(new_tmp0 == null) THEN GOTO 1
310+
311+
...
312+
313+
1: new_tmp0 . java.lang.Exception.<init>:()V();
314+
IF @inflight_exception == null THEN GOTO 2 // it is because we've not used it yet
315+
316+
...
317+
318+
2: IF !(new_tmp0 == null) THEN GOTO 3
319+
320+
...
321+
322+
3: @inflight_exception = (void *)new_tmp0;
323+
dead new_tmp0;
324+
325+
...
326+
327+
```
328+
where now instead of the instruction `THROW`, the global variable
329+
`@inflight_exception` holds the thrown exception in ia separate goto statement.
330+
331+
\subsection Catch
332+
333+
Consider the method `catchSomething(I)V` that tries the above method `testException(I)V` and catches the exception:
334+
335+
```java
336+
public void catchSomething(int i) {
337+
try {
338+
testException(i);
339+
} catch (Exception e) {
340+
}
341+
}
342+
```
343+
344+
The goto model before `remove_exceptions` is:
345+
```
346+
com.diffblue.regression.TestExceptions.catchSomething(int) /* java::com.diffblue.regression.TestExceptions.catchSomething:(I)V */
347+
348+
...
349+
350+
CATCH-PUSH ->2
351+
352+
...
353+
354+
1: SKIP
355+
this . com.diffblue.regression.TestExceptions.testException:(I)V(i);
356+
CATCH-POP
357+
GOTO 3
358+
2: void *anonlocal::2a;
359+
struct java.lang.Exception *caught_exception_tmp0;
360+
EXCEPTION LANDING PAD (struct java.lang.Exception * caught_exception_tmp0)
361+
anonlocal::2a = (void *)caught_exception_tmp0;
362+
dead caught_exception_tmp0;
363+
dead anonlocal::2a;
364+
365+
...
366+
367+
```
368+
which contains `CATCH` instructions that are intended to be replaced.
369+
370+
After `remove_exceptions` the goto model is:
371+
372+
```
373+
com.diffblue.regression.TestExceptions.catchSomething(int) /* java::com.diffblue.regression.TestExceptions.catchSomething:(I)V */
374+
375+
...
376+
377+
this . com.diffblue.regression.TestExceptions.testException:(I)V(i);
378+
IF @inflight_exception == null THEN GOTO 3 // true if testException does not throw, method terminates normally
379+
IF !(@inflight_exception == null) THEN GOTO 1 // true if testException throws, enters catch block
380+
381+
...
382+
383+
1: __CPROVER_string class_identifier_tmp;
384+
class_identifier_tmp = ((struct java.lang.Object *)@inflight_exception)->@class_identifier;
385+
instanceof_result_tmp = class_identifier_tmp == "java::java.lang.Exception" || ... ; // TRUE
386+
dead class_identifier_tmp;
387+
2: IF instanceof_result_tmp THEN GOTO 4
388+
389+
...
390+
391+
3: ASSERT false // block 3
392+
GOTO 5
393+
4: void *anonlocal::2a; // The catch block
394+
struct java.lang.Exception *caught_exception_tmp0;
395+
ASSERT false // block 4
396+
caught_exception_tmp0 = (struct java.lang.Exception *)@inflight_exception;
397+
@inflight_exception = null;
398+
anonlocal::2a = (void *)caught_exception_tmp0;
399+
dead caught_exception_tmp0;
400+
dead anonlocal::2a;
401+
5: ASSERT false // block 5
402+
6: END_FUNCTION
403+
```
404+
where the `CATCH` instructions have been replaced with new goto statements.
254405

255406
\section java-bytecode-remove-instanceof Remove instanceof
256407

0 commit comments

Comments
 (0)