[Soot-list] Re: CFG: RuntimeException: Attempting to push a non-constant cp entry

John Jorgensen jorgnsn at lcd.uregina.ca
Tue Oct 5 02:02:09 EDT 2004


A couple of weeks ago I said I would look into what would be
required for Soot to be able to deal with ldc and ldc_w
instructions which load class literals, so that Soot
could analyze the JDK 1.5.0 libraries.

First, to recap the problem: People analyzing the 1.5 class
library were seeing exceptions because for a Java statement like

  Class c = java.util.LinkedList.class;

the 1.5 release of javac generates code like

  ldc_w   #4; //class java/util/LinkedList

Prior to 1.5, the ldc and ldc_w instructions could only load
numeric and String literals from the constant pool, so
soot.coffi.CFG---which reads class files and turns them into
Soot's internal representation---refuses to deal with the new
variant of ldc.

I naively thought that fixing this would involve minor
adjustments to soot.coffi.CFG.  The naivety arose in part from my
assumption that each class really has a static field containing a
reference to its class structure, so that previous releases of
Soot were implementing

  Class c = java.util.LinkedList.class;

by something straightforward like

  getstatic java.util.LinkedList.class

In that case, I would just have to make it possible for ldc to
put the same reference to a java.lang.Class onto the stack as
getstatic does.

In fact, the code produced by previous compilers is rather more
complicated:

  getstatic     #8; //Field
  class$java$util$LinkedList:Ljava/lang/Class;
  ifnonnull     18
  ldc           #9; //String java.util.LinkedList
  invokestatic  #10; //Method
  class$:(Ljava/lang/String;)Ljava/lang/Class;
  dup
  putstatic     #8; //Field
  class$java$util$LinkedList:Ljava/lang/Class;
  goto          21
  getstatic     #8; //Field
  class$java$util$LinkedList:Ljava/lang/Class;
  astore_0
  aload_0
 
where class$java$util$LinkedList and class$ are an extra field
and method that javac adds to the class being compiled. The extra
method calls java.lang.Class.forName(String) to get a reference
to the class and caches the result in the extra field.

So the changes required for Soot to deal with this aspect
of Java 1.5 are not just having soot.coffi.CFG allow ldc to put a
reference to java.lang.Class on the top of the stack.  A
ClassConstant class probably needs to be added to
jimple---joining StringConstant, IntConstant, etc.---which means
that all the existing ValueSwitches need to be looked at to see
if they need to handle a new case.  I'm not sure how large the
impact on different analyses will be; the one example that I
happen to know about is that exception analyses now need to
reflect the fact that a load of a class literal has the potential
to throw a LinkageError.  

Then jasmin will have to modified to generate the ldc
instructions with class literals.

So, as Ondrej said this morning, the changes will be wide-ranging
and probably need to involve several people (though I believe he
was also thinking about how changes to the Java language, such as
generics, will affect the Java-to-Jimple part of Soot, and most
of those language changes do not affect the bytecode format).  

At least in the case of the ability to load class constants,
though, there is the hope of added precision in return for the
effort: the class constants should make it fairly straightforward
to keep track of the identity of the individual loaded class,
something that was more problematic when the Class reference was
retrieved through a call to Class.forName().


More information about the Soot-list mailing list