Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Now able to process non-abstract methods

Java Eclipsecon Conference 2007 Pack200

It's been a while since I've done much work on the Pack200 codebase; I've spent some time out of the country and had queued up some changes. Now that those are behind me, I can push forwards on the Pack200 implementation.

The good bit of news is that providing a class doesn't have any try/catch/finally blocks, inner classes, debugging information (e.g. line numbers) or annotations, I can now plough through a complete Pack200 file to the bitter end. Right now, I can pull out the 'compressed' bytecodes for each of the non-abstract methods (abstract methods were nailed on the head some time ago) and be able to generate a sensible looking .class file in a Jar as a result. The classes aren't directly usable yet; I'm putting a 'return' bytecode in for each method generated, since Pack200 does weird and wonderful things with the bytecodes and their operands, including replacement of bytecode groups with a single psuedo-bytecode, so it's not just a case of dumping out the data byte-for-byte.

I did spend ages working out how to calculate the number of local fields a method would use. There's a neat way of specifying the data in the Pack200 specification in a single byte:

valuestackNAlocalshandlers
[1..144](x-1)%12(x-1)/120
[145..208](x-1)%8(x-1)/81
[209..255](x-1)%7(x-1)/72

Neat way of compressing it, but I was getting a value for locals reported by 'javap' different to the value I was seeing in NALocals, often with an off-by-one error. Of course, it turned out to be an RTFM situation -- NAlocals stands for non-argument locals, so in actual fact locals = NALocals + numberOfArgs. Not only that, but the limitations of the JVM section of the Class File Format notes that the implicit parameter 'this' is passed for an instance call; so for instance methods, you have to add one to the number of locals.

Perhaps unsurprisingly, all of my off-by-one errors were from instance methods with no arguments (and all of the static methods with no arguments were correct). A quick fix later, and these values now report the correct information.

So, next step; start trying to do reverse compression of the bytecodes and align them with the values in the file. I have a nasty feeling that it will be tricky, since I may have to change how the constant pools are stored/processed; and given that the operands for the bytecodes are split over about 25 different arrays (one for each type) it's going to be fun weaving the bytecodes and operands with each other.

I'm hoping that by the time my Pack200 talk at EclipseCon comes together, I'll be able to decompress a 'helloworld' class packed in a Jar and run it live :-)