Fix FELIX-2664 Native methods should not be manipulated


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1023050 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
index 279d00b..41cca2f 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
@@ -1,4 +1,4 @@
-/* 

+/*

  * Licensed to the Apache Software Foundation (ASF) under one

  * or more contributor license agreements.  See the NOTICE file

  * distributed with this work for additional information

@@ -46,7 +46,7 @@
      * Instance Manager Field.

      */

     public static final  String IM_FIELD = "__IM";

-    

+

     /**

      * All POJO method will be renamed by using this prefix.

      */

@@ -73,7 +73,7 @@
     private static final  String ENTRY = "onEntry";

 

     /**

-     * onExit method name. 

+     * onExit method name.

      */

     private static final  String EXIT = "onExit";

 

@@ -83,7 +83,7 @@
     private static final  String ERROR = "onError";

 

     /**

-     * onGet method name. 

+     * onGet method name.

      */

     private static final  String GET = "onGet";

 

@@ -93,7 +93,7 @@
     private static final  String SET = "onSet";

 

     /**

-     * Name of the current manipulated class. 

+     * Name of the current manipulated class.

      */

     private String m_owner;

 

@@ -108,20 +108,20 @@
      * This set contains method id.

      */

     private List m_methods = new ArrayList(); // Contains method id.

-    

+

     /**

      * List of fields injected as method flag in the class.

      * This set contains field name generate from method id.

      */

-    private List m_methodFlags = new ArrayList(); 

-    

+    private List m_methodFlags = new ArrayList();

+

     /**

      * The list of methods visited during the previous analysis.

      * This list allows getting annotations to move to generated

      * method.

      */

     private List m_visitedMethods = new ArrayList();

-    

+

     /**

      * Set to <code>true</code> when a suitable constructor

      * is found. If not set to <code>true</code> at the end

@@ -169,7 +169,7 @@
     /**

      * A method is visited.

      * This method does not manipulate clinit and class$ methods.

-     * In the case of a constructor, this method will generate a constructor with the instance manager 

+     * In the case of a constructor, this method will generate a constructor with the instance manager

      * and will adapt the current constructor to call this constructor.

      * For standard method, this method will create method header, rename the current method and adapt it.

      * @param access : access flag.

@@ -206,21 +206,25 @@
             MethodVisitor mv = super.visitMethod(ACC_PRIVATE, "<init>", newDesc, signature, exceptions);

             return new ConstructorCodeAdapter(mv, m_owner, m_fields, ACC_PRIVATE, name, newDesc, m_superclass);

         }

-        

-        if ((access & ACC_SYNTHETIC) == ACC_SYNTHETIC && name.startsWith("access$")) { 

+

+        if ((access & ACC_SYNTHETIC) == ACC_SYNTHETIC && name.startsWith("access$")) {

             MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);

-            return new MethodCodeAdapter(mv, m_owner, access, name, desc, m_fields); 

+            return new MethodCodeAdapter(mv, m_owner, access, name, desc, m_fields);

         }

 

+        // Do nothing on static methods

         if ((access & ACC_STATIC) == ACC_STATIC) { return super.visitMethod(access, name, desc, signature, exceptions); }

 

+        // Do nothing on native methods

+        if ((access & ACC_NATIVE) == ACC_NATIVE) { return super.visitMethod(access, name, desc, signature, exceptions); }

+

         MethodDescriptor md = getMethodDescriptor(name, desc);

         if (md == null) {

             generateMethodHeader(access, name, desc, signature, exceptions, new ArrayList(0), new HashMap());

         } else {

             generateMethodHeader(access, name, desc, signature, exceptions, md.getAnnotations(), md.getParameterAnnotations());

         }

-        

+

         String id = generateMethodFlag(name, desc);

         if (! m_methodFlags.contains(id)) {

             FieldVisitor flagField = cv.visitField(Opcodes.ACC_PRIVATE, id, "Z", null, null);

@@ -231,10 +235,10 @@
         MethodVisitor mv = super.visitMethod(ACC_PRIVATE, PREFIX + name, desc, signature, exceptions);

         return new MethodCodeAdapter(mv, m_owner, ACC_PRIVATE, PREFIX + name, desc, m_fields);

     }

-    

+

     /**

      * Gets the method descriptor for the specified name and descriptor.

-     * The method descriptor is looked inside the 

+     * The method descriptor is looked inside the

      * {@link MethodCreator#m_visitedMethods}

      * @param name the name of the method

      * @param desc the descriptor of the method

@@ -249,7 +253,7 @@
         }

         return null;

     }

-    

+

     /**

      * Visit a Field.

      * This field access is replaced by an invocation to the getter method or to the setter method.

@@ -308,7 +312,7 @@
         mv.visitInsn(ACONST_NULL);

         mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;)V");

         mv.visitInsn(RETURN);

-   

+

         // Move annotations

         if (annotations != null) {

             for (int i = 0; i < annotations.size(); i++) {

@@ -316,7 +320,7 @@
                 ad.visitAnnotation(mv);

             }

         }

-        

+

         mv.visitMaxs(0, 0);

         mv.visitEnd();

     }

@@ -340,7 +344,7 @@
         mv.visitVarInsn(ALOAD, 1);

         mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;Lorg/osgi/framework/BundleContext;)V");

         mv.visitInsn(RETURN);

-        

+

         // Move annotations

         if (annotations != null) {

             for (int i = 0; i < annotations.size(); i++) {

@@ -366,20 +370,20 @@
      * @param paramAnnotations : the parameter annotations to move to this method.

      */

     private void generateMethodHeader(int access, String name, String desc, String signature, String[] exceptions, List annotations, Map paramAnnotations) {

-        GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc); 

-        

+        GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc);

+

         mv.visitCode();

-        

+

         Type returnType = Type.getReturnType(desc);

 

         // Compute result and exception stack location

         int result = -1;

         int exception = -1;

-        

+

         //int arguments = mv.newLocal(Type.getType((new Object[0]).getClass()));

 

         if (returnType.getSort() != Type.VOID) {

-            // The method returns something 

+            // The method returns something

             result = mv.newLocal(returnType);

             exception = mv.newLocal(Type.getType(Throwable.class));

         } else {

@@ -402,18 +406,18 @@
         mv.visitInsn(returnType.getOpcode(IRETURN));

 

         // end of the non intercepted method invocation.

-        

+

         mv.visitLabel(l0);

-        

+

         mv.visitVarInsn(ALOAD, 0);

         mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

         mv.visitVarInsn(ALOAD, 0);

         mv.visitLdcInsn(generateMethodId(name, desc));

         mv.loadArgArray();

         mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ENTRY, "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");

-        

+

         mv.visitVarInsn(ALOAD, 0);

-            

+

         // Do not allow argument modification : just reload arguments.

         mv.loadArgs();

         mv.visitMethodInsn(INVOKESPECIAL, m_owner, PREFIX + name, desc);

@@ -433,7 +437,7 @@
             mv.visitInsn(ACONST_NULL);

         }

         mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", EXIT, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

-        

+

         mv.visitLabel(l1);

         Label l7 = new Label();

         mv.visitJumpInsn(GOTO, l7);

@@ -454,7 +458,7 @@
             mv.visitVarInsn(returnType.getOpcode(ILOAD), result);

         }

         mv.visitInsn(returnType.getOpcode(IRETURN));

-        

+

         // Move annotations

         if (annotations != null) {

             for (int i = 0; i < annotations.size(); i++) {

@@ -462,7 +466,7 @@
                 ad.visitAnnotation(mv);

             }

         }

-        

+

         // Move parameter annotations

         if (paramAnnotations != null  && ! paramAnnotations.isEmpty()) {

             Iterator ids = paramAnnotations.keySet().iterator();

@@ -568,7 +572,7 @@
 

         // Add the getComponentInstance

         createGetComponentInstanceMethod();

-        

+

         // Need to inject a constructor?

         if (! m_foundSuitableConstructor) { // No adequate constructor, create one.

             createSimpleConstructor();