[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a bug in soot (coffi)



The relevant section is 2.17.5 "Detailed Initialization Procedure":
...
8. Next, execute either the class variable initializers and static initializers of
   the class or the field initializers of the interface, in textual order, as
-> though they were a single block, *except* that final static variables and fields
   of interfaces whose values are compile-time constants are initialized first.
...

So, you would be possibly changing the initialization order of fields.  Now, is that
an important thing?  I do not have an answer, but I really dislike replacing a
constant value by executable code.  I already feel that the class file format lacks
"constant" arrays and pre-initialized non-constant variables and arrays.

Now, if you take into account "further" compilation of a class ClassA against a
Soot-optimized class ClassOpt, then an important issue arises: If the
compile-time constant fields (e.g. final public static [primitive-type]) of
ClassOpt do not have a ConstantValue attribute, then ClassA will compile accesses to
constants of ClassOpt as GET_STATIC, instead of simply doing an ICONST or LDC.  This
is an important consequence, which violates the Java Language Specification.
I don't have at habd the exact section, but the JLS says that:

class ClassA
{
...
  if (ClassOpt.DEBUG)
  {
    /* then_code */
  }
  else
  {
    /* else_code */
  }
...
}

will be compiled to bytecode that DOES NOT contain any conditional; only one of then_code
or else_code will be included in the class file, depending on the value of ClassA.DEBUG.

So, I really think Soot should not move constant values into <clinit>; it should instead
preserve ConstantValue attributes.

Etienne

Feng Qian wrote:
The constant field represented by the |field_info| structure is assigned the value referenced by its |ConstantValue| attribute as part of the initialization of the class or interface declaring the constant field (§2.17.4) <http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19075>. This occurs immediately prior to the invocation of the class or interface initialization method (§3.9) <http://java.sun.com/docs/books/vmspec/2nd-edition/html/Overview.doc.html#12174> of that class or interface.

Probably it is not as worse as you may think ;-) .

Cheers,
Feng


Etienne Gagnon wrote:


Hi Feng,

Feng Qian wrote:

...
testconstA.java modified
public class testconstA {
public static final z = 7;
}
The solution is to assign the value of ConstantValue attribute to a static field in <clinit> explicitly (create one if no <clinit> exists) before any other real code in original <clinit>...



So, you are saying that you want to change such a class into:


testconstA.java modified again
public class testconstA {
 public static final z;
 static {
  z = 7;
 }
}

I would really prefer that the ConstantValue attribute be preserved
instead of adding an assignment statement.  Execution of static blocks
happen at a later time than initialization of fields with ConstantValue
attributes, according to the JVM spec.  [In other words, constant fields
are initialized with their value before <clinit>() is called].

Etienne





--
Etienne M. Gagnon, Ph.D.             http://www.info.uqam.ca/~egagnon/
SableVM:                                       http://www.sablevm.org/
SableCC:                                       http://www.sablecc.org/