[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/