Op.Pure and granularity of effects

Hannes Greule hannesgreule at outlook.de
Sat Jan 27 11:55:24 UTC 2024


Hi,

I went through the Ops implementing Op.Pure and noticed that some of 
them aren't pure according to my understanding of "pure".

Namely, FieldLoadOp and ArrayLoadOp can throw exceptions (and 
ArithmethicOperation too, I guess).

Interestingly, the test code in [1] has a similar understanding of 
pureness; It might eliminate expressions that throw exceptions!

I came up with two test cases showcasing the problem:

@Test
public void testAccessField() {
     record MyRecord(int a) {}
     CoreOps.ClosureOp lf = generate((MyRecord myRecord) -> {
         int i = myRecord.a;
         return -2;
     });
     Assert.assertThrows(NullPointerException.class, () -> 
Interpreter.invoke(MethodHandles.lookup(), lf, (Object) null));
}

@Test
public void testArrayLoad() {
     CoreOps.ClosureOp lf = generate((int[] array) -> {
         int i = array[-1];
         return -2;
     });
     Assert.assertThrows(ArrayIndexOutOfBoundsException.class, () -> 
Interpreter.invoke(MethodHandles.lookup(), lf, (Object) new int[0]));
}

I think to tackle that problem, introducing more interfaces (or a method 
that returns a set of side effects) would make analyses easier. For 
example, splitting into "throws exception", "loads from memory", "writes 
to memory" might easy to understand and work with. Everything that 
doesn't describe a side effect this way can considered pure then.

We can go further (which is only possible with interfaces, not with an 
enum) and let an interface describe which exceptions it can throw. This 
could be useful when analysing try-catch blocks.

Please let me know what you think of the problem and the suggestions.

Hannes


[1] 
https://github.com/openjdk/babylon/blob/af40e7d754bc527797dc5c582750dba7c4c9e3af/test/jdk/java/lang/reflect/code/expression/ExpressionElimination.java#L94-L101


More information about the babylon-dev mailing list