baliuka     02/03/03 11:35:57

  Added:       simplestore/src/java/org/apache/commons/simplestore/tools
                        Enhancer.java
  Log:
  Added enchancer for not interface types,
  add BCEL to classpath to compile enchancer
  
  Revision  Changes    Path
  1.1                  
jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/Enhancer.java
  
  Index: Enhancer.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.commons.simplestore.tools;
  
  import org.apache.bcel.classfile.*;
  import org.apache.bcel.generic.*;
  import org.apache.bcel.util.Class2HTML;
  import org.apache.bcel.Repository;
  import org.apache.bcel.util.InstructionFinder;
  
  /**
   *@author     Juozas Baliuka <a href="mailto:[EMAIL PROTECTED]";>
   *      [EMAIL PROTECTED]</a>
   *@version    $Id: Enhancer.java,v 1.1 2002/03/03 19:35:57 baliuka Exp $
   */
  public class Enhancer implements org.apache.bcel.Constants{
      
      static boolean DEBUG = true;
      
      static final String INTERCEPTOR_CLASS = MethodInterceptor.class.getName();
      
      static final  ObjectType BOOLEAN_OBJECT    = new 
ObjectType(Boolean.class.getName());
      static final  ObjectType INTEGER_OBJECT    = new 
ObjectType(Integer.class.getName());
      static final  ObjectType CHARACTER_OBJECT  = new 
ObjectType(Character.class.getName());
      static final  ObjectType BYTE_OBJECT       = new 
ObjectType(Byte.class.getName());
      static final  ObjectType SHORT_OBJECT      = new 
ObjectType(Short.class.getName());
      static final  ObjectType LONG_OBJECT       = new 
ObjectType(Long.class.getName());
      static final  ObjectType DOUBLE_OBJECT     = new 
ObjectType(Double.class.getName());
      static final  ObjectType FLOAT_OBJECT      = new 
ObjectType(Float.class.getName() );
      static final  ObjectType METHOD_OBJECT     = new 
ObjectType(java.lang.reflect.Method.class.getName() );
      static final  ObjectType NUMBER_OBJECT     = new 
ObjectType(Number.class.getName());
      static final  String CONSTRUCTOR_NAME      =  "<init>";
      static final  String FIELD_NAME            =  "h";
      static final  String SOURCE_FILE           =  "<generated>";
      
      private static int addAfterRef( ConstantPoolGen cp ){
          return   cp.addInterfaceMethodref(INTERCEPTOR_CLASS,"afterReturn",
          
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Ljava/lang/Object;ZLjava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;"
 );
      }
      private static int addInvokeSupperRef( ConstantPoolGen cp ){
          return   cp.addInterfaceMethodref(INTERCEPTOR_CLASS,"invokeSuper",
          
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Ljava/lang/Object;)Z");
      }
      
      private static int addBeforeRef(ConstantPoolGen cp){
          return   cp.addInterfaceMethodref(INTERCEPTOR_CLASS,"beforeInvoke",
          
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
          
      }
     
      
      /** Creates a new instance of Enchancer */
      private Enhancer() {
      }
      
      public static Object enhance(Class cls , MethodInterceptor ih) {
          
          return enhance(cls,ih,Thread.currentThread().getContextClassLoader());
      }
      public static Object enhance(Class cls, MethodInterceptor ih,ClassLoader loader) 
{
          
          JavaClass clazz = enhance(cls);
          
          try{
              
              byte b [] = clazz.getBytes();
              java.lang.reflect.Method m =
              ClassLoader.class.getDeclaredMethod("defineClass",
              new Class[]{String.class,byte[].class,int.class,int.class}
              );
              
              boolean flag = m.isAccessible();
              m.setAccessible(true);
              Class result = (Class)m.invoke(loader,new 
Object[]{clazz.getClassName(),b,new Integer(0),new Integer(b.length)});
              m.setAccessible(flag);
              
              java.lang.reflect.Method methods [] = result.getMethods();
              for( int i = 0; i < methods.length; i++ ){
                  try{
                      result.getField("mtd_" + methods[i].getName() + "$" +
                      methods[i].getParameterTypes().length
                      ).set(null,methods[i]);
                  }catch( java.lang.NoSuchFieldException nsfe ){
                  }
              }
              
              
              return result.getConstructor(new Class[]{ MethodInterceptor.class} ).
              newInstance(new Object[]{ih});
              
              
          }catch( Exception e){
              e.printStackTrace();
          }
          return null;
          
      }
      
      private static void addConstructor(ClassGen  cg ){
          
          String parentClass = cg.getSuperclassName();
          InstructionFactory factory = new InstructionFactory(cg);
          ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
          
          InstructionList il = new InstructionList();
          MethodGen costructor  = new MethodGen(ACC_PUBLIC,// access flags
          Type.VOID,// return type
          new Type[] {            // argument types
              new ObjectType(INTERCEPTOR_CLASS)
          }, null, // arg names
          CONSTRUCTOR_NAME, cg.getClassName(), il, cp);
          
          
          il.append( new ALOAD(0));
          il.append( factory.createInvoke(parentClass,CONSTRUCTOR_NAME,Type.VOID ,new 
Type[]{}, INVOKESPECIAL ));
          il.append( new ALOAD(0));
          il.append( new ALOAD(1));
          il.append( factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new 
ObjectType(INTERCEPTOR_CLASS),PUTFIELD));
          il.append( new RETURN() );
          cg.addMethod( getMethod( costructor ) );
          
      }
      private static void addHandlerField(ClassGen  cg){
          
          ConstantPoolGen cp = cg.getConstantPool();
          FieldGen fg = new FieldGen( ACC_PUBLIC ,
          new ObjectType(INTERCEPTOR_CLASS) ,
          FIELD_NAME , cp);
          cg.addField(fg.getField());
          
      }
      
      private static ClassGen getClassGen( String class_name, Class  parentClass){
          
          return new ClassGen( class_name , parentClass.getName(),
          SOURCE_FILE, ACC_PUBLIC , null );
      }
      
      private static JavaClass enhance( Class parentClass )  {
          
          String class_name = parentClass.getName() + "$$FinalImpl";
          JavaClass parent = Repository.lookupClass(parentClass.getName());
          ClassGen  cg = getClassGen(class_name,parentClass);
          ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
          addHandlerField(cg);
          addConstructor(cg);
          int before =  addBeforeRef(cp);
          int after  =  addAfterRef(cp);
          int invokeSuper  = addInvokeSupperRef(cp);
          Method  methods[] = parent.getMethods();
          for( int i = 0 ; i < methods.length; i++ ){
              if(  !methods[i].getName().equals(CONSTRUCTOR_NAME) && (
              ( methods[i].getAccessFlags()& ACC_STATIC ) == 0 ) ){
                  cg.addMethod( generateMethod( methods[i], cg,
                  before, after, invokeSuper ) );
              }
          }
          
          JavaClass jcl = cg.getJavaClass();
          return  jcl;
          
      }
      
      
      private static void addMethodField(String fieldName, ClassGen cg ){
          ConstantPoolGen cp = cg.getConstantPool();
          FieldGen fg = new FieldGen( ACC_PUBLIC | ACC_STATIC  , METHOD_OBJECT , 
fieldName , cp);
          cg.addField(fg.getField());
          
      }
      
      private static int createArgArray(InstructionList    il, InstructionFactory 
factory, ConstantPoolGen cp, Type[] args ){
          int argCount = args.length;
          if( argCount > 5 )
              il.append( new  BIPUSH((byte)argCount) );
          else il.append( new  ICONST((byte)argCount) );
          il.append( new ANEWARRAY( cp.addClass( Type.OBJECT )) );
          int load = 1;
          for(int i = 0; i< argCount; i++) {
              
              il.append( new DUP() );
              if( i > 5 )
                  il.append( new BIPUSH( (byte) i ) );
              else il.append( new ICONST( (byte) i ) );
              if ( args[i] instanceof BasicType  ){
                  if ( args[i].equals( Type.BOOLEAN )  ){
                      il.append( new NEW( cp.addClass( BOOLEAN_OBJECT ) ) );
                      il.append( new DUP() );
                      il.append( new ILOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Boolean.class.getName(),CONSTRUCTOR_NAME, "(Z)V")) );
                  }else  if ( args[i].equals( Type.INT )  ){
                      il.append( new NEW( cp.addClass( INTEGER_OBJECT ) ) );
                      il.append( new DUP() );
                      il.append( new ILOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Integer.class.getName(),CONSTRUCTOR_NAME, "(I)V")) );
                  }else  if ( args[i].equals( Type.CHAR )  ){
                      il.append( new NEW( cp.addClass( CHARACTER_OBJECT ) ) );
                      il.append( new DUP() );
                      il.append( new ILOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Character.class.getName(),CONSTRUCTOR_NAME, "(C)V")) );
                  }else  if ( args[i].equals( Type.BYTE )  ){
                      il.append( new NEW( cp.addClass( BYTE_OBJECT ) ) );
                      il.append( new DUP() );
                      il.append( new ILOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Byte.class.getName(),CONSTRUCTOR_NAME, "(B)V")) );
                  }else  if ( args[i].equals( Type.SHORT )  ){
                      il.append( new NEW( cp.addClass( SHORT_OBJECT ) ));
                      il.append( new DUP() );
                      il.append( new ILOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Short.class.getName(),CONSTRUCTOR_NAME, "(S)V")) );
                  }else  if ( args[i].equals( Type.LONG )  ){
                      il.append( new NEW( cp.addClass( LONG_OBJECT ) ));
                      il.append( new DUP() );
                      il.append( new LLOAD( load  ) );
                      load += 2;
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Long.class.getName(),CONSTRUCTOR_NAME, "(J)V")) );
                  }else  if ( args[i].equals( Type.DOUBLE )  ){
                      il.append( new NEW( cp.addClass( DOUBLE_OBJECT ) ) );
                      il.append( new DUP() );
                      il.append( new DLOAD( load  ) );
                      load += 2;
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Double.class.getName(),CONSTRUCTOR_NAME, "(D)V")) );
                  }else  if ( args[i].equals( Type.FLOAT )  ){
                      il.append( new NEW( cp.addClass( FLOAT_OBJECT ) ));
                      il.append( new DUP() );
                      il.append( new FLOAD( load++ ) );
                      il.append( new 
INVOKESPECIAL(cp.addMethodref(Float.class.getName(),CONSTRUCTOR_NAME, "(F)V")) );
                  }
                  
                  
                  
                  
                  il.append( new AASTORE() );
                  //  il.append( new DUP() );
                  
              }else{
                  il.append( new ALOAD( load++ ) );
                  il.append( new AASTORE() );
              }
          }
          return load;
      }
      private static  Method getMethod(MethodGen mg){
          mg.stripAttributes(true);
          mg.setMaxLocals();
          mg.setMaxStack();
          return mg.getMethod();
      }
      private static InstructionHandle generateReturnValue( InstructionList il, 
InstructionFactory factory, ConstantPoolGen cp, Type returnType, int stack ){
          
          if( returnType.equals(Type.VOID)){
              
              return il.append( new RETURN() );
              
          }
          il.append( new ASTORE( stack  ) );
          il.append( new ALOAD( stack  ) );
          if( returnType instanceof ObjectType ) {
              return il.append( new ARETURN() );
          }else if ( returnType instanceof BasicType  ){
              if ( returnType.equals( Type.BOOLEAN )  ){
                  il.append( new CHECKCAST( cp.addClass( BOOLEAN_OBJECT ) ) );
                  il.append( factory.createInvoke(Boolean.class.getName(),"boolValue",
                  Type.BOOLEAN,new Type[]{},INVOKEVIRTUAL )
                  );
                  return   il.append( new IRETURN());
              }else if (returnType.equals( Type.CHAR )){
                  
                  il.append( new CHECKCAST( cp.addClass( CHARACTER_OBJECT ) ) );
                  il.append( 
factory.createInvoke(Character.class.getName(),"charValue",
                  Type.CHAR,new Type[]{},INVOKEVIRTUAL )
                  );
                  return  il.append( new IRETURN());
              }else if (returnType.equals( Type.LONG )){
                  
                  il.append( new CHECKCAST( cp.addClass( NUMBER_OBJECT ) ) );
                  il.append( factory.createInvoke(Number.class.getName(),"longValue",
                  Type.LONG,new Type[]{},INVOKEVIRTUAL )
                  );
                  return il.append( new LRETURN());
              }else if (returnType.equals( Type.DOUBLE )){
                  
                  il.append( new CHECKCAST( cp.addClass( NUMBER_OBJECT ) ) );
                  il.append( factory.createInvoke(Number.class.getName(),"doubleValue",
                  Type.DOUBLE,new Type[]{},INVOKEVIRTUAL )
                  );
                  return il.append( new DRETURN());
              }else if (returnType.equals( Type.FLOAT )){
                  
                  il.append( new CHECKCAST( cp.addClass( NUMBER_OBJECT ) ) );
                  il.append( 
factory.createInvoke(java.lang.Number.class.getName(),"floatValue",
                  Type.FLOAT,new Type[]{},INVOKEVIRTUAL )
                  );
                  return   il.append( new FRETURN());
              }else {
                  
                  il.append( new CHECKCAST( cp.addClass( NUMBER_OBJECT ) ) );
                  il.append( factory.createInvoke(Number.class.getName(),"intValue",
                  Type.INT,new Type[]{},INVOKEVIRTUAL )
                  );
                  return il.append( new IRETURN());
              }
              
              
              
          }
          return null;
      }
      private static Instruction newWrapper(Type type,ConstantPoolGen cp) {
          
          if ( type instanceof BasicType  ){
              if ( type.equals( Type.BOOLEAN )  ){
                  return new NEW( cp.addClass( BOOLEAN_OBJECT  ) );
                  
              }else  if ( type.equals( Type.INT )  ){
                  return new NEW( cp.addClass( INTEGER_OBJECT  ) );
                  
              }else  if ( type.equals( Type.CHAR )  ){
                  return new NEW( cp.addClass( CHARACTER_OBJECT  ) );
              }else  if ( type.equals( Type.BYTE )  ){
                  return new NEW( cp.addClass( BYTE_OBJECT ));
                  
              }else  if ( type.equals( Type.SHORT )  ){
                  return new NEW( cp.addClass( SHORT_OBJECT ));
              }else  if ( type.equals( Type.LONG )  ){
                  return new NEW( cp.addClass( LONG_OBJECT  ));
              }else  if ( type.equals( Type.DOUBLE )  ){
                  return new NEW( cp.addClass( DOUBLE_OBJECT  ) );
                  
              }else  if ( type.equals( Type.FLOAT )  ){
                  return new NEW( cp.addClass( FLOAT_OBJECT ) );
              }
          }
          
          return null;
          
      }
      
      private static Instruction initWrapper(Type type,ConstantPoolGen cp){
          
          if ( type instanceof BasicType  ){
              if ( type.equals( Type.BOOLEAN )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Boolean.class.getName(),CONSTRUCTOR_NAME, "(Z)V"));
              }else  if ( type.equals( Type.INT )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Integer.class.getName(),CONSTRUCTOR_NAME, "(I)V"));
              }else  if ( type.equals( Type.CHAR )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Character.class.getName(),CONSTRUCTOR_NAME, "(C)V"));
              }else  if ( type.equals( Type.BYTE )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Byte.class.getName(),CONSTRUCTOR_NAME, "(B)V") );
              }else  if ( type.equals( Type.SHORT )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Short.class.getName(),CONSTRUCTOR_NAME, "(S)V") );
              }else  if ( type.equals( Type.LONG )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Long.class.getName(),CONSTRUCTOR_NAME, "(J)V")) ;
              }else  if ( type.equals( Type.DOUBLE )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Double.class.getName(),CONSTRUCTOR_NAME, "(D)V") );
              }else  if ( type.equals( Type.FLOAT )  ){
                  return new 
INVOKESPECIAL(cp.addMethodref(Float.class.getName(),CONSTRUCTOR_NAME, "(F)V")) ;
              }
          }
          
          return null;
          
          
          
          
      }
      
      private static int loadArg(InstructionList il, Type t, int index,int pos ){
          
          
          if( t instanceof BasicType ){
              
              if( t.equals( Type.LONG )) {
                  il.append(new LLOAD( pos ));
                  pos += 2;
                  return pos;
              }else if( t.equals( Type.DOUBLE )){
                  il.append(new DLOAD( pos ));
                  pos += 2;
                  return pos;
              }else if (t.equals( Type.FLOAT )) {
                  il.append(new FLOAD( pos ));
                  return ++pos;
              }else {
                  il.append(new ILOAD( pos ));
                  return ++pos;
              }
          }else{
              il.append(new ALOAD(pos));
              return ++pos;
              
              
          }
          
      }
      private static  Method  generateMethod( Method method,
      ClassGen cg,int before,
      int after, int invokeSuper){
          
          InstructionList    il      = new InstructionList();
          InstructionFactory factory = new InstructionFactory(cg);
          ConstantPoolGen cp = cg.getConstantPool();
          MethodGen mg = new MethodGen(method, cg.getClassName(), cp);
          Type types[] = mg.getArgumentTypes();
          int argCount = types.length;
          
          String fieldName = "mtd_" + method.getName() + "$" + argCount;
          addMethodField( fieldName, cg );
          
          boolean returnsValue = ! mg.getReturnType().equals(Type.VOID);
          
          mg.setAccessFlags(ACC_PUBLIC);
          mg.setInstructionList(il);
          
          InstructionHandle start = il.getStart();
          //  il.append(  new BIPUSH ((byte)argCount) );
          int loaded = createArgArray(il,factory,cp,mg.getArgumentTypes());
          int argArray = loaded;
          il.append( new ASTORE(argArray) );
          il.append( new ALOAD(0) );
          il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new 
ObjectType(INTERCEPTOR_CLASS),GETFIELD));
          il.append( new ALOAD(0) );
          il.append( factory.createGetStatic(cg.getClassName(),fieldName, 
METHOD_OBJECT ) );
          il.append( new ALOAD( argArray  ) );
          il.append( new INVOKEINTERFACE(before,4) );
          int resutFromBefore = ++loaded ;
          il.append( new ASTORE( resutFromBefore ) );
          il.append( new ACONST_NULL() );
          int resultFromSuper = ++loaded;
          il.append( new ASTORE( resultFromSuper ) );
          il.append( new ICONST(0) );
          int superInvoked = ++loaded;
          il.append( new ISTORE( superInvoked ) );
          il.append( new ACONST_NULL() );
          int error = ++loaded;
          il.append( new ASTORE( error  ) );
          il.append( new ALOAD(0) );//this.handler
          il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new 
ObjectType(INTERCEPTOR_CLASS),GETFIELD));
          il.append( new ALOAD(0) );//this
          il.append( factory.createGetStatic(cg.getClassName(),fieldName, 
METHOD_OBJECT ) );
          il.append( new ALOAD(argArray) );
          il.append( new ALOAD(resutFromBefore) );
          il.append( new INVOKEINTERFACE(invokeSuper,5) );
          IFEQ ifInvoke = new IFEQ(null);
          InstructionHandle condition = il.append( ifInvoke );
          il.append( new ICONST(1));
          InstructionHandle ehStart = il.append( new ISTORE( superInvoked ) );// 
Ivoked = true
          Instruction wrapper = newWrapper( mg.getReturnType(),cp );
          if( wrapper != null ){
              ehStart = il.append( wrapper );
              il.append( new DUP() );
          }
          int pos = 1;
          il.append(new ALOAD(0) );//this
          for( int i = 0; i < argCount; i++ ){//load args to stack
              pos = loadArg(il,types[i] , i, pos ) ;
          }
          //invokeSuper
          
          il.append( new INVOKESPECIAL( cp.addMethodref(cg.getSuperclassName(), 
method.getName(),method.getSignature() ) ) );
          if( wrapper != null ){
              il.append( initWrapper(mg.getReturnType(),cp) );
          }
          
          InstructionHandle ehEnd = il.append( new ASTORE(resultFromSuper) );
          //  GOTO gotoHandled = new GOTO(null);
          //   il.append( gotoHandled );
          //      InstructionHandle ehHandled =  il.append( new ASTORE(error + 1) );
          //     il.append( new ALOAD(error + 1) );
          //     il.append( new ALOAD(error));
          InstructionHandle endif = il.append( new ALOAD(0) );//this
          ifInvoke.setTarget(endif);
          //     gotoHandled.setTarget(endif);
          il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new 
ObjectType(INTERCEPTOR_CLASS),GETFIELD));
          il.append( new ALOAD(0) );//this
          il.append( factory.createGetStatic(cg.getClassName(),fieldName,METHOD_OBJECT 
) );
          il.append( new ALOAD(argArray) );
          il.append( new ALOAD(resutFromBefore) );
          il.append( new ILOAD(superInvoked) );
          il.append( new ALOAD(resultFromSuper) );
          il.append( new ALOAD(error) );
          il.append( new INVOKEINTERFACE(after,8) );
          
          
          InstructionHandle exitMethod =  
generateReturnValue(il,factory,cp,mg.getReturnType(),++loaded);
          // bug in BCEL ?
          // mg.addExceptionHandler(ehStart,ehEnd,ehHandled,Type.THROWABLE);
          
          mg.setMaxStack();
          mg.setMaxLocals();
          Method result = getMethod(mg);
          if( DEBUG ){
           System.err.println(mg.getMethod());
           System.err.println(mg.getMethod().getCode());
           System.err.flush();
          }
          
          return result;
      }
      
      
      
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to