diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index 1f8aa1900..8b2831063 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -36,76 +36,107 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; public class XwJNI { private static final String TAG = XwJNI.class.getSimpleName(); - public static class GamePtr implements AutoCloseable { - private long m_ptrGame = 0; + abstract static class PtrWrapper { + // This class provides ref counting and wrapping of a long that's + // really a pointer returned by jni code. In addition to the + // refcounting, which doesn't have to be used in a meaningful way, it + // provides type safety (avoids a long representing every jni + // datatype. BUT there's cost to the jni code calling back into java + // (the ptr() method) to get the long. I originally did this to wrap + // the long that represents DictIter state, then pulled that on + // noticing a slowdown in wordlist browsing. Still, I like having two + // classes here so I'm keeping that. + private long m_ptr; private int m_refCount = 0; - private long m_rowid; private String mStack; - private GamePtr( long ptr, long rowid ) + PtrWrapper( long ptr ) { - m_ptrGame = ptr; - m_rowid = rowid; - mStack = android.util.Log.getStackTraceString(new Exception()); - Quarantine.recordOpened( rowid ); + m_ptr = ptr; + if ( BuildConfig.DEBUG ) { + mStack = android.util.Log.getStackTraceString(new Exception()); + } } - public synchronized long ptr() + public long ptr() { - Assert.assertTrue( 0 != m_ptrGame ); - return m_ptrGame; + Assert.assertTrueNR( 0 != m_ptr ); + return m_ptr; } - public synchronized GamePtr retain() + public synchronized PtrWrapper retain() { ++m_refCount; - Log.d( TAG, "retain(this=%H, rowid=%d): refCount now %d", - this, m_rowid, m_refCount ); return this; } - public long getRowid() { return m_rowid; } + abstract void onFinalRelease( long ptr ); - // Force (via an assert in finalize() below) that this is called. It's + // Force (via an assert in finalize() below) that this is called. It's // better if jni stuff isn't being done on the finalizer thread public synchronized void release() { --m_refCount; - // Log.d( TAG, "%s.release(this=%H, rowid=%d): refCount now %d", - // getClass().getName(), this, m_rowid, m_refCount ); if ( 0 == m_refCount ) { - if ( 0 != m_ptrGame ) { - Quarantine.recordClosed( m_rowid ); - if ( haveEnv( getJNI().m_ptrGlobals ) ) { - game_dispose( this ); // will crash if haveEnv fails - } else { - Log.d( TAG, "release(): no ENV!!! (this=%H, rowid=%d)", - this, m_rowid ); - Assert.failDbg(); // seen on Play Store console - } - m_ptrGame = 0; - } + onFinalRelease( m_ptr ); + m_ptr = 0; } else { Assert.assertTrue( m_refCount > 0 || !BuildConfig.DEBUG ); } } + // @Override + public void finalize() throws java.lang.Throwable + { + if ( BuildConfig.DEBUG && (0 != m_refCount || 0 != m_ptr) ) { + Log.e( TAG, "finalize(): called prematurely: refCount: %d" + + "; ptr: %d; creator: %s", m_refCount, m_ptr, mStack ); + } + super.finalize(); + } + } + + public static class GamePtr extends PtrWrapper implements AutoCloseable { + private long m_rowid; + + private GamePtr( long ptr, long rowid ) + { + super( ptr ); + m_rowid = rowid; + Quarantine.recordOpened( rowid ); + } + + public long getRowid() { return m_rowid; } + + @Override + void onFinalRelease( long ptr ) + { + if ( 0 != ptr ) { + Quarantine.recordClosed( m_rowid ); + if ( haveEnv( getJNI().m_ptrGlobals ) ) { + game_dispose( this ); // will crash if haveEnv fails + } else { + Log.d( TAG, "release(): no ENV!!! (this=%H, rowid=%d)", + this, m_rowid ); + Assert.failDbg(); // seen on Play Store console + } + } + } + + public GamePtr retain() + { + super.retain(); + // Log.d( TAG, "retain(this=%H, rowid=%d): refCount now %d", + // this, m_rowid, m_refCount ); + return this; + } + @Override public void close() { release(); } - - // @Override - public void finalize() throws java.lang.Throwable - { - if ( BuildConfig.DEBUG && (0 != m_refCount || 0 != m_ptrGame) ) { - Log.e( TAG, "finalize(): called prematurely: refCount: %d" - + "; ptr: %d; creator: %s", m_refCount, m_ptrGame, mStack ); - } - super.finalize(); - } - } + } // GamePtr private static XwJNI s_JNI = null; private static synchronized XwJNI getJNI() @@ -559,5 +590,6 @@ public class XwJNI { String fromPhone, int wantPort); + // This always returns true on release builds now. private static native boolean haveEnv( long jniState ); } diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index c77ef7e1b..d74a7d77f 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -116,9 +116,9 @@ releaseMPool( JNIGlobalState* globalState ) #define GAMEPTR_IS_OBJECT #ifdef GAMEPTR_IS_OBJECT -typedef jobject GamePtrType; +typedef jobject PtrType; #else -typedef long GamePtrType; +typedef long PtrType; #endif #ifdef LOG_MAPPING @@ -347,8 +347,8 @@ tilesArrayToTileSet( JNIEnv* env, jintArray jtiles, TrayTileSet* tset ) } #ifdef GAMEPTR_IS_OBJECT -static JNIState* -getState( JNIEnv* env, GamePtrType gamePtr, const char* func ) +static void* +getState( JNIEnv* env, PtrType gamePtr, const char* func ) { #ifdef DEBUG if ( NULL == gamePtr ) { @@ -359,7 +359,7 @@ getState( JNIEnv* env, GamePtrType gamePtr, const char* func ) XP_ASSERT( NULL != gamePtr ); /* fired */ jmethodID mid = getMethodID( env, gamePtr, "ptr", "()J" ); XP_ASSERT( !!mid ); - return (JNIState*)(*env)->CallLongMethod( env, gamePtr, mid ); + return (void*)(*env)->CallLongMethod( env, gamePtr, mid ); } #else # define getState( env, gamePtr, func ) ((JNIState*)(gamePtr)) @@ -977,14 +977,17 @@ struct _JNIState { XP_U16 lastSavedSize; #ifdef DEBUG const char* envSetterFunc; + XP_U32 guard; #endif MPSLOT }; +#define GAME_GUARD 0x453627 #define XWJNI_START() { \ JNIState* state = getState( env, gamePtr, __func__ ); \ + XP_ASSERT( state->guard == GAME_GUARD ); \ MPSLOT; \ - MPASSIGN( mpool, state->mpool); \ + MPASSIGN( mpool, state->mpool ); \ XP_ASSERT( !!state->globalJNI ); \ MAP_THREAD( &state->globalJNI->ti, env ); \ @@ -1003,6 +1006,9 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGameJNI MemPoolCtx* mpool = ((JNIGlobalState*)jniGlobalPtr)->mpool; #endif JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) ); +#ifdef DEBUG + state->guard = GAME_GUARD; +#endif state->globalJNI = (JNIGlobalState*)jniGlobalPtr; MAP_THREAD( &state->globalJNI->ti, env ); AndGameGlobals* globals = &state->globals; @@ -1030,7 +1036,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_envDone JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject j_gi, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject j_gi, jobjectArray j_names, jobjectArray j_dicts, jobjectArray j_paths, jstring j_lang, jobject j_util, jobject j_draw, jobject j_cp, jobject j_procs ) @@ -1079,9 +1085,10 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame } /* makeNewGame */ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose -( JNIEnv* env, jclass claz, GamePtrType gamePtr ) +( JNIEnv* env, jclass claz, PtrType gamePtr ) { JNIState* state = getState( env, gamePtr, __func__ ); + XP_ASSERT( state->guard == GAME_GUARD ); #ifdef MEM_DEBUG MemPoolCtx* mpool = state->mpool; @@ -1099,12 +1106,15 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose MAP_REMOVE( &state->globalJNI->ti, env ); +#ifdef DEBUG + XP_MEMSET( state, -1, sizeof(*state) ); +#endif XP_FREE( mpool, state ); } /* game_dispose */ JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream -( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi, +( JNIEnv* env, jclass C, PtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi, jobjectArray jdictNames, jobjectArray jdicts, jobjectArray jpaths, jstring jlang, jobject jutil, jobject jdraw, jobject jcp, jobject jprocs ) { @@ -1161,7 +1171,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream JNIEXPORT jbyteArray JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi ) { jbyteArray result; XWJNI_START_GLOBALS(); @@ -1191,7 +1201,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveSucceeded -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); game_saveSucceeded( &state->game, env, state->curSaveCount ); @@ -1200,7 +1210,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveSucceeded JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jdraw ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jdraw ) { XWJNI_START_GLOBALS(); @@ -1215,7 +1225,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1invalAll -( JNIEnv *env, jclass C, GamePtrType gamePtr ) +( JNIEnv *env, jclass C, PtrType gamePtr ) { XWJNI_START(); board_invalAll( state->game.board ); @@ -1224,7 +1234,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1invalAll JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw -( JNIEnv *env, jclass C, GamePtrType gamePtr ) +( JNIEnv *env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1235,7 +1245,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1drawSnapshot -( JNIEnv *env, jclass C, GamePtrType gamePtr, jobject jdraw, jint width, +( JNIEnv *env, jclass C, PtrType gamePtr, jobject jdraw, jint width, jint height ) { XWJNI_START(); @@ -1248,7 +1258,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1drawSnapshot #ifdef COMMON_LAYOUT JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi, jint left, jint top, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi, jint left, jint top, jint width, jint height, jint scorePct, jint trayPct, jint scoreWidth, jint fontWidth, jint fontHt, jboolean squareTiles, jobject jdims ) { @@ -1271,7 +1281,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jdims ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jdims ) { XWJNI_START(); BoardDims dims; @@ -1284,7 +1294,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos -(JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top, jint width, +(JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top, jint width, jint height, jint maxCellSize, jboolean lefty ) { XWJNI_START(); @@ -1295,7 +1305,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1setScoreboardLoc -( JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top, +( JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top, jint width, jint height, jboolean divideHorizontally ) { XWJNI_START(); @@ -1306,7 +1316,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setScoreboardLoc JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1setTrayLoc -( JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top, +( JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top, jint width, jint height, jint minDividerWidth ) { XWJNI_START(); @@ -1318,7 +1328,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setTrayLoc JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint zoomBy, jbooleanArray jCanZoom ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint zoomBy, jbooleanArray jCanZoom ) { jboolean result; XWJNI_START(); @@ -1333,7 +1343,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom #ifdef XWFEATURE_ACTIVERECT JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1getActiveRect -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jrect, jintArray dims ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jrect, jintArray dims ) { jboolean result; XWJNI_START(); @@ -1358,7 +1368,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getActiveRect #ifdef POINTER_SUPPORT JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenDown -(JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy, jbooleanArray barray ) +(JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy, jbooleanArray barray ) { jboolean result; XWJNI_START(); @@ -1370,7 +1380,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenDown JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenMove -( JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy ) +( JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy ) { jboolean result; XWJNI_START(); @@ -1381,7 +1391,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenMove JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenUp -( JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy ) +( JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy ) { jboolean result; XWJNI_START(); @@ -1392,7 +1402,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenUp JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1containsPt -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint xx, jint yy ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint xx, jint yy ) { jboolean result; XWJNI_START(); @@ -1404,7 +1414,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1containsPt JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1juggleTray -(JNIEnv* env, jclass C, GamePtrType gamePtr ) +(JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1415,7 +1425,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1juggleTray JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1getTrayVisState -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jboolean result; XWJNI_START(); @@ -1426,7 +1436,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getTrayVisState JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1getSelPlayer -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jint result; XWJNI_START(); @@ -1437,7 +1447,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getSelPlayer JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1passwordProvided -(JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jstring jpasswd ) +(JNIEnv* env, jclass C, PtrType gamePtr, jint player, jstring jpasswd ) { jboolean result; XWJNI_START(); @@ -1450,7 +1460,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1passwordProvided JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1hideTray -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jboolean result; XWJNI_START(); @@ -1461,7 +1471,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1hideTray JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1showTray -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jboolean result; XWJNI_START(); @@ -1472,7 +1482,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1showTray JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1beginTrade -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1483,7 +1493,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1beginTrade JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1endTrade -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1494,7 +1504,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1endTrade JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1setBlankValue -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, +( JNIEnv* env, jclass C, PtrType gamePtr, jint player, jint col, jint row, jint tile ) { jboolean result; @@ -1506,7 +1516,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setBlankValue JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1517,7 +1527,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn -( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean phoniesConfirmed, +( JNIEnv* env, jclass C, PtrType gamePtr, jboolean phoniesConfirmed, jboolean turnConfirmed, jintArray jNewTiles ) { jboolean result; @@ -1538,7 +1548,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1flip -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jboolean result; XWJNI_START(); @@ -1549,7 +1559,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1flip JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1replaceTiles -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { jboolean result; XWJNI_START(); @@ -1560,7 +1570,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1replaceTiles JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1redoReplacedTiles -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1571,7 +1581,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1redoReplacedTiles JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1reset -(JNIEnv* env, jclass C, GamePtrType gamePtr ) +(JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); server_reset( state->game.server, env, state->game.comms ); @@ -1580,7 +1590,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1reset JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1handleUndo -(JNIEnv* env, jclass C, GamePtrType gamePtr) +(JNIEnv* env, jclass C, PtrType gamePtr) { XWJNI_START(); server_handleUndo( state->game.server, env, 0 ); @@ -1589,7 +1599,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1handleUndo JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1do -(JNIEnv* env, jclass C, GamePtrType gamePtr ) +(JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1601,7 +1611,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1do JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1tilesPicked -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jintArray jNewTiles ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint player, jintArray jNewTiles ) { XWJNI_START(); TrayTileSet newTiles; @@ -1612,7 +1622,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1tilesPicked JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1countTilesInPool -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jint result; XWJNI_START(); @@ -1623,7 +1633,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1countTilesInPool JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1resetEngine -(JNIEnv* env, jclass C, GamePtrType gamePtr ) +(JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); board_resetEngine( state->game.board ); @@ -1632,7 +1642,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1resetEngine JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1requestHint -( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean useLimits, +( JNIEnv* env, jclass C, PtrType gamePtr, jboolean useLimits, jboolean goBack, jbooleanArray workRemains ) { jboolean result; @@ -1654,7 +1664,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1requestHint JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_timerFired -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint why, jint when, jint handle ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint why, jint when, jint handle ) { jboolean result; XWJNI_START_GLOBALS(); @@ -1666,7 +1676,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_timerFired JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1formatRemainingTiles -(JNIEnv* env, jclass C, GamePtrType gamePtr ) +(JNIEnv* env, jclass C, PtrType gamePtr ) { jstring result; XWJNI_START_GLOBALS(); @@ -1682,7 +1692,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1formatRemainingTiles JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1formatDictCounts -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint nCols ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint nCols ) { jstring result; XWJNI_START_GLOBALS(); @@ -1696,7 +1706,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1formatDictCounts JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1getGameIsOver -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -1707,7 +1717,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1getGameIsOver JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_model_1writeGameHistory -( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean gameOver ) +( JNIEnv* env, jclass C, PtrType gamePtr, jboolean gameOver ) { jstring result; XWJNI_START_GLOBALS(); @@ -1722,7 +1732,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1writeGameHistory JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNMoves -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jint result; XWJNI_START(); @@ -1735,7 +1745,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNMoves JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNumTilesInTray -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint player ) { jint result; XWJNI_START(); @@ -1747,7 +1757,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNumTilesInTray JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jobject jlmi ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint player, jobject jlmi ) { XWJNI_START(); XP_ASSERT( !!state->game.model ); @@ -1768,7 +1778,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1writeFinalScores -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jstring result; XWJNI_START_GLOBALS(); @@ -1792,7 +1802,7 @@ and_send_on_close( XWStreamCtxt* stream, XWEnv xwe, void* closure ) JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1initClientConnection -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; LOG_FUNC(); @@ -1807,7 +1817,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1initClientConnection JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1start -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); CommsCtxt* comms = state->game.comms; @@ -1819,7 +1829,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1start JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1stop -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); CommsCtxt* comms = state->game.comms; @@ -1831,7 +1841,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1stop JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resetSame -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); if ( !!state->game.comms ) { @@ -1842,7 +1852,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resetSame JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr -(JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr ) +(JNIEnv* env, jclass C, PtrType gamePtr, jobject jaddr ) { XWJNI_START(); XP_ASSERT( state->game.comms ); @@ -1854,7 +1864,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr JNIEXPORT jobjectArray JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrs -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jobjectArray result = NULL; XWJNI_START(); @@ -1882,7 +1892,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrs JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1augmentHostAddr -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jaddr ) { XWJNI_START(); if ( state->game.comms ) { @@ -1897,7 +1907,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1augmentHostAddr JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage -( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject jaddr ) +( JNIEnv* env, jclass C, PtrType gamePtr, jbyteArray jstream, jobject jaddr ) { jboolean result; XWJNI_START_GLOBALS(); @@ -1922,7 +1932,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jsummary ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jsummary ) { XWJNI_START(); ModelCtxt* model = state->game.model; @@ -2016,7 +2026,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1server_1prefsChanged -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jcp ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jcp ) { jboolean result; XWJNI_START(); @@ -2034,7 +2044,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1server_1prefsChanged #ifdef KEYBOARD_NAV JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1getFocusOwner -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jint result; XWJNI_START(); @@ -2045,7 +2055,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getFocusOwner JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1focusChanged -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint typ ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint typ ) { jboolean result; XWJNI_START(); @@ -2058,7 +2068,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1focusChanged #ifdef KEYBOARD_NAV JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1handleKey -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jkey, jboolean jup, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jkey, jboolean jup, jbooleanArray jhandled ) { jboolean result; @@ -2080,7 +2090,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handleKey JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1getGi -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi ) { XWJNI_START_GLOBALS(); setJGI( env, jgi, globals->gi ); @@ -2109,7 +2119,7 @@ static const SetInfo gsi_bools[] = { JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgsi ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgsi ) { XWJNI_START(); GameStateInfo info; @@ -2123,7 +2133,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1hasComms -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -2135,7 +2145,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1hasComms #ifdef XWFEATURE_CHANGEDICT JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi, jstring jname, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi, jstring jname, jbyteArray jDictBytes, jstring jpath ) { XWJNI_START_GLOBALS(); @@ -2154,7 +2164,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict JNIEXPORT jint JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resendAll -( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean force, jobject jFilter, +( JNIEnv* env, jclass C, PtrType gamePtr, jboolean force, jobject jFilter, jboolean thenAck ) { jint result; @@ -2194,7 +2204,7 @@ onGotOne( void* closure, XWEnv xwe, XP_U8* msg, XP_U16 len, MsgID XP_UNUSED(msgI JNIEXPORT jobjectArray JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getPending -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jobjectArray result = NULL; XWJNI_START(); @@ -2215,7 +2225,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getPending #ifdef XWFEATURE_COMMSACK JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1ackAny -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); XP_ASSERT( !!state->game.comms ); @@ -2226,7 +2236,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1ackAny JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1transportFailed -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject failedTyp ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject failedTyp ) { XWJNI_START(); XP_ASSERT( !!state->game.comms ); @@ -2238,7 +2248,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1transportFailed JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1isConnected -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jboolean result; XWJNI_START(); @@ -2249,7 +2259,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1isConnected JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1formatRelayID -( JNIEnv* env, jclass C, GamePtrType gamePtr, jint indx ) +( JNIEnv* env, jclass C, PtrType gamePtr, jint indx ) { jstring result = NULL; XWJNI_START(); @@ -2268,7 +2278,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1formatRelayID JNIEXPORT jstring JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { jstring result = NULL; #ifdef DEBUG @@ -2287,7 +2297,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp ) +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp ) { LOG_FUNC(); XWJNI_START(); @@ -2302,7 +2312,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr #ifdef DEBUG JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddrDisabled -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp, jboolean forSend, jboolean val ) { XWJNI_START(); @@ -2316,7 +2326,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddrDisabled JNIEXPORT jboolean JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrDisabled -( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp, +( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp, jboolean forSend ) { jboolean result = XP_FALSE; @@ -2345,7 +2355,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_haveEnv JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame -( JNIEnv* env, jclass C, GamePtrType gamePtr ) +( JNIEnv* env, jclass C, PtrType gamePtr ) { XWJNI_START(); XP_ASSERT( !!state->game.server ); @@ -2354,7 +2364,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame } JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1pause -( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg ) +( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg ) { XWJNI_START(); XP_ASSERT( !!state->game.board ); @@ -2367,7 +2377,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1pause } JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1unpause -( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg ) +( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg ) { XWJNI_START(); XP_ASSERT( !!state->game.board ); @@ -2380,7 +2390,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1unpause #ifdef XWFEATURE_CHAT JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1sendChat -( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg ) +( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg ) { XWJNI_START(); XP_ASSERT( !!state->game.server ); @@ -2402,13 +2412,14 @@ typedef struct _DictIterData { DictIter iter; IndexData idata; XP_U16 depth; -#ifdef MEM_DEBUG - MemPoolCtx* mpool; +#ifdef DEBUG + XP_U32 guard; #endif } DictIterData; static void makeIndex( DictIterData* data ); static void freeIndices( DictIterData* data ); +#define GI_GUARD 0x89ab72 JNIEXPORT jlong JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_di_1init @@ -2428,34 +2439,43 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1init data->globalState = globalState; data->dict = dict; data->depth = 2; -#ifdef MEM_DEBUG - data->mpool = globalState->mpool; +#ifdef DEBUG + data->guard = GI_GUARD; #endif closure = (jlong)data; } return closure; } + +#define DI_HEADER() { \ + DictIterData* data = (DictIterData*)closure; \ + XP_ASSERT( NULL == data || data->guard == GI_GUARD ); \ + +#define DI_HEADER_END() \ + } + JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_di_1setMinMax ( JNIEnv* env, jclass C, jlong closure, jint min, jint max ) { - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { di_initIter( &data->iter, data->dict, min, max ); makeIndex( data ); (void)di_firstWord( &data->iter ); } + DI_HEADER_END(); } JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_di_1destroy ( JNIEnv* env, jclass C, jlong closure ) { - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { #ifdef MEM_DEBUG - MemPoolCtx* mpool = data->mpool; + MemPoolCtx* mpool = data->globalState->mpool; #endif dict_unref( data->dict, env ); freeIndices( data ); @@ -2464,6 +2484,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1destroy XP_FREE( mpool, data ); } + DI_HEADER_END(); } JNIEXPORT jint JNICALL @@ -2471,10 +2492,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1wordCount (JNIEnv* env, jclass C, jlong closure ) { jint result = 0; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { result = data->iter.nWords; } + DI_HEADER_END(); return result; } @@ -2483,7 +2505,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getCounts (JNIEnv* env, jclass C, jlong closure ) { jintArray result = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { DictIter iter; di_initIter( &iter, data->dict, 0, MAX_COLS_DICT ); @@ -2495,6 +2517,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getCounts sizeof(lens.lens[0]) ); } } + DI_HEADER_END(); return result; } @@ -2503,7 +2526,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getPrefixes ( JNIEnv* env, jclass C, jlong closure ) { jobjectArray result = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data && NULL != data->idata.prefixes ) { result = makeStringArray( env, data->idata.count, NULL ); @@ -2518,6 +2541,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getPrefixes deleteLocalRef( env, jstr ); } } + DI_HEADER_END(); return result; } @@ -2526,7 +2550,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getIndices ( JNIEnv* env, jclass C, jlong closure ) { jintArray jindices = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { XP_ASSERT( !!data->idata.indices ); XP_ASSERT( sizeof(jint) == sizeof(data->idata.indices[0]) ); @@ -2534,6 +2558,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getIndices (jint*)data->idata.indices, sizeof(data->idata.indices[0]) ); } + DI_HEADER_END(); return jindices; } @@ -2542,7 +2567,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord ( JNIEnv* env, jclass C, jlong closure, jint nn, jstring jdelim ) { jstring result = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { if ( di_getNthWord( &data->iter, nn, data->depth, &data->idata ) ) { XP_UCHAR buf[64]; @@ -2555,6 +2580,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord } } } + DI_HEADER_END(); return result; } @@ -2578,7 +2604,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1strToTiles ( JNIEnv* env, jclass C, jlong closure, jstring jstr ) { jobjectArray result = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); const char* str = (*env)->GetStringUTFChars( env, jstr, NULL ); FTData ftd = { .env = env, }; @@ -2593,7 +2619,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1strToTiles } (*env)->ReleaseStringUTFChars( env, jstr, str ); - + DI_HEADER_END(); return result; } @@ -2602,7 +2628,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getStartsWith ( JNIEnv* env, jclass C, jlong closure, jbyteArray jtiles ) { jint result = -1; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); XP_U16 nTiles = (*env)->GetArrayLength( env, jtiles ); jbyte* tiles = (*env)->GetByteArrayElements( env, jtiles, NULL ); @@ -2611,7 +2637,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getStartsWith } (*env)->ReleaseByteArrayElements( env, jtiles, tiles, 0 ); - + DI_HEADER_END(); return result; } @@ -2620,13 +2646,12 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1tilesToStr ( JNIEnv* env, jclass C, jlong closure, jbyteArray jtiles, jstring jdelim ) { jstring result = NULL; - + DI_HEADER(); XP_UCHAR buf[64]; const XP_UCHAR* delim = NULL; if ( !!jdelim ) { delim = (*env)->GetStringUTFChars( env, jdelim, NULL ); } - DictIterData* data = (DictIterData*)closure; XP_U16 nTiles = (*env)->GetArrayLength( env, jtiles ); jbyte* tiles = (*env)->GetByteArrayElements( env, jtiles, NULL ); @@ -2642,7 +2667,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1tilesToStr (*env)->ReleaseStringUTFChars( env, jdelim, delim ); } (*env)->ReleaseByteArrayElements( env, jtiles, tiles, 0 ); - + DI_HEADER_END(); return result; } @@ -2651,13 +2676,14 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getDesc ( JNIEnv* env, jclass C, jlong closure ) { jstring result = NULL; - DictIterData* data = (DictIterData*)closure; + DI_HEADER(); if ( NULL != data ) { const XP_UCHAR* disc = dict_getDesc( data->dict ); if ( NULL != disc && '\0' != disc[0] ) { result = (*env)->NewStringUTF( env, disc ); } } + DI_HEADER_END(); return result; } @@ -2666,11 +2692,11 @@ freeIndices( DictIterData* data ) { IndexData* idata = &data->idata; if ( !!idata->prefixes ) { - XP_FREE( data->mpool, idata->prefixes ); + XP_FREE( data->globalState->mpool, idata->prefixes ); idata->prefixes = NULL; } if( !!idata->indices ) { - XP_FREE( data->mpool, idata->indices ); + XP_FREE( data->globalState->mpool, idata->indices ); idata->indices = NULL; } } @@ -2688,18 +2714,20 @@ makeIndex( DictIterData* data ) freeIndices( data ); IndexData* idata = &data->idata; - idata->prefixes = XP_MALLOC( data->mpool, count * data->depth +#ifdef MEM_DEBUG + MemPoolCtx* mpool = data->globalState->mpool; +#endif + idata->prefixes = XP_MALLOC( mpool, count * data->depth * sizeof(*idata->prefixes) ); - idata->indices = XP_MALLOC( data->mpool, - count * sizeof(*idata->indices) ); + idata->indices = XP_MALLOC( mpool, count * sizeof(*idata->indices) ); idata->count = count; di_makeIndex( &data->iter, data->depth, idata ); if ( 0 < idata->count ) { - idata->prefixes = XP_REALLOC( data->mpool, idata->prefixes, + idata->prefixes = XP_REALLOC( mpool, idata->prefixes, idata->count * data->depth * sizeof(*idata->prefixes) ); - idata->indices = XP_REALLOC( data->mpool, idata->indices, + idata->indices = XP_REALLOC( mpool, idata->indices, idata->count * sizeof(*idata->indices) ); } else { freeIndices( data );