> Hi,
>
> I am using javaflow in one of my project to get the continuation
> functionality. I have hit a situation in which I need to call a function
> using reflection which potentially can call suspend. (changing this,
removes
> a few functionality that is already present, hence before changing I want
to
> be sure I have tried everything). I have attached a sample test that
> fails(compilerun.sh runs it, jar paths have to be changed here).
>
> On a high level, I have some fn which has a code as below:
>
> private void callsomeshared()
>         throws Exception
> {
>         Method mthd = _someShared.getDeclaredMethod("doSomething");
>         int cnt = 0;
>         while (cnt < 10)
>         {
>             mthd.invoke(_shared);
>             //Continuation.suspend();
>             cnt++;
>         }
> }
>
> The doSomething does this:
>     public boolean doSomething()
>         throws Exception
>     {
>         if (_shared.value() < 10)
>         {
>             _shared.echo();
>             Continuation.suspend();
>         }
>
>         return (_shared.value() < 10);
>     }
>
> Doing this, fails with a ClassCastException, since when it hits the
> Method.invoke, it is potentially popping out the AnotherLoader class and
> does not have the Method class pushed. I am wondering is it possible that
in
> the push and pops added in the callsomeshared method, if the call is a
> Method.invoke along with the pushReference for this object, we also push
the
> reference and the parameters of the Method.invoke, so that when the
> method.invoke is called again, it potentially acts as if it is a new call
to
> the reflection method, but the reflection method has the push/pop BCI'ed
and
> hence will get handled correctly??
>
> I have tried the following:- (I am using asm for BCI)
> In the ContinuationMethodAdapter, in the function visitMethodInsn I have
> added the following code:
>                 //RS:
>                 if (name.equals("invoke") &&
> owner.startsWith("java/lang/reflect/Method"))
>                 {
>                     System.out.println("method:" + stackRecorderVar + ":"
+
> name + ":" + owner + ":" + desc + ":");
>                     mv.visitVarInsn(ALOAD, stackRecorderVar);
>                     mv.visitVarInsn(ALOAD, 1);
>                     mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER,
> PUSH_METHOD + "Reference", "(Ljava/lang/Object;)V");
>                 }
>                 //RS:
> before the existing pushReference call. Seems to pop and work, but,
> obviously there are problems here:
> 1) Currently I have hardcoded the method variable as ALOAD_1, how can I
get
> which one is this?
> 2) The arguments are not pushed and hence when the method invoke is called
> during continuation, it is giving me a NullPointerException.
>
> Can you help me how these two can be got, so I can try if this idea will
> work for reflection calls?
>
> Thanx
> Rgds
> Raji .S.
>
>

Reply via email to