}
case CREATEPROXY: {
final int niface = args.narg()-1;
if ( niface <= 0 )
throw new LuaError("no interfaces");
final LuaValue lobj = args.checktable(niface+1);
// get the interfaces
final Class[] ifaces = new Class[niface];
for ( int i=0; i<niface; i++ )
ifaces[i] = classForName(args.checkjstring(i+1));
// create the invocation handler
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
LuaValue func = lobj.get(name);
if ( func.isnil() )
return null;
boolean isvarargs = ((method.getModifiers() & METHOD_MODIFIERS_VARARGS) != 0);
int n = args!=null? args.length: 0;
LuaValue[] v;
if ( isvarargs ) {
Object o = args[--n];
int m = Array.getLength( o );
v = new LuaValue[n+m];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
for ( int i=0; i<m; i++ )
v[i+n] = CoerceJavaToLua.coerce(Array.get(o,i));
} else {
v = new LuaValue[n];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
}
LuaValue result = func.invoke(v).arg1();
return CoerceLuaToJava.coerce(result, method.getReturnType());
}
};
// create the proxy object
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);
// return the proxy
return LuaValue.userdataOf( proxy );
}
case LOADLIB: {
// get constructor
String classname = args.checkjstring(1);
String methodname = args.checkjstring(2);
Class clazz = classForName(classname);
Method method = clazz.getMethod(methodname, new Class[] {});
Object result = method.invoke(clazz, new Object[] {});
if ( result instanceof LuaValue ) {
return (LuaValue) result;
} else {
return NIL;
}
}
default:
throw new LuaError("not yet supported: "+this);
}
} catch (LuaError e) {
throw e;
} catch (InvocationTargetException ite) {
throw new LuaError(ite.getTargetException());
} catch (Exception e) {
throw new LuaError(e);
}
}