i am working on a java’s bytecode project, and need to identify ternary operator and nested ternary operator.
I got two questions
- how to determine an if statement is ternary operator?based on stack variables?
- how to determine an if statement’ s consumed value on stack oprand is a ternary operator’s result
example:
((a>b ? 0 : 1 ) > (a > c ? 10 : 20) ? 100 : 101
here is a full example of ternary operator chain:
source code:
public void ddddd() { int m,k, n, z; Random r = new Random(); boolean p = (r.nextInt() > 100 || (30 > r.nextInt() ? (r.nextInt() > 4000 ? 1 : 0) : (r.nextInt() > 2000 ? 100 : 20)) < (r.nextInt() > 1000 ? 0 : 1)); } structed bytecode:
[
7 astore] java/util/Random var1(1) = <init>(v0) [ 9 aload] java/util/Random var1(1) = (stack_var)var1 [ 11 invokevirtual] I v11 = var1.nextInt() [ 14 bipush] (I)v14 = 100 if { // block_id: 16 16 => 89 parent_id: 0 [ 16 if_icmpgt] v11 > v14 : goto => 85 if_false_block { // block_id: 15 19 => 89 parent_id: 16 [ 19 bipush] (I)v19 = 30 [ 21 aload] java/util/Random var1(1) = (stack_var)var1 [ 23 invokevirtual] I v23 = var1.nextInt() if { // block_id: 9 26 => 64 parent_id: 15 [ 26 if_icmple] v19 <= v23 : goto => 48 if_false_block { // block_id: 8 29 => 45 parent_id: 9 [ 29 aload] java/util/Random var1(1) = (stack_var)var1 [ 31 invokevirtual] I v31 = var1.nextInt() [ 34 sipush] (I)v34 = 4000 if { // block_id: 6 37 => 45 parent_id: 8 [ 37 if_icmple] v31 <= v34 : goto => 44 if_false_block { // block_id: 5 40 => 41 parent_id: 6 [ 40 iconst_1] (I)v40 = 1 [ 41 goto] goto: 66 } if_true_block { // block_id: 4 44 => 45 parent_id: 6 [ 44 iconst_0] (I)v44 = 0 [ 45 goto] goto: 66 } } } if_true_block { // block_id: 7 48 => 64 parent_id: 9 [ 48 aload] java/util/Random var1(1) = (stack_var)var1 [ 50 invokevirtual] I v50 = var1.nextInt() [ 53 sipush] (I)v53 = 2000 if { // block_id: 3 56 => 64 parent_id: 7 [ 56 if_icmple] v50 <= v53 : goto => 64 if_false_block { // block_id: 2 59 => 61 parent_id: 3 [ 59 bipush] (I)v59 = 100 [ 61 goto] goto: 66 } if_true_block { // block_id: 1 64 => 64 parent_id: 3 [ 64 bipush] (I)v64 = 20 } } } } [ 66 aload] java/util/Random var1(1) = (stack_var)var1 [ 68 invokevirtual] I v68 = var1.nextInt() [ 71 sipush] (I)v71 = 1000 if { // block_id: 12 74 => 81 parent_id: 15 [ 74 if_icmple] v68 <= v71 : goto => 81 if_false_block { // block_id: 11 77 => 78 parent_id: 12 [ 77 iconst_0] (I)v77 = 0 [ 78 goto] goto: 82 } if_true_block { // block_id: 10 81 => 81 parent_id: 12 [ 81 iconst_1] (I)v81 = 1 } } if { // block_id: 14 82 => 89 parent_id: 15 [ 82 if_icmpge] v40 >= v77 : goto => 89 [ 85 iconst_1] (I)v85 = 1 [ 86 goto] goto: 90 if_true_block { // block_id: 13 89 => 89 parent_id: 14 [ 89 iconst_0] (I)v89 = 0 } } } } [ 90 istore] I var2(1) = (stack_var)var2 [ 92 return] return
ifstatements have not. The link given by Bohemian actually demonstrates the typical compilation strategy. I don’t know why you say “it’s not relevant” when it is exactly the answer to the question. In fact, I don’t see how your own answer is relevant to the question. There, you discuss whether you can “shrink a nested type of ternary operator into one line” but that was never asked for.