Analyzer does not use stack map frames
Marcin Rzeźnicki <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I'd like to present here a quick rant :-) on Analyzer class. It seems
not to use information from stack map frames generated by the compiler
(when present) which leads to at least two awkward issues which are
not easy to solve:
- chop frames, if a frame is of F_CHOP type it communicates that
variable goes out of scope. Analyzer does not handle this case
seemingly (from its code I gather that it simply treats FRAME as no-op
and tries to merge current frame with next frame, which is very bad if
you want to know which variables are present at some point of code
(and let's say, generate your stack map frames based on this
information). Consider:
for(T x : collection) { ... } *
Here javac compiler (eclipse compiler differs AFAIK) generates
"hidden" Iterator type variable (usually called i$) which it chops at
*. If you try to generate some stack map frame yourself based on
frames analyzer generated after * then what you see is that some
variable i$ is present. It is misleading and can lead to number of
issues. Let''s say that somewhere after * you have for(T y :
another_collection) { }. Then javac frames may go as follows: append
[Iterator], chop 1, append [Iterator] - if you modify code between
these two loops and try to put correct frame yourself (to restore
state) you may end up with a frame full[.., Iterator] - after which
javac inserted append [Iterator] messes up the whole thing. You can
resolve this by tracking all this yourself but that defeats the
purpose of generic Analyzer because you need to redo much of its work.
- types, Analyzer does not use type information which sometimes makes
impossible to determine the real type of variable. Consider following
code:
List l;
if (sth) l = new ArrayList(); else l = new LinkedList();
javac generates frames append[List], same. Analyzer does not use type
information from stack map frames but delegates determining of correct
type to an Interpreter. But no Interpreter can resolve this issue
fully. Interpreter's merge(Value, Value) is expected to find correct
common supertype and fill this hole. It is not possible in Java where
two types can have any number of overlapping interfaces. In the
example above it is relatively easy to determine that, let's say,
AbstractList is correct but consider: Serializable s if (sth) s = new
ArrayList() else s = new SQLClientInfoException() //sorry for
contrived example :-) - these runtime types share Serializable as well
as Iterable in common and you have no way to determine which one of
these two you should choose.
--
Pozdrawiam
Marcin Rzeźnicki
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws