comparison src/luan/LuaJavaFunction.java @ 4:24fd6381caca

add to interp git-svn-id: https://luan-java.googlecode.com/svn/trunk@5 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 18 Nov 2012 04:18:15 +0000
parents 4da26b11d12a
children 9cea1aea5eef
comparison
equal deleted inserted replaced
3:7a2cdbc5767f 4:24fd6381caca
1 package luan; 1 package luan;
2 2
3 import java.lang.reflect.Array;
3 import java.lang.reflect.Method; 4 import java.lang.reflect.Method;
4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.InvocationTargetException;
5 6
6 7
7 public final class LuaJavaFunction extends LuaFunction { 8 public final class LuaJavaFunction extends LuaFunction {
8 private final Method method; 9 private final Method method;
9 private final Object obj; 10 private final Object obj;
10 private final RtnConverter rtnConverter; 11 private final RtnConverter rtnConverter;
11 private final ArgConverter[] argConverters; 12 private final ArgConverter[] argConverters;
13 private final Class<?> varArgCls;
12 14
13 public LuaJavaFunction(Method method,Object obj) { 15 public LuaJavaFunction(Method method,Object obj) {
14 this.method = method; 16 this.method = method;
15 this.obj = obj; 17 this.obj = obj;
16 rtnConverter = getRtnConverter(method); 18 this.rtnConverter = getRtnConverter(method);
17 argConverters = getArgConverters(method); 19 this.argConverters = getArgConverters(method);
20 if( method.isVarArgs() ) {
21 Class<?>[] paramTypes = method.getParameterTypes();
22 this.varArgCls = paramTypes[paramTypes.length-1].getComponentType();
23 } else {
24 this.varArgCls = null;
25 }
18 } 26 }
19 27
20 @Override public Object[] call(Object... args) { 28 @Override public Object[] call(Object... args) {
21 args = fixArgs(args); 29 args = fixArgs(args);
22 Object rtn; 30 Object rtn;
29 } 37 }
30 return rtnConverter.convert(rtn); 38 return rtnConverter.convert(rtn);
31 } 39 }
32 40
33 private Object[] fixArgs(Object[] args) { 41 private Object[] fixArgs(Object[] args) {
34 if( args.length != argConverters.length ) { 42 if( varArgCls==null ) {
35 Object[] t = new Object[argConverters.length]; 43 if( args.length != argConverters.length ) {
36 System.arraycopy(args,0,t,0,Math.min(args.length,t.length)); 44 Object[] t = new Object[argConverters.length];
37 args = t; 45 System.arraycopy(args,0,t,0,Math.min(args.length,t.length));
38 } 46 args = t;
39 for( int i=0; i<args.length; i++ ) { 47 }
40 args[i] = argConverters[i].convert(args[i]); 48 for( int i=0; i<args.length; i++ ) {
41 } 49 args[i] = argConverters[i].convert(args[i]);
42 return args; 50 }
51 return args;
52 } else { // varargs
53 Object[] rtn = new Object[argConverters.length];
54 int n = argConverters.length - 1;
55 if( args.length < argConverters.length ) {
56 System.arraycopy(args,0,rtn,0,args.length);
57 rtn[rtn.length-1] = Array.newInstance(varArgCls,0);
58 } else {
59 System.arraycopy(args,0,rtn,0,n);
60 Object[] varArgs = (Object[])Array.newInstance(varArgCls,args.length-n);
61 ArgConverter ac = argConverters[n];
62 for( int i=0; i<varArgs.length; i++ ) {
63 varArgs[i] = ac.convert(args[n+i]);
64 }
65 rtn[rtn.length-1] = varArgs;
66 }
67 for( int i=0; i<n; i++ ) {
68 rtn[i] = argConverters[i].convert(rtn[i]);
69 }
70 return rtn;
71 }
43 } 72 }
44 73
45 74
46 private interface RtnConverter { 75 private interface RtnConverter {
47 public Object[] convert(Object obj); 76 public Object[] convert(Object obj);
182 return obj; 211 return obj;
183 } 212 }
184 }; 213 };
185 214
186 private static ArgConverter[] getArgConverters(Method m) { 215 private static ArgConverter[] getArgConverters(Method m) {
216 final boolean isVarArgs = m.isVarArgs();
187 Class<?>[] paramTypes = m.getParameterTypes(); 217 Class<?>[] paramTypes = m.getParameterTypes();
188 ArgConverter[] a = new ArgConverter[paramTypes.length]; 218 ArgConverter[] a = new ArgConverter[paramTypes.length];
189 for( int i=0; i<a.length; i++ ) { 219 for( int i=0; i<a.length; i++ ) {
190 a[i] = getArgConverter(paramTypes[i]); 220 Class<?> paramType = paramTypes[i];
221 if( isVarArgs && i == a.length-1 )
222 paramType = paramType.getComponentType();
223 a[i] = getArgConverter(paramType);
191 } 224 }
192 return a; 225 return a;
193 } 226 }
194 227
195 private static ArgConverter getArgConverter(Class<?> cls) { 228 private static ArgConverter getArgConverter(Class<?> cls) {