I've been playing with javaflow and noticed the following.
Suppose I have the following code:
File root = new File("data");
This compiles into the following bytecode:
// local variable 0 is "this"
// local variable 1 is "root"
0 new java/io/File
3 dup
4 ldc "data"
6 invokespecial java/io/File/<init>(Ljava/lang/String;)V
9 astore_1
After the instrumentation, this code expands to:
118 ldc "data"
120 aload 2
122 swap
123 invokevirtual o/a/c/j/b/StackRecorder/pushObject...
126 new java/io/File
129 dup
130 aload 2
132 invokevirtual o/a/c/j/b/StackRecorder/popObject...
135 checkcast java/lang/String
138 invokespecial java/io/File/<init>(Ljava/lang/String;)V
141 astore_1
I don't think I understand the instrumentation logic completely, but
from a cursory look, the idea is to evaluate constructor parameters
before the 'new' op (and StackRecorder is used as a temporary place to
store evaluated objects.)
This is actually causing an NPE if I run the above code outside the
continuation environment (because StackRecorder is null.)
So here goes my questions:
Why is this necessary? I'd imagine it's related to restoring/capturing
stack frames when Continuation.suspend is invoked inside a constructor,
but it's not clear to me why we need to handle 'new's/'invokespecial's
differently from, say, 'invokevirtual'.
Also, I noticed that the BcelClassTransformer isn't actually generating
the stack capture/restore code for invokespecial. Is that a TODO? Is
this related to the following line in the TODO file?
o fix unintialized objects for method/constructor calls
--
Kohsuke Kawaguchi
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]