diff --git a/jni/luajava/luajava.c b/jni/luajava/luajava.c index 08d86f3..f5b3b1d 100755 --- a/jni/luajava/luajava.c +++ b/jni/luajava/luajava.c @@ -33,6 +33,9 @@ * *****************************************************************************/ +// Ignore two warnings that, in this file, are false positives +#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" #include #include @@ -51,6 +54,8 @@ #define LUAJAVASTATEINDEX "LuaJavaStateIndex" /* Index metamethod name */ #define LUAINDEXMETAMETHODTAG "__index" +/* Length metamethod name */ +#define LUALENMETAMETHODTAG "__len" /* New index metamethod name */ #define LUANEWINDEXMETAMETHODTAG "__newindex" /* Garbage collector metamethod name */ @@ -741,6 +746,27 @@ int classIndex( lua_State * L ) return ret; } +/* Function: arrayLen */ +int arrayLen( lua_State * L ) +{ + lua_Number stateIndex; + JNIEnv * javaEnv; + jobject obj; + + javaEnv = getEnvFromState( L ); + stateIndex = getLuaStateIndex( L ); + + if ( !isJavaObject( L , 1 ) ) + { + lua_pushstring( L , "Not a valid Java Object." ); + lua_error( L ); + } + + obj = lua_jobject( L , 1 ); + + lua_pushnumber(L,(*javaEnv)->GetArrayLength(javaEnv, obj)); + return 1; +} /*************************************************************************** * @@ -1241,6 +1267,11 @@ int pushJavaArray( lua_State * L , jobject javaObject, JNIEnv * javaEnv ) lua_pushcfunction( L , &arrayIndex ); lua_rawset( L , -3 ); + /* pushes the __len metamethod */ + lua_pushstring( L , LUALENMETAMETHODTAG ); + lua_pushcfunction( L , &arrayLen ); + lua_rawset( L , -3 ); + /* pushes the __fallback metamethod (used for non-integer keys*/ lua_pushstring( L , "__fallback" ); lua_pushlightuserdata( L , javaEnv); diff --git a/src/org/keplerproject/luajava/LuaObject.java b/src/org/keplerproject/luajava/LuaObject.java index 36d4b62..86d4c0d 100755 --- a/src/org/keplerproject/luajava/LuaObject.java +++ b/src/org/keplerproject/luajava/LuaObject.java @@ -27,6 +27,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.StringTokenizer; +import java.util.Vector; /** * This class represents a Lua object of any type. A LuaObject is constructed by a {@link LuaState} object using one of @@ -51,12 +52,16 @@ * @author Rizzato * @author Thiago Ponte */ +@SuppressWarnings("rawtypes") public class LuaObject { protected Integer ref; + protected LuaState L; static int REGISTRYINDEX = LuaState.LUA_REGISTRYINDEX.intValue(); + protected static Vector m_toDelete = new Vector(); + /** * Creates a reference to an object in the variable globalName * @@ -71,6 +76,18 @@ protected LuaObject(LuaState L, String globalName) L.getGlobal(globalName); registerValue(-1); L.pop(1); + + synchronized (m_toDelete) + { + if (L.getCPtrPeer() != 0) + { + for (int i : m_toDelete) + { + L.LunRef(REGISTRYINDEX,i); + } + m_toDelete.clear(); + } + } } } @@ -89,7 +106,7 @@ protected LuaObject(LuaObject parent, String name) throws LuaException this.L = parent.getLuaState(); if (!parent.isTable() && !parent.isUserdata()) - { + { LuaJavaAPI.throwLuaException(parent.L,"Object parent should be a table or userdata ."); } @@ -199,7 +216,7 @@ private void registerValue(int index) ref = new Integer(key); } } - + public int getRef() { return (int)ref; @@ -209,10 +226,9 @@ protected void finalize() { try { - synchronized (L) + synchronized (m_toDelete) { - if (L.getCPtrPeer() != 0) - L.LunRef(REGISTRYINDEX, ref.intValue()); + m_toDelete.add(ref); } } catch (Exception e) @@ -220,7 +236,7 @@ protected void finalize() System.err.println("Unable to release object " + ref); } } - + public static LuaObject fromReference(LuaState L, int ref) { L.rawGetI(REGISTRYINDEX, ref); LuaObject obj = new LuaObject(L,-1); @@ -409,11 +425,11 @@ public LuaObject getField(String field) throws LuaException * @return Object[] - Returned Objects * @throws LuaException */ - public Object[] call(Object[] args, int nres) throws LuaException - { + public Object[] call(Object[] args, int nres) throws LuaException + { return call(args,nres,false); } - + public Object[] call(Object[] args, int nres, boolean trace) throws LuaException { synchronized (L)