KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > runtime > callback > InvocationCallbackFactory


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2006 Ola Bini <ola@ologix.com>
15  *
16  * Alternatively, the contents of this file may be used under the terms of
17  * either of the GNU General Public License Version 2 or later (the "GPL"),
18  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19  * in which case the provisions of the GPL or the LGPL are applicable instead
20  * of those above. If you wish to allow use of your version of this file only
21  * under the terms of either the GPL or the LGPL, and not to allow others to
22  * use your version of this file under the terms of the CPL, indicate your
23  * decision by deleting the provisions above and replace them with the notice
24  * and other provisions required by the GPL or the LGPL. If you do not delete
25  * the provisions above, a recipient may use your version of this file under
26  * the terms of any one of the CPL, the GPL or the LGPL.
27  ***** END LICENSE BLOCK *****/

28 package org.jruby.runtime.callback;
29
30 import org.jruby.Ruby;
31 import org.jruby.RubyKernel;
32 import org.objectweb.asm.ClassWriter;
33 import org.objectweb.asm.MethodVisitor;
34 import org.objectweb.asm.Opcodes;
35 import org.jruby.runtime.Arity;
36 import org.jruby.runtime.Block;
37 import org.jruby.runtime.CallbackFactory;
38 import org.jruby.runtime.CompiledBlockCallback;
39 import org.jruby.runtime.ThreadContext;
40 import org.jruby.runtime.builtin.IRubyObject;
41 import org.jruby.util.CodegenUtils;
42
43 public class InvocationCallbackFactory extends CallbackFactory implements Opcodes {
44     private final static CodegenUtils cg = CodegenUtils.instance;
45
46     private final Class JavaDoc type;
47     private final String JavaDoc typePath;
48     private final Ruby runtime;
49
50     private final static String JavaDoc SUPER_CLASS = cg.p(InvocationCallback.class);
51     private final static String JavaDoc FAST_SUPER_CLASS = cg.p(FastInvocationCallback.class);
52     private final static String JavaDoc BLOCK_ID = cg.ci(Block.class);
53     private final static String JavaDoc CALL_SIG = cg.sig(RubyKernel.IRUBY_OBJECT, cg.params(Object JavaDoc.class, Object JavaDoc[].class, Block.class));
54     private final static String JavaDoc FAST_CALL_SIG = cg.sig(RubyKernel.IRUBY_OBJECT, cg.params(Object JavaDoc.class, Object JavaDoc[].class));
55     private final static String JavaDoc BLOCK_CALL_SIG = cg.sig(RubyKernel.IRUBY_OBJECT, cg.params(ThreadContext.class, RubyKernel.IRUBY_OBJECT, IRubyObject[].class, Block.class, IRubyObject[][].class));
56     private final static String JavaDoc IRUB = cg.p(RubyKernel.IRUBY_OBJECT);
57     private final static String JavaDoc IRUB_ID = cg.ci(RubyKernel.IRUBY_OBJECT);
58     
59     public InvocationCallbackFactory(Ruby runtime, Class JavaDoc type) {
60         this.type = type;
61         this.typePath = cg.p(type);
62         this.runtime = runtime;
63     }
64
65     private String JavaDoc getReturnName(String JavaDoc method, Class JavaDoc[] args) throws Exception JavaDoc {
66         String JavaDoc t = type.getMethod(method,args).getReturnType().getName().replace('.','/');
67         if("void".equalsIgnoreCase(t)) {
68             throw new IllegalArgumentException JavaDoc("Method " + method + " has a void return type. This is not allowed in JRuby.");
69         }
70         return t;
71     }
72
73     private ClassWriter createCtor(String JavaDoc namePath) throws Exception JavaDoc {
74         ClassWriter cw = new ClassWriter(true);
75         cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, namePath, null, SUPER_CLASS, null);
76         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
77         mv.visitCode();
78         mv.visitVarInsn(ALOAD, 0);
79         mv.visitMethodInsn(INVOKESPECIAL, SUPER_CLASS, "<init>", "()V");
80         mv.visitInsn(RETURN);
81         mv.visitMaxs(1, 1);
82         mv.visitEnd();
83         return cw;
84     }
85
86     private ClassWriter createCtorFast(String JavaDoc namePath) throws Exception JavaDoc {
87         ClassWriter cw = new ClassWriter(true);
88         cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, namePath, null, FAST_SUPER_CLASS, null);
89         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
90         mv.visitCode();
91         mv.visitVarInsn(ALOAD, 0);
92         mv.visitMethodInsn(INVOKESPECIAL, FAST_SUPER_CLASS, "<init>", "()V");
93         mv.visitInsn(RETURN);
94         mv.visitMaxs(1, 1);
95         mv.visitEnd();
96         return cw;
97     }
98
99     private ClassWriter createBlockCtor(String JavaDoc namePath) throws Exception JavaDoc {
100         ClassWriter cw = new ClassWriter(true);
101         cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, namePath, null, cg.p(Object JavaDoc.class), new String JavaDoc[] { cg.p(CompiledBlockCallback.class) });
102         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
103         mv.visitCode();
104         mv.visitVarInsn(ALOAD, 0);
105         mv.visitMethodInsn(INVOKESPECIAL, cg.p(Object JavaDoc.class), "<init>", "()V");
106         mv.visitInsn(RETURN);
107         mv.visitMaxs(1, 1);
108         mv.visitEnd();
109         return cw;
110     }
111
112     private Class JavaDoc tryClass(String JavaDoc name) {
113         try {
114             return Class.forName(name,true,runtime.getJRubyClassLoader());
115         } catch(Exception JavaDoc e) {
116             return null;
117         }
118     }
119
120     private MethodVisitor startCall(ClassWriter cw) {
121         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "call", CALL_SIG, null, null);;
122         mv.visitCode();
123         mv.visitVarInsn(ALOAD, 1);
124         mv.visitTypeInsn(CHECKCAST, typePath);
125         return mv;
126     }
127
128     private MethodVisitor startCallS(ClassWriter cw) {
129         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "call", CALL_SIG, null, null);;
130         mv.visitCode();
131         mv.visitVarInsn(ALOAD, 1);
132         mv.visitTypeInsn(CHECKCAST, IRUB);
133         return mv;
134     }
135
136     private MethodVisitor startCallFast(ClassWriter cw) {
137         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "call", FAST_CALL_SIG, null, null);;
138         mv.visitCode();
139         mv.visitVarInsn(ALOAD, 1);
140         mv.visitTypeInsn(CHECKCAST, typePath);
141         return mv;
142     }
143
144     private MethodVisitor startCallSFast(ClassWriter cw) {
145         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "call", FAST_CALL_SIG, null, null);;
146         mv.visitCode();
147         mv.visitVarInsn(ALOAD, 1);
148         mv.visitTypeInsn(CHECKCAST, IRUB);
149         return mv;
150     }
151
152     private MethodVisitor startBlockCall(ClassWriter cw) {
153         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "call", BLOCK_CALL_SIG, null, null);;
154         mv.visitCode();
155         return mv;
156     }
157
158     private Class JavaDoc endCall(ClassWriter cw, MethodVisitor mv, String JavaDoc name) {
159         mv.visitEnd();
160         cw.visitEnd();
161         byte[] code = cw.toByteArray();
162         return runtime.getJRubyClassLoader().defineClass(name, code);
163     }
164
165     public Callback getMethod(String JavaDoc method) {
166         String JavaDoc mname = type.getName() + "Invoker" + method + "0";
167         String JavaDoc mnamePath = typePath + "Invoker" + method + "0";
168         Class JavaDoc c = tryClass(mname);
169         try {
170             if(c == null) {
171                 String JavaDoc ret = getReturnName(method, new Class JavaDoc[]{Block.class});
172                 ClassWriter cw = createCtor(mnamePath);
173                 MethodVisitor mv = startCall(cw);
174                 mv.visitVarInsn(ALOAD, 3);
175                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "(" + BLOCK_ID + ")L" + ret + ";");
176                 mv.visitInsn(ARETURN);
177                 mv.visitMaxs(1, 3);
178                 c = endCall(cw,mv,mname);
179             }
180             InvocationCallback ic = (InvocationCallback)c.newInstance();
181             ic.setArity(Arity.noArguments());
182             return ic;
183         } catch(IllegalArgumentException JavaDoc e) {
184             throw e;
185         } catch(Exception JavaDoc e) {
186             throw new IllegalArgumentException JavaDoc(e.getMessage());
187         }
188     }
189
190     public Callback getMethod(String JavaDoc method, Class JavaDoc arg1) {
191         String JavaDoc mname = type.getName() + "Invoker" + method + "1";
192         String JavaDoc mnamePath = typePath + "Invoker" + method + "1";
193         Class JavaDoc c = tryClass(mname);
194         try {
195             if(c == null) {
196                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1,Block.class});
197                 ClassWriter cw = createCtor(mnamePath);
198                 MethodVisitor mv = startCall(cw);
199                 mv.visitVarInsn(ALOAD, 2);
200                 mv.visitInsn(ICONST_0);
201                 mv.visitInsn(AALOAD);
202                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
203                 mv.visitVarInsn(ALOAD, 3);
204                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+BLOCK_ID+")L"+ret+";");
205                 mv.visitInsn(ARETURN);
206                 mv.visitMaxs(3, 3);
207                 c = endCall(cw,mv,mname);
208             }
209             InvocationCallback ic = (InvocationCallback)c.newInstance();
210             ic.setArity(Arity.singleArgument());
211             return ic;
212         } catch(IllegalArgumentException JavaDoc e) {
213             throw e;
214         } catch(Exception JavaDoc e) {
215             throw new IllegalArgumentException JavaDoc(e.getMessage());
216         }
217     }
218
219     public Callback getMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2) {
220         String JavaDoc mname = type.getName() + "Invoker" + method + "2";
221         String JavaDoc mnamePath = typePath + "Invoker" + method + "2";
222         Class JavaDoc c = tryClass(mname);
223         try {
224             if(c == null) {
225                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1,arg2,Block.class});
226                 ClassWriter cw = createCtor(mnamePath);
227                 MethodVisitor mv = startCall(cw);
228                 mv.visitVarInsn(ALOAD, 2);
229                 mv.visitInsn(ICONST_0);
230                 mv.visitInsn(AALOAD);
231                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
232                 mv.visitVarInsn(ALOAD, 2);
233                 mv.visitInsn(ICONST_1);
234                 mv.visitInsn(AALOAD);
235                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
236                 mv.visitVarInsn(ALOAD, 3);
237                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+cg.ci(arg2)+BLOCK_ID+")L"+ret+";");
238                 mv.visitInsn(ARETURN);
239                 mv.visitMaxs(4, 3);
240                 c = endCall(cw,mv,mname);
241             }
242             InvocationCallback ic = (InvocationCallback)c.newInstance();
243             ic.setArity(Arity.twoArguments());
244             return ic;
245         } catch(IllegalArgumentException JavaDoc e) {
246             throw e;
247         } catch(Exception JavaDoc e) {
248             throw new IllegalArgumentException JavaDoc(e.getMessage());
249         }
250     }
251     
252     public Callback getMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2, Class JavaDoc arg3) {
253         String JavaDoc mname = type.getName() + "Invoker" + method + "3";
254         String JavaDoc mnamePath = typePath + "Invoker" + method + "3";
255         Class JavaDoc c = tryClass(mname);
256         try {
257             if(c == null) {
258                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1,arg2,arg3,Block.class});
259                 ClassWriter cw = createCtor(mnamePath);
260                 MethodVisitor mv = startCall(cw);
261                 mv.visitVarInsn(ALOAD, 2);
262                 mv.visitInsn(ICONST_0);
263                 mv.visitInsn(AALOAD);
264                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
265                 mv.visitVarInsn(ALOAD, 2);
266                 mv.visitInsn(ICONST_1);
267                 mv.visitInsn(AALOAD);
268                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
269                 mv.visitVarInsn(ALOAD, 2);
270                 mv.visitInsn(ICONST_2);
271                 mv.visitInsn(AALOAD);
272                 mv.visitTypeInsn(CHECKCAST, cg.p(arg3));
273                 mv.visitVarInsn(ALOAD, 3);
274                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+cg.ci(arg2)+cg.ci(arg3)+BLOCK_ID+")L"+ret+";");
275                 mv.visitInsn(ARETURN);
276                 mv.visitMaxs(5, 3);
277                 c = endCall(cw,mv,mname);
278             }
279             InvocationCallback ic = (InvocationCallback)c.newInstance();
280             ic.setArity(Arity.fixed(3));
281             return ic;
282         } catch(IllegalArgumentException JavaDoc e) {
283             throw e;
284         } catch(Exception JavaDoc e) {
285             throw new IllegalArgumentException JavaDoc(e.getMessage());
286         }
287     }
288
289     public Callback getSingletonMethod(String JavaDoc method) {
290         String JavaDoc mname = type.getName() + "InvokerS" + method + "0";
291         String JavaDoc mnamePath = typePath + "InvokerS" + method + "0";
292         Class JavaDoc c = tryClass(mname);
293         try {
294             if(c == null) {
295                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,Block.class});
296                 ClassWriter cw = createCtor(mnamePath);
297                 MethodVisitor mv = startCallS(cw);
298                 mv.visitVarInsn(ALOAD, 3);
299                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + BLOCK_ID + ")L" + ret +";");
300                 mv.visitInsn(ARETURN);
301                 mv.visitMaxs(1, 3);
302                 c = endCall(cw,mv,mname);
303             }
304             InvocationCallback ic = (InvocationCallback)c.newInstance();
305             ic.setArity(Arity.noArguments());
306             return ic;
307         } catch(IllegalArgumentException JavaDoc e) {
308             throw e;
309         } catch(Exception JavaDoc e) {
310             throw new IllegalArgumentException JavaDoc(e.getMessage());
311         }
312     }
313
314     public Callback getSingletonMethod(String JavaDoc method, Class JavaDoc arg1) {
315         String JavaDoc mname = type.getName() + "InvokerS" + method + "1";
316         String JavaDoc mnamePath = typePath + "InvokerS" + method + "1";
317         Class JavaDoc c = tryClass(mname);
318         try {
319             if(c == null) {
320                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1,Block.class});
321                 ClassWriter cw = createCtor(mnamePath);
322                 MethodVisitor mv = startCallS(cw);
323                 mv.visitVarInsn(ALOAD, 2);
324                 mv.visitInsn(ICONST_0);
325                 mv.visitInsn(AALOAD);
326                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
327                 mv.visitVarInsn(ALOAD, 3);
328                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + BLOCK_ID + ")L" + ret + ";");
329                 mv.visitInsn(ARETURN);
330                 mv.visitMaxs(3, 3);
331                 c = endCall(cw,mv,mname);
332             }
333             InvocationCallback ic = (InvocationCallback)c.newInstance();
334             ic.setArity(Arity.singleArgument());
335             return ic;
336         } catch(IllegalArgumentException JavaDoc e) {
337             throw e;
338         } catch(Exception JavaDoc e) {
339             throw new IllegalArgumentException JavaDoc(e.getMessage());
340         }
341     }
342
343     public Callback getSingletonMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2) {
344         String JavaDoc mname = type.getName() + "InvokerS" + method + "2";
345         String JavaDoc mnamePath = typePath + "InvokerS" + method + "2";
346         Class JavaDoc c = tryClass(mname);
347         try {
348             if(c == null) {
349                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1,arg2,Block.class});
350                 ClassWriter cw = createCtor(mnamePath);
351                 MethodVisitor mv = startCallS(cw);
352                 mv.visitVarInsn(ALOAD, 2);
353                 mv.visitInsn(ICONST_0);
354                 mv.visitInsn(AALOAD);
355                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
356                 mv.visitVarInsn(ALOAD, 2);
357                 mv.visitInsn(ICONST_1);
358                 mv.visitInsn(AALOAD);
359                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
360                 mv.visitVarInsn(ALOAD, 3);
361                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + cg.ci(arg2) + BLOCK_ID + ")L" + ret + ";");
362                 mv.visitInsn(ARETURN);
363                 mv.visitMaxs(4, 4);
364                 c = endCall(cw,mv,mname);
365             }
366             InvocationCallback ic = (InvocationCallback)c.newInstance();
367             ic.setArity(Arity.twoArguments());
368             return ic;
369         } catch(IllegalArgumentException JavaDoc e) {
370             throw e;
371         } catch(Exception JavaDoc e) {
372             throw new IllegalArgumentException JavaDoc(e.getMessage());
373         }
374     }
375
376     public Callback getSingletonMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2, Class JavaDoc arg3) {
377         String JavaDoc mname = type.getName() + "InvokerS" + method + "3";
378         String JavaDoc mnamePath = typePath + "InvokerS" + method + "3";
379         Class JavaDoc c = tryClass(mname);
380         try {
381             if(c == null) {
382                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1,arg2,arg3,Block.class});
383                 ClassWriter cw = createCtor(mnamePath);
384                 MethodVisitor mv = startCallS(cw);
385                 mv.visitVarInsn(ALOAD, 2);
386                 mv.visitInsn(ICONST_0);
387                 mv.visitInsn(AALOAD);
388                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
389                 mv.visitVarInsn(ALOAD, 2);
390                 mv.visitInsn(ICONST_1);
391                 mv.visitInsn(AALOAD);
392                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
393                 mv.visitVarInsn(ALOAD, 2);
394                 mv.visitInsn(ICONST_2);
395                 mv.visitInsn(AALOAD);
396                 mv.visitTypeInsn(CHECKCAST, cg.p(arg3));
397                 mv.visitVarInsn(ALOAD, 3);
398                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + cg.ci(arg2) + cg.ci(arg3) + BLOCK_ID + ")L" + ret + ";");
399                 mv.visitInsn(ARETURN);
400                 mv.visitMaxs(5, 3);
401                 c = endCall(cw,mv,mname);
402             }
403             InvocationCallback ic = (InvocationCallback)c.newInstance();
404             ic.setArity(Arity.fixed(3));
405             return ic;
406         } catch(IllegalArgumentException JavaDoc e) {
407             throw e;
408         } catch(Exception JavaDoc e) {
409             throw new IllegalArgumentException JavaDoc(e.getMessage());
410         }
411     }
412
413     public Callback getBlockMethod(String JavaDoc method) {
414         // TODO: This is probably BAD...
415
return new ReflectionCallback(
416             type,
417             method,
418             new Class JavaDoc[] { RubyKernel.IRUBY_OBJECT, RubyKernel.IRUBY_OBJECT },
419             false,
420             true,
421             Arity.fixed(2), false);
422     }
423     
424     public CompiledBlockCallback getBlockCallback(String JavaDoc method) {
425         String JavaDoc mname = type.getName() + "Block" + method + "xx1";
426         String JavaDoc mnamePath = typePath + "Block" + method + "xx1";
427         Class JavaDoc c = tryClass(mname);
428         try {
429             if(c == null) {
430                 ClassWriter cw = createBlockCtor(mnamePath);
431                 MethodVisitor mv = startBlockCall(cw);
432                 mv.visitVarInsn(ALOAD, 1);
433                 mv.visitVarInsn(ALOAD, 2);
434                 mv.visitVarInsn(ALOAD, 3);
435                 mv.visitVarInsn(ALOAD, 4);
436                 mv.visitVarInsn(ALOAD, 5);
437                 mv.visitMethodInsn(INVOKESTATIC, typePath, method,
438                         cg.sig(RubyKernel.IRUBY_OBJECT, cg.params(ThreadContext.class, RubyKernel.IRUBY_OBJECT, IRubyObject[].class, Block.class, IRubyObject[][].class)));
439                 mv.visitInsn(ARETURN);
440                 mv.visitMaxs(2, 3);
441                 c = endCall(cw,mv,mname);
442             }
443             CompiledBlockCallback ic = (CompiledBlockCallback)c.newInstance();
444             return ic;
445         } catch(IllegalArgumentException JavaDoc e) {
446             throw e;
447         } catch(Exception JavaDoc e) {
448             throw new IllegalArgumentException JavaDoc(e.getMessage());
449         }
450     }
451
452     public Callback getOptSingletonMethod(String JavaDoc method) {
453         String JavaDoc mname = type.getName() + "InvokerS" + method + "xx1";
454         String JavaDoc mnamePath = typePath + "InvokerS" + method + "xx1";
455         Class JavaDoc c = tryClass(mname);
456         try {
457             if(c == null) {
458                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,IRubyObject[].class,Block.class});
459                 ClassWriter cw = createCtor(mnamePath);
460                 MethodVisitor mv = startCallS(cw);
461                 mv.visitVarInsn(ALOAD, 2);
462                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
463                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
464                 mv.visitVarInsn(ALOAD, 3);
465                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + "[" + IRUB_ID + BLOCK_ID + ")L"+ret+";");
466                 mv.visitInsn(ARETURN);
467                 mv.visitMaxs(2, 3);
468                 c = endCall(cw,mv,mname);
469             }
470             InvocationCallback ic = (InvocationCallback)c.newInstance();
471             ic.setArity(Arity.optional());
472             return ic;
473         } catch(IllegalArgumentException JavaDoc e) {
474             throw e;
475         } catch(Exception JavaDoc e) {
476             throw new IllegalArgumentException JavaDoc(e.getMessage());
477         }
478     }
479
480     public Callback getOptMethod(String JavaDoc method) {
481         String JavaDoc mname = type.getName() + "Invoker" + method + "xx1";
482         String JavaDoc mnamePath = typePath + "Invoker" + method + "xx1";
483         Class JavaDoc c = tryClass(mname);
484         try {
485             if(c == null) {
486                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{IRubyObject[].class, Block.class});
487                 ClassWriter cw = createCtor(mnamePath);
488                 MethodVisitor mv = startCall(cw);
489                 mv.visitVarInsn(ALOAD, 2);
490                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
491                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
492                 mv.visitVarInsn(ALOAD, 3);
493                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "([" + IRUB_ID + BLOCK_ID + ")L" + ret + ";");
494                 mv.visitInsn(ARETURN);
495                 mv.visitMaxs(2, 3);
496                 c = endCall(cw,mv,mname);
497             }
498             InvocationCallback ic = (InvocationCallback)c.newInstance();
499             ic.setArity(Arity.optional());
500             return ic;
501         } catch(IllegalArgumentException JavaDoc e) {
502             throw e;
503         } catch(Exception JavaDoc e) {
504             throw new IllegalArgumentException JavaDoc(e.getMessage());
505         }
506     }
507
508     public Callback getFastMethod(String JavaDoc method) {
509         String JavaDoc mname = type.getName() + "Invoker" + method + "0";
510         String JavaDoc mnamePath = typePath + "Invoker" + method + "0";
511         Class JavaDoc c = tryClass(mname);
512         try {
513             if(c == null) {
514                 String JavaDoc ret = getReturnName(method, null);
515                 ClassWriter cw = createCtorFast(mnamePath);
516                 MethodVisitor mv = startCallFast(cw);
517                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "()L" + ret + ";");
518                 mv.visitInsn(ARETURN);
519                 mv.visitMaxs(1, 3);
520                 c = endCall(cw,mv,mname);
521             }
522             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
523             ic.setArity(Arity.noArguments());
524             return ic;
525         } catch(IllegalArgumentException JavaDoc e) {
526             throw e;
527         } catch(Exception JavaDoc e) {
528             throw new IllegalArgumentException JavaDoc(e.getMessage());
529         }
530     }
531
532     public Callback getFastMethod(String JavaDoc method, Class JavaDoc arg1) {
533         String JavaDoc mname = type.getName() + "Invoker" + method + "1";
534         String JavaDoc mnamePath = typePath + "Invoker" + method + "1";
535         Class JavaDoc c = tryClass(mname);
536         try {
537             if(c == null) {
538                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1});
539                 ClassWriter cw = createCtorFast(mnamePath);
540                 MethodVisitor mv = startCallFast(cw);
541                 mv.visitVarInsn(ALOAD, 2);
542                 mv.visitInsn(ICONST_0);
543                 mv.visitInsn(AALOAD);
544                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
545                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+")L"+ret+";");
546                 mv.visitInsn(ARETURN);
547                 mv.visitMaxs(3, 3);
548                 c = endCall(cw,mv,mname);
549             }
550             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
551             ic.setArity(Arity.singleArgument());
552             return ic;
553         } catch(IllegalArgumentException JavaDoc e) {
554             throw e;
555         } catch(Exception JavaDoc e) {
556             throw new IllegalArgumentException JavaDoc(e.getMessage());
557         }
558     }
559
560     public Callback getFastMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2) {
561         String JavaDoc mname = type.getName() + "Invoker" + method + "2";
562         String JavaDoc mnamePath = typePath + "Invoker" + method + "2";
563         Class JavaDoc c = tryClass(mname);
564         try {
565             if(c == null) {
566                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1,arg2});
567                 ClassWriter cw = createCtorFast(mnamePath);
568                 MethodVisitor mv = startCallFast(cw);
569                 mv.visitVarInsn(ALOAD, 2);
570                 mv.visitInsn(ICONST_0);
571                 mv.visitInsn(AALOAD);
572                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
573                 mv.visitVarInsn(ALOAD, 2);
574                 mv.visitInsn(ICONST_1);
575                 mv.visitInsn(AALOAD);
576                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
577                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+cg.ci(arg2)+")L"+ret+";");
578                 mv.visitInsn(ARETURN);
579                 mv.visitMaxs(4, 3);
580                 c = endCall(cw,mv,mname);
581             }
582             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
583             ic.setArity(Arity.twoArguments());
584             return ic;
585         } catch(IllegalArgumentException JavaDoc e) {
586             throw e;
587         } catch(Exception JavaDoc e) {
588             throw new IllegalArgumentException JavaDoc(e.getMessage());
589         }
590     }
591
592     public Callback getFastMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2, Class JavaDoc arg3) {
593         String JavaDoc mname = type.getName() + "Invoker" + method + "3";
594         String JavaDoc mnamePath = typePath + "Invoker" + method + "3";
595         Class JavaDoc c = tryClass(mname);
596         try {
597             if(c == null) {
598                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{arg1,arg2,arg3});
599                 ClassWriter cw = createCtorFast(mnamePath);
600                 MethodVisitor mv = startCallFast(cw);
601                 mv.visitVarInsn(ALOAD, 2);
602                 mv.visitInsn(ICONST_0);
603                 mv.visitInsn(AALOAD);
604                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
605                 mv.visitVarInsn(ALOAD, 2);
606                 mv.visitInsn(ICONST_1);
607                 mv.visitInsn(AALOAD);
608                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
609                 mv.visitVarInsn(ALOAD, 2);
610                 mv.visitInsn(ICONST_2);
611                 mv.visitInsn(AALOAD);
612                 mv.visitTypeInsn(CHECKCAST, cg.p(arg3));
613                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "("+cg.ci(arg1)+cg.ci(arg2)+cg.ci(arg3)+")L"+ret+";");
614                 mv.visitInsn(ARETURN);
615                 mv.visitMaxs(5, 3);
616                 c = endCall(cw,mv,mname);
617             }
618             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
619             ic.setArity(Arity.fixed(3));
620             return ic;
621         } catch(IllegalArgumentException JavaDoc e) {
622             throw e;
623         } catch(Exception JavaDoc e) {
624             throw new IllegalArgumentException JavaDoc(e.getMessage());
625         }
626     }
627
628     public Callback getFastSingletonMethod(String JavaDoc method) {
629         String JavaDoc mname = type.getName() + "InvokerS" + method + "0";
630         String JavaDoc mnamePath = typePath + "InvokerS" + method + "0";
631         Class JavaDoc c = tryClass(mname);
632         try {
633             if(c == null) {
634                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT});
635                 ClassWriter cw = createCtorFast(mnamePath);
636                 MethodVisitor mv = startCallSFast(cw);
637                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + ")L" + ret +";");
638                 mv.visitInsn(ARETURN);
639                 mv.visitMaxs(1, 3);
640                 c = endCall(cw,mv,mname);
641             }
642             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
643             ic.setArity(Arity.noArguments());
644             return ic;
645         } catch(IllegalArgumentException JavaDoc e) {
646             throw e;
647         } catch(Exception JavaDoc e) {
648             throw new IllegalArgumentException JavaDoc(e.getMessage());
649         }
650     }
651
652     public Callback getFastSingletonMethod(String JavaDoc method, Class JavaDoc arg1) {
653         String JavaDoc mname = type.getName() + "InvokerS" + method + "1";
654         String JavaDoc mnamePath = typePath + "InvokerS" + method + "1";
655         Class JavaDoc c = tryClass(mname);
656         try {
657             if(c == null) {
658                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1});
659                 ClassWriter cw = createCtorFast(mnamePath);
660                 MethodVisitor mv = startCallSFast(cw);
661                 mv.visitVarInsn(ALOAD, 2);
662                 mv.visitInsn(ICONST_0);
663                 mv.visitInsn(AALOAD);
664                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
665                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + ")L" + ret + ";");
666                 mv.visitInsn(ARETURN);
667                 mv.visitMaxs(3, 3);
668                 c = endCall(cw,mv,mname);
669             }
670             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
671             ic.setArity(Arity.singleArgument());
672             return ic;
673         } catch(IllegalArgumentException JavaDoc e) {
674             throw e;
675         } catch(Exception JavaDoc e) {
676             throw new IllegalArgumentException JavaDoc(e.getMessage());
677         }
678     }
679
680     public Callback getFastSingletonMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2) {
681         String JavaDoc mname = type.getName() + "InvokerS" + method + "2";
682         String JavaDoc mnamePath = typePath + "InvokerS" + method + "2";
683         Class JavaDoc c = tryClass(mname);
684         try {
685             if(c == null) {
686                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1,arg2});
687                 ClassWriter cw = createCtorFast(mnamePath);
688                 MethodVisitor mv = startCallSFast(cw);
689                 mv.visitVarInsn(ALOAD, 2);
690                 mv.visitInsn(ICONST_0);
691                 mv.visitInsn(AALOAD);
692                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
693                 mv.visitVarInsn(ALOAD, 2);
694                 mv.visitInsn(ICONST_1);
695                 mv.visitInsn(AALOAD);
696                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
697                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + cg.ci(arg2) + ")L" + ret + ";");
698                 mv.visitInsn(ARETURN);
699                 mv.visitMaxs(4, 4);
700                 c = endCall(cw,mv,mname);
701             }
702             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
703             ic.setArity(Arity.twoArguments());
704             return ic;
705         } catch(IllegalArgumentException JavaDoc e) {
706             throw e;
707         } catch(Exception JavaDoc e) {
708             throw new IllegalArgumentException JavaDoc(e.getMessage());
709         }
710     }
711
712     public Callback getFastSingletonMethod(String JavaDoc method, Class JavaDoc arg1, Class JavaDoc arg2, Class JavaDoc arg3) {
713         String JavaDoc mname = type.getName() + "InvokerS" + method + "3";
714         String JavaDoc mnamePath = typePath + "InvokerS" + method + "3";
715         Class JavaDoc c = tryClass(mname);
716         try {
717             if(c == null) {
718                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,arg1,arg2,arg3});
719                 ClassWriter cw = createCtorFast(mnamePath);
720                 MethodVisitor mv = startCallSFast(cw);
721                 mv.visitVarInsn(ALOAD, 2);
722                 mv.visitInsn(ICONST_0);
723                 mv.visitInsn(AALOAD);
724                 mv.visitTypeInsn(CHECKCAST, cg.p(arg1));
725                 mv.visitVarInsn(ALOAD, 2);
726                 mv.visitInsn(ICONST_1);
727                 mv.visitInsn(AALOAD);
728                 mv.visitTypeInsn(CHECKCAST, cg.p(arg2));
729                 mv.visitVarInsn(ALOAD, 2);
730                 mv.visitInsn(ICONST_2);
731                 mv.visitInsn(AALOAD);
732                 mv.visitTypeInsn(CHECKCAST, cg.p(arg3));
733                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + cg.ci(arg1) + cg.ci(arg2) + cg.ci(arg3) + ")L" + ret + ";");
734                 mv.visitInsn(ARETURN);
735                 mv.visitMaxs(5, 3);
736                 c = endCall(cw,mv,mname);
737             }
738             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
739             ic.setArity(Arity.fixed(3));
740             return ic;
741         } catch(IllegalArgumentException JavaDoc e) {
742             throw e;
743         } catch(Exception JavaDoc e) {
744             throw new IllegalArgumentException JavaDoc(e.getMessage());
745         }
746     }
747
748     public Callback getFastOptMethod(String JavaDoc method) {
749         String JavaDoc mname = type.getName() + "Invoker" + method + "xx1";
750         String JavaDoc mnamePath = typePath + "Invoker" + method + "xx1";
751         Class JavaDoc c = tryClass(mname);
752         try {
753             if(c == null) {
754                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{IRubyObject[].class});
755                 ClassWriter cw = createCtorFast(mnamePath);
756                 MethodVisitor mv = startCallFast(cw);
757                 mv.visitVarInsn(ALOAD, 2);
758                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
759                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
760                 mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "([" + IRUB_ID + ")L" + ret + ";");
761                 mv.visitInsn(ARETURN);
762                 mv.visitMaxs(2, 3);
763                 c = endCall(cw,mv,mname);
764             }
765             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
766             ic.setArity(Arity.optional());
767             return ic;
768         } catch(IllegalArgumentException JavaDoc e) {
769             throw e;
770         } catch(Exception JavaDoc e) {
771             throw new IllegalArgumentException JavaDoc(e.getMessage());
772         }
773     }
774
775     public Callback getFastOptSingletonMethod(String JavaDoc method) {
776         String JavaDoc mname = type.getName() + "InvokerS" + method + "xx1";
777         String JavaDoc mnamePath = typePath + "InvokerS" + method + "xx1";
778         Class JavaDoc c = tryClass(mname);
779         try {
780             if(c == null) {
781                 String JavaDoc ret = getReturnName(method,new Class JavaDoc[]{RubyKernel.IRUBY_OBJECT,IRubyObject[].class});
782                 ClassWriter cw = createCtorFast(mnamePath);
783                 MethodVisitor mv = startCallSFast(cw);
784                 mv.visitVarInsn(ALOAD, 2);
785                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
786                 mv.visitTypeInsn(CHECKCAST, "[" + IRUB_ID);
787                 mv.visitMethodInsn(INVOKESTATIC, typePath, method, "(" + IRUB_ID + "[" + IRUB_ID + ")L"+ret+";");
788                 mv.visitInsn(ARETURN);
789                 mv.visitMaxs(2, 3);
790                 c = endCall(cw,mv,mname);
791             }
792             FastInvocationCallback ic = (FastInvocationCallback)c.newInstance();
793             ic.setArity(Arity.optional());
794             return ic;
795         } catch(IllegalArgumentException JavaDoc e) {
796             throw e;
797         } catch(Exception JavaDoc e) {
798             throw new IllegalArgumentException JavaDoc(e.getMessage());
799         }
800     }
801 } //InvocationCallbackFactory
802
Popular Tags