I am trying to decompile a couple of jar files using JAD in Java (I tried JD-GUI as well with even less luck), but I get quite a lot of errors. One type (easy to fix) seems to be with internal classes, but I also found this bit of code:
static int[] $SWITCH_TABLE$atp$com$OrderType()
{
$SWITCH_TABLE$atp$com$OrderType;
if($SWITCH_TABLE$atp$com$OrderType == null) goto _L2; else goto _L1
_L1:
return;
_L2:
JVM INSTR pop ;
int ai[] = new int[OrderType.values().length];
try
{
ai[OrderType.LIMIT.ordinal()] = 2;
}
catch(NoSuchFieldError _ex) { }
try
{
ai[OrderType.MARKET.ordinal()] = 1;
}
catch(NoSuchFieldError _ex) { }
try
{
ai[OrderType.STOP.ordinal()] = 3;
}
catch(NoSuchFieldError _ex) { }
try
{
ai[OrderType.TAKE.ordinal()] = 4;
}
catch(NoSuchFieldError _ex) { }
return $SWITCH_TABLE$atp$com$OrderType = ai;
}
which is used as follows:
switch($SWITCH_TABLE$atp$com$OrderType()[co.getOrderType().ordinal()])
{
case 1: // '\001'
order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker);
break;
case 2: // '\002'
order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker);
break;
case 3: // '\003'
order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker);
break;
}
Any idea what this construct originally could have been?
Looks to me like a switch statement on an enum. Take a look at the enum class, which enums implicitly extend. It has the
ordinal
method that's being used to switch over. There's probably someOrderType
enum with constants LIMIT, MARKET, STOP and TAKE.EDIT: Actually, I'm guessing some more info would be nice. There's some smoke and mirrors being used for stuff like enums. An enum constant gets some ordinal number behind the screens. This ordinal number is what's actually used in a bunch of constructs. When switching over an enum instance, the compiler actually creates a switch over an int (a well-known construct that's been around for a while) with the ordinal number as input.
What happens in your two code blocks is this: the first one sets up a "table" (actually just an array) for the enum ordinals if this didn't happen yet. There's a null check. If the table is null, it'll jump to label
_L2
to do the priming. Otherwise, it jumps to label_L1
that simply returns. The second code block (the actualy switch statement) does a switch on an int. The int is obtained from the table by getting the element at the index that corresponds with the enum constant's ordinal number.It seems a bit odd, but this forms some sort of indirection between the enum ordinals and the values used internally by the switch.
Now, the reason this all looks so low-level instead of simply seeing a switch on an enum is that enums were introduced in JDK 1.5, but JAD has been out of maintenance for a while and only really supports decompilation of source up to 1.4. Seeing how enums were implemented using constructs available in 1.4, the decompilation does actually work, but JAD has no knowledge of enums and as such doesn't make an effort to present this in a more legible manner.
Here's what that second code block probably looked like: