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.GroovyRuntimeException;
19 import groovy.lang.MetaClassImpl;
20 import groovy.lang.MetaMethod;
21 import org.codehaus.groovy.runtime.MetaClassHelper;
22 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
23 import org.codehaus.groovy.reflection.CachedMethod;
24
25 /**
26 * POJO call site
27 * meta class - cached
28 * method - cached
29 *
30 * @author Alex Tkachman
31 */
32 public class StaticMetaMethodSite extends MetaMethodSite {
33 private final int version;
34
35 public StaticMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
36 super(site, metaClass, metaMethod, params);
37 version = metaClass.getVersion ();
38 }
39
40 public Object invoke(Object receiver, Object[] args) throws Throwable {
41 MetaClassHelper.unwrap(args);
42 try {
43 return metaMethod.doMethodInvoke(receiver, args);
44 } catch (GroovyRuntimeException gre) {
45 throw ScriptBytecodeAdapter.unwrap(gre);
46 }
47 }
48
49 protected final boolean checkCall(Object receiver, Object[] args) {
50 return receiver == metaClass.getTheClass() // meta class match receiver
51 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
52 && MetaClassHelper.sameClasses(params, args);
53 }
54
55 protected final boolean checkCall(Object receiver) {
56 return receiver == metaClass.getTheClass() // meta class match receiver
57 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
58 && MetaClassHelper.sameClasses(params);
59 }
60
61 protected final boolean checkCall(Object receiver, Object arg1) {
62 return receiver == metaClass.getTheClass() // meta class match receiver
63 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
64 && MetaClassHelper.sameClasses(params, arg1);
65 }
66
67 protected final boolean checkCall(Object receiver, Object arg1, Object arg2) {
68 return receiver == metaClass.getTheClass() // meta class match receiver
69 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
70 && MetaClassHelper.sameClasses(params, arg1, arg2);
71 }
72
73 protected final boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3) {
74 return receiver == metaClass.getTheClass() // meta class match receiver
75 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
76 && MetaClassHelper.sameClasses(params, arg1, arg2, arg3);
77 }
78
79 protected final boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) {
80 return receiver == metaClass.getTheClass() // meta class match receiver
81 && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid
82 && MetaClassHelper.sameClasses(params, arg1, arg2, arg3, arg4);
83 }
84
85 public Object call(Object receiver, Object[] args) throws Throwable {
86 if(checkCall(receiver, args)) {
87 try {
88 return invoke(receiver, args);
89 } catch (GroovyRuntimeException gre) {
90 throw ScriptBytecodeAdapter.unwrap(gre);
91 }
92 } else {
93 return CallSiteArray.defaultCall(this, receiver, args);
94 }
95 }
96
97 public Object callStatic(Class receiver, Object[] args) throws Throwable {
98 if(checkCall(receiver, args))
99 return invoke(receiver, args);
100 else
101 return CallSiteArray.defaultCallStatic(this, receiver, args);
102 }
103
104 public static CallSite createStaticMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object[] args) {
105 if (metaMethod.correctArguments(args) == args) {
106 if (noWrappers(args)) {
107 if (noCoerce(metaMethod,args))
108 return new StaticMetaMethodSiteNoUnwrap(site, metaClass, metaMethod, params);
109 else
110 if (metaMethod.getClass() == CachedMethod.class)
111 return ((CachedMethod)metaMethod).createStaticMetaMethodSite(site, metaClass, params);
112 else
113 return new StaticMetaMethodSiteNoUnwrapNoCoerce (site, metaClass, metaMethod, params);
114 }
115 }
116 return new StaticMetaMethodSite(site, metaClass, metaMethod, params);
117 }
118
119 /**
120 * Call site where we know there is no need to unwrap arguments
121 */
122 public static class StaticMetaMethodSiteNoUnwrap extends StaticMetaMethodSite {
123
124 public StaticMetaMethodSiteNoUnwrap(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
125 super(site, metaClass, metaMethod, params);
126 }
127
128 public final Object invoke(Object receiver, Object[] args) throws Throwable {
129 try {
130 return metaMethod.doMethodInvoke(receiver, args);
131 } catch (GroovyRuntimeException gre) {
132 throw ScriptBytecodeAdapter.unwrap(gre);
133 }
134 }
135 }
136
137 /**
138 * Call site where we know there is no need neither unwrap nor coerce arguments
139 */
140 public static class StaticMetaMethodSiteNoUnwrapNoCoerce extends StaticMetaMethodSite {
141
142 public StaticMetaMethodSiteNoUnwrapNoCoerce(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) {
143 super(site, metaClass, metaMethod, params);
144 }
145
146 public final Object invoke(Object receiver, Object[] args) throws Throwable {
147 try {
148 return metaMethod.invoke(receiver, args);
149 } catch (GroovyRuntimeException gre) {
150 throw ScriptBytecodeAdapter.unwrap(gre);
151 }
152 }
153 }
154 }