Save This Page
Home » Groovy-1.7.0 » org.codehaus » groovy » runtime » callsite » [javadoc | source]
    1   /*
    2    * Copyright 2003-2007 the original author or authors.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   package org.codehaus.groovy.runtime.callsite;
   17   
   18   import groovy.lang.GroovyObject;
   19   import groovy.lang.GroovyRuntimeException;
   20   import groovy.lang.MetaClassImpl;
   21   import groovy.lang.MetaMethod;
   22   import org.codehaus.groovy.reflection.CachedMethod;
   23   import org.codehaus.groovy.runtime.MetaClassHelper;
   24   import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
   25   
   26   import java.lang.reflect.InvocationTargetException;
   27   import java.lang.reflect.Method;
   28   
   29   /**
   30    * POGO call site
   31    *   meta class - cached
   32    *   method - cached
   33   */
   34   public class PogoMetaMethodSite extends MetaMethodSite {
   35       public PogoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
   36           super(site, metaClass, metaMethod, params);
   37       }
   38   
   39       public Object invoke(Object receiver, Object[] args) throws Throwable {
   40           MetaClassHelper.unwrap(args);
   41           try {
   42               return metaMethod.doMethodInvoke(receiver,  args);
   43           } catch (GroovyRuntimeException gre) {
   44               throw ScriptBytecodeAdapter.unwrap(gre);
   45           }
   46       }
   47   
   48       public Object callCurrent(GroovyObject receiver, Object[] args) throws Throwable {
   49           if(checkCall(receiver, args)) {
   50               try {
   51                   return invoke(receiver,args);
   52               } catch (GroovyRuntimeException gre) {
   53                   throw ScriptBytecodeAdapter.unwrap(gre);
   54               }
   55           } else {
   56               return CallSiteArray.defaultCallCurrent(this, receiver, args);
   57           }
   58       }
   59   
   60       public Object call(Object receiver, Object[] args) throws Throwable {
   61           if(checkCall(receiver, args)) {
   62               try {
   63                   return invoke(receiver,args);
   64               } catch (GroovyRuntimeException gre) {
   65                   throw ScriptBytecodeAdapter.unwrap(gre);
   66               }
   67           } else {
   68               return CallSiteArray.defaultCall(this, receiver, args);
   69           }
   70       }
   71   
   72       protected boolean checkCall(Object receiver, Object[] args) {
   73           try {
   74               return usage.get() == 0
   75                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
   76                  && MetaClassHelper.sameClasses(params, args);
   77           }
   78           catch (NullPointerException e) {
   79               if (receiver == null)
   80                 return false;
   81               throw e;
   82           }
   83           catch (ClassCastException e) {
   84               if (!(receiver instanceof GroovyObject))
   85                 return false;
   86               throw e;
   87           }
   88       }
   89   
   90       protected boolean checkCall(Object receiver) {
   91           try {
   92               return usage.get() == 0
   93                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
   94                  && MetaClassHelper.sameClasses(params);
   95           }
   96           catch (NullPointerException e) {
   97               if (receiver == null)
   98                 return false;
   99               throw e;
  100           }
  101           catch (ClassCastException e) {
  102               if (!(receiver instanceof GroovyObject))
  103                 return false;
  104               throw e;
  105           }
  106       }
  107   
  108       protected boolean checkCall(Object receiver, Object arg1) {
  109           try {
  110               return usage.get() == 0
  111                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
  112                  && MetaClassHelper.sameClasses(params, arg1);
  113           }
  114           catch (NullPointerException e) {
  115               if (receiver == null)
  116                 return false;
  117               throw e;
  118           }
  119           catch (ClassCastException e) {
  120               if (!(receiver instanceof GroovyObject))
  121                 return false;
  122               throw e;
  123           }
  124       }
  125   
  126       protected boolean checkCall(Object receiver, Object arg1, Object arg2) {
  127           try {
  128               return usage.get() == 0
  129                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
  130                  && MetaClassHelper.sameClasses(params, arg1, arg2);
  131           }
  132           catch (NullPointerException e) {
  133               if (receiver == null)
  134                 return false;
  135               throw e;
  136           }
  137           catch (ClassCastException e) {
  138               if (!(receiver instanceof GroovyObject))
  139                 return false;
  140               throw e;
  141           }
  142       }
  143   
  144       protected boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3) {
  145           try {
  146               return usage.get() == 0
  147                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
  148                  && MetaClassHelper.sameClasses(params, arg1, arg2, arg3);
  149           }
  150           catch (NullPointerException e) {
  151               if (receiver == null)
  152                 return false;
  153               throw e;
  154           }
  155           catch (ClassCastException e) {
  156               if (!(receiver instanceof GroovyObject))
  157                 return false;
  158               throw e;
  159           }
  160       }
  161   
  162       protected boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) {
  163           try {
  164               return usage.get() == 0
  165                  && ((GroovyObject)receiver).getMetaClass() == metaClass // metaClass still be valid
  166                  && MetaClassHelper.sameClasses(params, arg1, arg2, arg3, arg4);
  167           }
  168           catch (NullPointerException e) {
  169               if (receiver == null)
  170                 return false;
  171               throw e;
  172           }
  173           catch (ClassCastException e) {
  174               if (!(receiver instanceof GroovyObject))
  175                 return false;
  176               throw e;
  177           }
  178       }
  179   
  180       public static CallSite createPogoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object[] args) {
  181           if (metaMethod.getClass() == CachedMethod.class)
  182             return createCachedMethodSite (site, metaClass, (CachedMethod) metaMethod, params, args);
  183   
  184           return createNonAwareCallSite(site, metaClass, metaMethod, params, args);
  185       }
  186   
  187       private static CallSite createNonAwareCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object[] args) {
  188           if (metaMethod.correctArguments(args) == args) {
  189               if (noWrappers(args)) {
  190                   if (noCoerce(metaMethod,args))
  191                       return new PogoMetaMethodSiteNoUnwrap(site, metaClass, metaMethod, params);
  192                   else {
  193                       return new PogoMetaMethodSiteNoUnwrapNoCoerce(site, metaClass, metaMethod, params);
  194                   }
  195               }
  196           }
  197           return new PogoMetaMethodSite(site, metaClass, metaMethod, params);
  198       }
  199   
  200       public static CallSite createCachedMethodSite(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class[] params, Object[] args) {
  201           if (metaMethod.correctArguments(args) == args) {
  202               if (noWrappers(args)) {
  203                   if (noCoerce(metaMethod,args))
  204                       return new PogoCachedMethodSiteNoUnwrap(site, metaClass, metaMethod, params);
  205                   else {
  206                       return metaMethod.createPogoMetaMethodSite(site, metaClass, params);
  207                   }
  208               }
  209           }
  210           return new PogoCachedMethodSite(site, metaClass, metaMethod, params);
  211       }
  212   
  213       public static class PogoCachedMethodSite extends PogoMetaMethodSite {
  214           final Method reflect;
  215   
  216           public PogoCachedMethodSite(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class[] params) {
  217               super(site, metaClass, metaMethod, params);
  218               reflect = metaMethod.setAccessible();
  219           }
  220   
  221           public Object invoke(Object receiver, Object[] args) throws Throwable {
  222               MetaClassHelper.unwrap(args);
  223               args = metaMethod.coerceArgumentsToClasses(args);
  224               try {
  225                   return reflect.invoke(receiver, args);
  226               } catch (InvocationTargetException e) {
  227                   Throwable cause = e.getCause();
  228                   if (cause instanceof GroovyRuntimeException) {
  229                       throw ScriptBytecodeAdapter.unwrap ((GroovyRuntimeException) cause);
  230                   } else {
  231                       throw cause;
  232                   }
  233               }
  234           }
  235       }
  236   
  237       public static class PogoCachedMethodSiteNoUnwrap extends PogoCachedMethodSite {
  238   
  239           public PogoCachedMethodSiteNoUnwrap(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class params[]) {
  240               super(site, metaClass, metaMethod, params);
  241           }
  242   
  243           public final Object invoke(Object receiver, Object[] args) throws Throwable {
  244               args = metaMethod.coerceArgumentsToClasses(args);
  245               try {
  246                   return reflect.invoke(receiver, args);
  247               } catch (InvocationTargetException e) {
  248                   Throwable cause = e.getCause();
  249                   if (cause instanceof GroovyRuntimeException) {
  250                       throw ScriptBytecodeAdapter.unwrap ((GroovyRuntimeException) cause);
  251                   } else {
  252                       throw cause;
  253                   }
  254               }
  255           }
  256       }
  257   
  258       public static class PogoCachedMethodSiteNoUnwrapNoCoerce extends PogoCachedMethodSite {
  259   
  260           public PogoCachedMethodSiteNoUnwrapNoCoerce(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class params[]) {
  261               super(site, metaClass, metaMethod, params);
  262           }
  263   
  264           public final Object invoke(Object receiver, Object[] args) throws Throwable {
  265               try {
  266                   return reflect.invoke(receiver, args);
  267               } catch (InvocationTargetException e) {
  268                   Throwable cause = e.getCause();
  269                   if (cause instanceof GroovyRuntimeException) {
  270                       throw ScriptBytecodeAdapter.unwrap ((GroovyRuntimeException) cause);
  271                   } else {
  272                       throw cause;
  273                   }
  274               }
  275           }
  276       }
  277   
  278       /**
  279        * Call site where we know there is no need to unwrap arguments
  280        */
  281       public static class PogoMetaMethodSiteNoUnwrap extends PogoMetaMethodSite {
  282   
  283           public PogoMetaMethodSiteNoUnwrap(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
  284               super(site, metaClass, metaMethod, params);
  285           }
  286   
  287           public final Object invoke(Object receiver, Object[] args) throws Throwable {
  288               try {
  289                   return metaMethod.doMethodInvoke(receiver,  args);
  290               } catch (GroovyRuntimeException gre) {
  291                   throw ScriptBytecodeAdapter.unwrap(gre);
  292               }
  293           }
  294       }
  295   
  296       /**
  297        * Call site where we know there is no need neither unwrap nor coerce arguments
  298        */
  299       public static class PogoMetaMethodSiteNoUnwrapNoCoerce extends PogoMetaMethodSite {
  300   
  301           public PogoMetaMethodSiteNoUnwrapNoCoerce(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
  302               super(site, metaClass, metaMethod, params);
  303           }
  304   
  305           public final Object invoke(Object receiver, Object[] args) throws Throwable {
  306               try {
  307                   return metaMethod.invoke(receiver,  args);
  308               } catch (GroovyRuntimeException gre) {
  309                   throw ScriptBytecodeAdapter.unwrap(gre);
  310               }
  311           }
  312       }
  313   }

Save This Page
Home » Groovy-1.7.0 » org.codehaus » groovy » runtime » callsite » [javadoc | source]