The rewrite method of the BCEL enhancer checks all the bytecode, and
when it find an INVOKE (or INVOKEVIRTUAL, still studying bytecode) to an
enhanced class (and there are other conditions) it writes the push and
pop instructions, so that if that class suspends the continuation, the
system will be able to restore the proper flow by popping all it needs
from the stack.

Unfortunately it seems like the following instruction :

AbstractContinuable enhancedFlowClass = new MyFlow();
method.invoke(enhancedFlowClass);

which is semantically equivalent, does not get surrounded by pushes and
pops, while if we simply rewrite it without introspection :

enhancedFlowClass.method();

It gets surrounded by stack instructions and then works perfectly.

So, the rewrite method, should do something like :

Is it an INVOKEVIRTUAL? Is it the method "invoke" of the object
"java.lang.Method"? is the first argument a BCEL enhanced class? then i
write pushes and pops as if it is a normal call.

This was my implementation of the behaviour above, but it doesn't work:

if (ins.getInstruction().getOpcode() == Constants.INVOKEVIRTUAL) {
String methodname = ((InvokeInstruction) ins.getInstruction()).getMethodName(method.getConstantPool());
 if ("invoke".equals(methodname)) {
   try {
     insList.delete(ins);
   } catch (TargetLostException e) {
     throw new ClassNotFoundException(e.getMessage(), e);
   }
insList.append(insFactory.createInvoke("org.apache.cocoon.samples.flow.java.SimpleFlow","test", Type.VOID,
                               new Type[] { Type.VOID },
                               Constants.INVOKEVIRTUAL));
 }
}

 Maurizio

Reply via email to