From: stephan Date: Sun, 6 Aug 2023 13:02:43 +0000 (+0000) Subject: JNI-internal cleanups and API renaming. Add a C-side java-string-to-utf8 conversion. X-Git-Tag: version-3.43.0~47^2~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c4c16c80d34c1648e3afa91bc6bda418348fe7b;p=thirdparty%2Fsqlite.git JNI-internal cleanups and API renaming. Add a C-side java-string-to-utf8 conversion. FossilOrigin-Name: 672d85795d04131135b1dc6a02d64eceb8b5084217c17766afeca4af23c07ec4 --- diff --git a/ext/jni/GNUmakefile b/ext/jni/GNUmakefile index d3b376ba0e..98ea80bb8d 100644 --- a/ext/jni/GNUmakefile +++ b/ext/jni/GNUmakefile @@ -128,7 +128,6 @@ $(sqlite3.c): $(sqlite3.h) SQLITE_OPT := \ -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ - -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ -DSQLITE_ENABLE_STMTVTAB \ -DSQLITE_ENABLE_DBPAGE_VTAB \ -DSQLITE_ENABLE_DBSTAT_VTAB \ @@ -137,7 +136,6 @@ SQLITE_OPT := \ -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_OMIT_DEPRECATED \ -DSQLITE_OMIT_SHARED_CACHE \ - -DSQLITE_OMIT_WAL \ -DSQLITE_THREADSAFE=0 \ -DSQLITE_TEMP_STORE=2 \ -DSQLITE_USE_URI=1 \ @@ -147,7 +145,7 @@ SQLITE_OPT := \ # for a var which gets set in all builds but only read # via assert(). -SQLITE_OPFS += -g -DDEBUG -UNDEBUG +SQLITE_OPT += -g -DDEBUG -UNDEBUG ifeq (1,$(enable.fts5)) SQLITE_OPT += -DSQLITE_ENABLE_FTS5 diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index 0e50e20f22..c2c99d8890 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -37,11 +37,9 @@ #if !defined(SQLITE_DEFAULT_PAGE_SIZE) # define SQLITE_DEFAULT_PAGE_SIZE 8192 #endif -#ifndef SQLITE_DEFAULT_UNIX_VFS -# define SQLITE_DEFAULT_UNIX_VFS "unix" +#ifndef SQLITE_DQS +# define SQLITE_DQS 0 #endif -#undef SQLITE_DQS -#define SQLITE_DQS 0 /**********************************************************************/ /* SQLITE_ENABLE_... */ @@ -57,11 +55,6 @@ #ifndef SQLITE_ENABLE_EXPLAIN_COMMENTS # define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 #endif -#ifdef SQLITE_ENABLE_FTS5 -# ifndef SQLITE_ENABLE_FTS4 -# define SQLITE_ENABLE_FTS4 1 -# endif -#endif #ifndef SQLITE_ENABLE_MATH_FUNCTIONS # define SQLITE_ENABLE_MATH_FUNCTIONS 1 #endif @@ -74,15 +67,15 @@ #ifndef SQLITE_ENABLE_RTREE # define SQLITE_ENABLE_RTREE 1 #endif -#ifndef SQLITE_ENABLE_SESSION -# define SQLITE_ENABLE_SESSION 1 -#endif +//#ifndef SQLITE_ENABLE_SESSION +//# define SQLITE_ENABLE_SESSION 1 +//#endif #ifndef SQLITE_ENABLE_STMTVTAB # define SQLITE_ENABLE_STMTVTAB 1 #endif -#ifndef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -# define SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -#endif +//#ifndef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +//# define SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +//#endif /**********************************************************************/ /* SQLITE_M... */ @@ -160,8 +153,8 @@ JFuncName(Suffix) /* First 2 parameters to all JNI bindings. */ #define JENV_JSELF JNIEnv * const env, jobject jSelf -/* Helpers to squelch -Xcheck:jni warnings about - not having checked for exceptions. */ +/* Helpers to account for -Xcheck:jni warnings about not having + checked for exceptions. */ #define IFTHREW if((*env)->ExceptionCheck(env)) #define EXCEPTION_IGNORE (void)((*env)->ExceptionCheck(env)) #define EXCEPTION_CLEAR (*env)->ExceptionClear(env) @@ -337,41 +330,41 @@ struct NphCacheLine { Whereas we cache new refs for each thread. */ -typedef struct JNIEnvCacheLine JNIEnvCacheLine; -struct JNIEnvCacheLine { +typedef struct JNIEnvCache JNIEnvCache; +struct JNIEnvCache { JNIEnv *env /* env in which this cache entry was created */; //! The various refs to global classes might be cacheable a single // time globally. Information online seems inconsistent on that // point. struct { - jclass cObj /* global ref to java.lang.Object */; - jclass cLong /* global ref to java.lang.Long */; - jclass cString /* global ref to java.lang.String */; - jobject oCharsetUtf8 /* global ref to StandardCharset.UTF_8 */; - jmethodID ctorLong1 /* the Long(long) constructor */; - jmethodID ctorStringBA /* the String(byte[],Charset) constructor */; + jclass cObj /* global ref to java.lang.Object */; + jclass cLong /* global ref to java.lang.Long */; + jclass cString /* global ref to java.lang.String */; + jobject oCharsetUtf8 /* global ref to StandardCharset.UTF_8 */; + jmethodID ctorLong1 /* the Long(long) constructor */; + jmethodID ctorStringBA /* the String(byte[],Charset) constructor */; + jmethodID stringGetBytes /* the String.getBytes(Charset) method */; } g; - jobject currentStmt /* Current Java sqlite3_stmt object being - prepared, stepped, reset, or - finalized. Needed for tracing, the - alternative being that we create a new - sqlite3_stmt wrapper object for every - tracing call which needs a stmt - object. This approach is rather invasive, - however, requiring code in all stmt - operations which can lead through the - tracing API. */; + jobject currentStmt /* Current Java sqlite3_stmt object being + prepared, stepped, reset, or + finalized. Needed for tracing, the + alternative being that we create a new + sqlite3_stmt wrapper object for every tracing + call which needs a stmt object. This approach + is rather invasive, however, requiring code + in all stmt operations which can lead through + the tracing API. */; #ifdef SQLITE_ENABLE_FTS5 - jobject jFtsExt /* Global ref to Java singleton for the - Fts5ExtensionApi instance. */; + jobject jFtsExt /* Global ref to Java singleton for the + Fts5ExtensionApi instance. */; struct { jclass klazz; jfieldID fidA; jfieldID fidB; } jPhraseIter; #endif - JNIEnvCacheLine * pPrev /* Previous entry in the linked list */; - JNIEnvCacheLine * pNext /* Next entry in the linked list */; + JNIEnvCache * pPrev /* Previous entry in the linked list */; + JNIEnvCache * pNext /* Next entry in the linked list */; /** TODO: NphCacheLine *pNphHit; to help fast-track cache lookups, update this to point to the @@ -445,8 +438,8 @@ static struct { */ JavaVM * jvm; struct { - JNIEnvCacheLine * aHead /* Linked list of in-use instances */; - JNIEnvCacheLine * aFree /* Linked list of free instances */; + JNIEnvCache * aHead /* Linked list of in-use instances */; + JNIEnvCache * aFree /* Linked list of free instances */; } envCache; struct { PerDbStateJni * aUsed /* Linked list of in-use instances */; @@ -550,14 +543,14 @@ static void s3jni_call_xDestroy(JNIEnv * const env, jobject jObj, jclass klazz){ standard UTF-8 to a Java string, but JNI offers only algorithms for working with MUTF-8, not UTF-8. */ -static jstring s3jni_string_from_utf8(JNIEnvCacheLine * const jc, - const char * const z, int n){ +static jstring s3jni_utf8_to_jstring(JNIEnvCache * const jc, + const char * const z, int n){ jstring rv = NULL; JNIEnv * const env = jc->env; - if( 0==n || (z && !z[0]) ){ - /* Fast-track the empty-string case. We could hypothetically do - this for any strings where n<4 and z is NUL-terminated and none - of z[0..3] are NUL bytes. */ + if( 0==n || (n<0 && z && !z[0]) ){ + /* Fast-track the empty-string case via the MUTF-8 API. We could + hypothetically do this for any strings where n<4 and z is + NUL-terminated and none of z[0..3] are NUL bytes. */ rv = (*env)->NewStringUTF(env, ""); }else if( z ){ jbyteArray jba; @@ -573,6 +566,45 @@ static jstring s3jni_string_from_utf8(JNIEnvCacheLine * const jc, return rv; } +/** + Converts the given java.lang.String object into a NUL-terminated + UTF-8 C-string by calling jstr.getBytes(StandardCharset.UTF_8). + Returns NULL if jstr is NULL or on allocation error. If jstr is not + NULL and nLen is not NULL then nLen is set to the length of the + returned string, not including the terminating NUL. If jstr is not + NULL and it returns NULL, this indicates an allocation error. In + that case, if nLen is not NULL then it is either set to 0 (if + fetching of jstr's bytes fails to allocate) or set to what would + have been the length of the string had C-string allocation + succeeded. +*/ +static char * s3jni_jstring_to_utf8(JNIEnvCache * const jc, + jstring jstr, int *nLen){ + JNIEnv * const env = jc->env; + jbyteArray jba; + jsize nBa; + char *rv; + + if(!jstr) return 0; + jba = (*env)->CallObjectMethod(env, jstr, jc->g.stringGetBytes, + jc->g.oCharsetUtf8); + if( (*env)->ExceptionCheck(env) || !jba + /* order of these checks is significant for -Xlint:jni */ ) { + EXCEPTION_REPORT; + if( nLen ) *nLen = 0; + return 0; + } + nBa = (*env)->GetArrayLength(env, jba); + if( nLen ) *nLen = (int)nBa; + rv = sqlite3_malloc( nBa + 1 ); + if( rv ){ + (*env)->GetByteArrayRegion(env, jba, 0, nBa, (jbyte*)rv); + rv[nBa] = 0; + } + UNREF_L(jba); + return rv; +} + /** Fetches the S3Global.envCache row for the given env, allocing a row if needed. When a row is allocated, its state is initialized @@ -580,8 +612,8 @@ static jstring s3jni_string_from_utf8(JNIEnvCacheLine * const jc, an entry fails. That's hypothetically possible but "shouldn't happen." */ FIXME_THREADING -static JNIEnvCacheLine * S3Global_JNIEnvCache_cache(JNIEnv * const env){ - struct JNIEnvCacheLine * row = S3Global.envCache.aHead; +static JNIEnvCache * S3Global_env_cache(JNIEnv * const env){ + struct JNIEnvCache * row = S3Global.envCache.aHead; for( ; row; row = row->pNext ){ if( row->env == env ){ ++S3Global.metrics.envCacheHits; @@ -595,7 +627,7 @@ static JNIEnvCacheLine * S3Global_JNIEnvCache_cache(JNIEnv * const env){ S3Global.envCache.aFree = row->pNext; if( row->pNext ) row->pNext->pPrev = 0; }else{ - row = sqlite3_malloc(sizeof(JNIEnvCacheLine)); + row = sqlite3_malloc(sizeof(JNIEnvCache)); if( !row ){ (*env)->FatalError(env, "Maintenance required: JNIEnvCache is full.") /* Does not return, but cc doesn't know that */; @@ -624,6 +656,10 @@ static JNIEnvCacheLine * S3Global_JNIEnvCache_cache(JNIEnv * const env){ (*env)->GetMethodID(env, row->g.cString, "", "([BLjava/nio/charset/Charset;)V"); EXCEPTION_IS_FATAL("Error getting reference to String(byte[],Charset) ctor."); + row->g.stringGetBytes = + (*env)->GetMethodID(env, row->g.cString, + "getBytes", "(Ljava/nio/charset/Charset;)[B"); + EXCEPTION_IS_FATAL("Error getting reference to String.getBytes(Charset)."); { /* StandardCharsets.UTF_8 */ jfieldID fUtf8; @@ -702,7 +738,7 @@ static void PerDbStateJni_set_aside(PerDbStateJni * const s){ Requires that p has been snipped from any linked list it is in. Clears all Java refs p holds and zeroes out p. */ -static void JNIEnvCacheLine_clear(JNIEnvCacheLine * const p){ +static void JNIEnvCache_clear(JNIEnvCache * const p){ JNIEnv * const env = p->env; if(env){ int i; @@ -718,7 +754,7 @@ static void JNIEnvCacheLine_clear(JNIEnvCacheLine * const p){ for( i = 0; i < NphCache_SIZE; ++i ){ NphCacheLine_clear(env, &p->nph[i]); } - memset(p, 0, sizeof(JNIEnvCacheLine)); + memset(p, 0, sizeof(JNIEnvCache)); } } @@ -750,8 +786,8 @@ static void PerDbStateJni_free_for_env(JNIEnv *env){ Also passes env to PerDbStateJni_free_for_env() to free up what would otherwise be stale references. */ -static int S3Global_JNIEnvCache_uncache(JNIEnv * const env){ - struct JNIEnvCacheLine * row = S3Global.envCache.aHead; +static int S3Global_env_uncache(JNIEnv * const env){ + struct JNIEnvCache * row = S3Global.envCache.aHead; for( ; row; row = row->pNext ){ if( row->env == env ){ break; @@ -764,7 +800,7 @@ static int S3Global_JNIEnvCache_uncache(JNIEnv * const env){ assert( !row->pPrev ); S3Global.envCache.aHead = row->pNext; } - JNIEnvCacheLine_clear(row); + JNIEnvCache_clear(row); assert( !row->pNext ); assert( !row->pPrev ); row->pNext = S3Global.envCache.aFree; @@ -776,7 +812,7 @@ static int S3Global_JNIEnvCache_uncache(JNIEnv * const env){ static void S3Global_JNIEnvCache_clear(void){ while( S3Global.envCache.aHead ){ - S3Global_JNIEnvCache_uncache( S3Global.envCache.aHead->env ); + S3Global_env_uncache( S3Global.envCache.aHead->env ); } } @@ -813,7 +849,7 @@ static struct NphCacheLine * S3Global_nph_cache(JNIEnv * const env, const char * looking up class objects can be expensive, so they should be cached as well. */ - struct JNIEnvCacheLine * const envRow = S3Global_JNIEnvCache_cache(env); + struct JNIEnvCache * const envRow = S3Global_env_cache(env); struct NphCacheLine * freeSlot = 0; struct NphCacheLine * cacheLine = 0; int i; @@ -1413,7 +1449,7 @@ static int udf_args(JNIEnv *env, *jArgv = 0; if(!jcx) goto error_oom; ja = (*env)->NewObjectArray(env, argc, - S3Global_JNIEnvCache_cache(env)->g.cObj, + S3Global_env_cache(env)->g.cObj, NULL); if(!ja) goto error_oom; for(i = 0; i < argc; ++i){ @@ -2063,41 +2099,25 @@ JDECL(jint,1create_1function)(JENV_JSELF, jobject jDb, jstring jFuncName, } -JDECL(jbyteArray,1db_1filename)(JENV_JSELF, jobject jDb, jbyteArray jDbName){ -#if 1 +JDECL(jstring,1db_1filename)(JENV_JSELF, jobject jDb, jstring jDbName){ PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0); - jbyte *zFilename = (ps && jDbName) ? JBA_TOC(jDbName) : 0; - const char *zRv; - jbyteArray jRv = 0; - - if( !ps || (jDbName && !zFilename) ) return 0; - zRv = sqlite3_db_filename(ps->pDb, (const char *)zFilename); - if( zRv ){ - const int n = sqlite3Strlen30(zRv); - jRv = (*env)->NewByteArray(env, (jint)n); - if( jRv ){ - (*env)->SetByteArrayRegion(env, jRv, 0, (jint)n, (const jbyte *)zRv); + JNIEnvCache * const jc = S3Global_env_cache(env); + char *zDbName; + jstring jRv = 0; + int nStr = 0; + + if( !ps || !jDbName ){ + return 0; + } + zDbName = s3jni_jstring_to_utf8(jc, jDbName, &nStr); + if( zDbName ){ + char const * zRv = sqlite3_db_filename(ps->pDb, zDbName); + sqlite3_free(zDbName); + if( zRv ){ + jRv = s3jni_utf8_to_jstring(jc, zRv, -1); } } - JBA_RELEASE(jDbName, zFilename); return jRv; -#else - /* For comparison, this impl expects a jstring jDbName and returns a - jstring for significant code savings but it's not - MUTF-8-safe. With this impl, the Java-side byte-array-using - sqlite3_db_filename() impl is unnecessary. */ - JDECL(jstring,1db_1filename)(JENV_JSELF, jobject jDb, jstring jDbName){ - PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0); - const char *zFilename = (ps && jDbName) ? JSTR_TOC(jDbName) : 0; - const char *zRv; - - if( !ps || (jDbName && !zFilename)) return 0; - zRv = sqlite3_db_filename(ps->pDb, zFilename ? zFilename : "main"); - JSTR_RELEASE(jDbName, zFilename); - return zRv ? (*env)->NewStringUTF(env, zRv) : 0; -} -#endif - } JDECL(jstring,1errmsg)(JENV_JSELF, jobject jpDb){ @@ -2127,7 +2147,7 @@ JDECL(jint,1initialize)(JENV_JSELF){ is needed for certain tracing flags. At a minumum those ops are: step, reset, finalize, prepare. */ -static jobject stmt_set_current(JNIEnvCacheLine * const jc, jobject jStmt){ +static jobject stmt_set_current(JNIEnvCache * const jc, jobject jStmt){ jobject const old = jc->currentStmt; jc->currentStmt = jStmt; return old; @@ -2137,7 +2157,7 @@ JDECL(jint,1finalize)(JENV_JSELF, jobject jpStmt){ int rc = 0; sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); if( pStmt ){ - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); jobject const pPrev = stmt_set_current(jc, jpStmt); rc = sqlite3_finalize(pStmt); setNativePointer(env, jpStmt, 0, S3ClassNames.sqlite3_stmt); @@ -2208,7 +2228,7 @@ static jint sqlite3_jni_prepare_v123(int prepVersion, JNIEnv * const env, jclass sqlite3_stmt * pStmt = 0; const char * zTail = 0; jbyte * const pBuf = JBA_TOC(baSql); - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); jobject const pOldStmt = stmt_set_current(jc, jOutStmt); int rc = SQLITE_ERROR; assert(prepVersion==1 || prepVersion==2 || prepVersion==3); @@ -2303,7 +2323,7 @@ JDECL(jint,1reset)(JENV_JSELF, jobject jpStmt){ int rc = 0; sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); if( pStmt ){ - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); jobject const pPrev = stmt_set_current(jc, jpStmt); rc = sqlite3_reset(pStmt); (void)stmt_set_current(jc, pPrev); @@ -2571,7 +2591,7 @@ JDECL(jint,1step)(JENV_JSELF,jobject jStmt){ int rc = SQLITE_MISUSE; sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt); if(pStmt){ - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); jobject const jPrevStmt = stmt_set_current(jc, jStmt); rc = sqlite3_step(pStmt); (void)stmt_set_current(jc, jPrevStmt); @@ -2585,11 +2605,11 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){ jobject jX = NULL /* the tracer's X arg */; jobject jP = NULL /* the tracer's P arg */; jobject jPUnref = NULL /* potentially a local ref to jP */; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); int rc; switch(traceflag){ case SQLITE_TRACE_STMT: - jX = s3jni_string_from_utf8(jc, (const char *)pX, -1); + jX = s3jni_utf8_to_jstring(jc, (const char *)pX, -1); if(!jX) return SQLITE_NOMEM; jP = jc->currentStmt; break; @@ -2841,6 +2861,7 @@ JDECL(void,1do_1something_1for_1developer)(JENV_JSELF){ #define SO(T) printf("\tsizeof(" #T ") = %u\n", (unsigned)sizeof(T)) SO(void*); SO(JniHookState); + SO(JNIEnvCache); SO(PerDbStateJni); SO(S3Global); SO(S3ClassNames); @@ -2964,7 +2985,7 @@ static inline jobject new_fts5_api_wrapper(JNIEnv * const env, fts5_api *sv){ instance, or NULL on OOM. */ static jobject s3jni_getFts5ExensionApi(JNIEnv * const env){ - JNIEnvCacheLine * const row = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const row = S3Global_env_cache(env); if( !row->jFtsExt ){ row->jFtsExt = new_NativePointerHolder_object(env, S3ClassNames.Fts5ExtensionApi, s3jni_ftsext()); @@ -3031,8 +3052,8 @@ JDECLFtsXA(jint,xColumnText)(JENV_JSELF,jobject jCtx, jint iCol, int rc = fext->xColumnText(PtrGet_Fts5Context(jCtx), (int)iCol, &pz, &pn); if( 0==rc ){ - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); - jstring jstr = pz ? s3jni_string_from_utf8(jc, pz, pn) : 0; + JNIEnvCache * const jc = S3Global_env_cache(env); + jstring jstr = pz ? s3jni_utf8_to_jstring(jc, pz, pn) : 0; if( pz ){ if( jstr ){ setOutputString(env, jOut, jstr); @@ -3188,7 +3209,7 @@ JDECLFtsXA(jint,xPhraseCount)(JENV_JSELF,jobject jCtx){ /** Initializes jc->jPhraseIter if it needed it. */ -static void s3jni_phraseIter_init(JNIEnv *const env, JNIEnvCacheLine * const jc, +static void s3jni_phraseIter_init(JNIEnv *const env, JNIEnvCache * const jc, jobject jIter){ if(!jc->jPhraseIter.klazz){ jclass klazz = (*env)->GetObjectClass(env, jIter); @@ -3202,7 +3223,7 @@ static void s3jni_phraseIter_init(JNIEnv *const env, JNIEnvCacheLine * const jc, } /* Copy the 'a' and 'b' fields from pSrc to Fts5PhraseIter object jIter. */ -static void s3jni_phraseIter_NToJ(JNIEnv *const env, JNIEnvCacheLine const * const jc, +static void s3jni_phraseIter_NToJ(JNIEnv *const env, JNIEnvCache const * const jc, Fts5PhraseIter const * const pSrc, jobject jIter){ assert(jc->jPhraseIter.klazz); @@ -3213,7 +3234,7 @@ static void s3jni_phraseIter_NToJ(JNIEnv *const env, JNIEnvCacheLine const * con } /* Copy the 'a' and 'b' fields from Fts5PhraseIter object jIter to pDest. */ -static void s3jni_phraseIter_JToN(JNIEnv *const env, JNIEnvCacheLine const * const jc, +static void s3jni_phraseIter_JToN(JNIEnv *const env, JNIEnvCache const * const jc, jobject jIter, Fts5PhraseIter * const pDest){ assert(jc->jPhraseIter.klazz); pDest->a = @@ -3228,7 +3249,7 @@ JDECLFtsXA(jint,xPhraseFirst)(JENV_JSELF,jobject jCtx, jint iPhrase, jobject jIter, jobject jOutCol, jobject jOutOff){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); Fts5PhraseIter iter; int rc, iCol = 0, iOff = 0; s3jni_phraseIter_init(env, jc, jIter); @@ -3245,7 +3266,7 @@ JDECLFtsXA(jint,xPhraseFirst)(JENV_JSELF,jobject jCtx, jint iPhrase, JDECLFtsXA(jint,xPhraseFirstColumn)(JENV_JSELF,jobject jCtx, jint iPhrase, jobject jIter, jobject jOutCol){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); Fts5PhraseIter iter; int rc, iCol = 0; s3jni_phraseIter_init(env, jc, jIter); @@ -3261,7 +3282,7 @@ JDECLFtsXA(jint,xPhraseFirstColumn)(JENV_JSELF,jobject jCtx, jint iPhrase, JDECLFtsXA(void,xPhraseNext)(JENV_JSELF,jobject jCtx, jobject jIter, jobject jOutCol, jobject jOutOff){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); Fts5PhraseIter iter; int iCol = 0, iOff = 0; if(!jc->jPhraseIter.klazz) return /*SQLITE_MISUSE*/; @@ -3276,7 +3297,7 @@ JDECLFtsXA(void,xPhraseNext)(JENV_JSELF,jobject jCtx, jobject jIter, JDECLFtsXA(void,xPhraseNextColumn)(JENV_JSELF,jobject jCtx, jobject jIter, jobject jOutCol){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); Fts5PhraseIter iter; int iCol = 0; if(!jc->jPhraseIter.klazz) return /*SQLITE_MISUSE*/; @@ -3298,7 +3319,7 @@ JDECLFtsXA(jint,xPhraseSize)(JENV_JSELF,jobject jCtx, jint iPhrase){ struct s3jni_xQueryPhraseState { JNIEnv *env; Fts5ExtensionApi const * fext; - JNIEnvCacheLine const * jc; + JNIEnvCache const * jc; jmethodID midCallback; jobject jCallback; jobject jFcx; @@ -3330,7 +3351,7 @@ static int s3jni_xQueryPhrase(const Fts5ExtensionApi *xapi, JDECLFtsXA(jint,xQueryPhrase)(JENV_JSELF,jobject jFcx, jint iPhrase, jobject jCallback){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); struct s3jni_xQueryPhraseState s; jclass klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL; if( !klazz ){ @@ -3419,7 +3440,7 @@ static jint s3jni_fts5_xTokenize(JENV_JSELF, const char *zClassName, jint tokFlags, jobject jFcx, jbyteArray jbaText, jobject jCallback){ Fts5ExtDecl; - JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env); + JNIEnvCache * const jc = S3Global_env_cache(env); struct s3jni_xQueryPhraseState s; int rc = 0; jbyte * const pText = JBA_TOC(jbaText); @@ -3485,8 +3506,8 @@ JDECLFtsXA(jobject,xUserData)(JENV_JSELF,jobject jFcx){ return pAux ? pAux->jUserData : 0; } - #endif /* SQLITE_ENABLE_FTS5 */ + //////////////////////////////////////////////////////////////////////// // End of the main API bindings. What follows are internal utilities. //////////////////////////////////////////////////////////////////////// @@ -3499,7 +3520,7 @@ JDECLFtsXA(jobject,xUserData)(JENV_JSELF,jobject jFcx){ */ JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_uncacheJniEnv(JNIEnv * const env, jclass self){ - return S3Global_JNIEnvCache_uncache(env) ? JNI_TRUE : JNI_FALSE; + return S3Global_env_uncache(env) ? JNI_TRUE : JNI_FALSE; } @@ -3564,7 +3585,7 @@ Java_org_sqlite_jni_SQLite3Jni_init(JNIEnv * const env, jclass self, jclass klaz (*env)->FatalError(env, "GetJavaVM() failure shouldn't be possible."); return; } - (void)S3Global_JNIEnvCache_cache(env); + (void)S3Global_env_cache(env); if( !S3Global.envCache.aHead ){ (*env)->FatalError(env, "Could not allocate JNIEnv-specific cache."); return; diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h index ea783afe50..0e5e0813f7 100644 --- a/ext/jni/src/c/sqlite3-jni.h +++ b/ext/jni/src/c/sqlite3-jni.h @@ -1094,10 +1094,10 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1data_1count /* * Class: org_sqlite_jni_SQLite3Jni * Method: sqlite3_db_filename - * Signature: (Lorg/sqlite/jni/sqlite3;[B)[B + * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1filename - (JNIEnv *, jclass, jobject, jbyteArray); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1filename + (JNIEnv *, jclass, jobject, jstring); /* * Class: org_sqlite_jni_SQLite3Jni diff --git a/ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java b/ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java index 5f2e560daf..327e5a5d28 100644 --- a/ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java +++ b/ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java @@ -34,7 +34,7 @@ public final class Fts5ExtensionApi extends NativePointerHolder xDestroyed = new ValueHolder<>(false); final ValueHolder xBusyCalled = new ValueHolder<>(0); diff --git a/ext/jni/src/org/sqlite/jni/fts5_api.java b/ext/jni/src/org/sqlite/jni/fts5_api.java index 53afeb93c6..4df8a748e2 100644 --- a/ext/jni/src/org/sqlite/jni/fts5_api.java +++ b/ext/jni/src/org/sqlite/jni/fts5_api.java @@ -30,7 +30,7 @@ public final class fts5_api extends NativePointerHolder { Returns the fts5_api instance associated with the given db, or null if something goes horribly wrong. */ - public static native fts5_api getInstanceForDb(@NotNull sqlite3 db); + public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db); // int (*xCreateTokenizer)( // fts5_api *pApi, diff --git a/manifest b/manifest index 749ff0d902..4be312149d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sdoc\soutdated\swarning\sabout\ssqlite3_trace_v2()\sJNI\sbinding\sbeing\sincompatible\swith\sMUTF-8.\sUse\snew\sto-string\scapability\sto\ssimplify\sFts5ExtensionApi::xColumnText()\sJNI\sbinding. -D 2023-08-06T11:05:17.309 +C JNI-internal\scleanups\sand\sAPI\srenaming.\sAdd\sa\sC-side\sjava-string-to-utf8\sconversion. +D 2023-08-06T13:02:43.735 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -230,10 +230,10 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 -F ext/jni/GNUmakefile bb4cd99bd8da534215cb6d278f05a626283eb5d2e8aebdb4d35e548637d35a9a +F ext/jni/GNUmakefile 9f0b0172903dfdb46ed3a77d431153238b7b96ec66cf40333c07e6dd23a3fabe F ext/jni/README.md 6ff7e1f4100dee980434a6ee37a199b653bceec62e233a6e2ccde6e7ae0c58bf -F ext/jni/src/c/sqlite3-jni.c 433ac7a2f113cda29ecf89b72711b55eeb97be5305fadd420408d1e538699177 -F ext/jni/src/c/sqlite3-jni.h 1bb138aa39a5ae6cc0b2ab6c72de9afe752123b02f3322a8d5b1ca36b9e5a410 +F ext/jni/src/c/sqlite3-jni.c 38c251d74f78b54b30e84ed97230eb2fa008e7400e9a460066ef6f1c43c06a2b +F ext/jni/src/c/sqlite3-jni.h 8ddf8a2e044d7880c75c07c9f025f3cdc5d486a42d30d99e0c45d7a8a973a97d F ext/jni/src/org/sqlite/jni/Authorizer.java 8dde03bbe50896d2f426240a4af4dcb6d98b655af84fe6ed86e637f5d5ac1fc8 F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c F ext/jni/src/org/sqlite/jni/Collation.java 8dffbb00938007ad0967b2ab424d3c908413af1bbd3d212b9c9899910f1218d1 @@ -241,7 +241,7 @@ F ext/jni/src/org/sqlite/jni/CollationNeeded.java ebc7cd96d46a70daa76016a308e80f F ext/jni/src/org/sqlite/jni/CommitHook.java 87c6a8e5138c61a8eeff018fe16d23f29219150239746032687f245938baca1a F ext/jni/src/org/sqlite/jni/Fts5.java 13844685231e8b4840a706db3bed84d5dfcf15be0ae7e809eac40420dba24901 F ext/jni/src/org/sqlite/jni/Fts5Context.java 0a5a02047a6a1dd3e4a38b0e542a8dd2de365033ba30e6ae019a676305959890 -F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java aaab15f6dd515fa45b99ddb1f2f889657a2939f64f7934114f013c98442032da +F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java 5b92cc034ca403936f11e07838699e6cf28afc5dd84020dfe9a6b64739b65065 F ext/jni/src/org/sqlite/jni/Fts5Function.java 65cde7151e441fee012250a5e03277de7babcd11a0c308a832b7940574259bcc F ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java 6642beda341c0b1b46af4e2d7f6f9ab03a7aede43277b2c92859176d6bce3be9 F ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java 91489893596b6528c0df5cd7180bd5b55809c26e2b797fb321dfcdbc1298c060 @@ -250,13 +250,13 @@ F ext/jni/src/org/sqlite/jni/OutputPointer.java fcece068415b804aa7843534addb3905 F ext/jni/src/org/sqlite/jni/ProgressHandler.java 5979450e996416d28543f1d42634d308439565a99332a8bd84e424af667116cc F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564 F ext/jni/src/org/sqlite/jni/SQLFunction.java 09ce81c1c637e31c3a830d4c859cce95d65f5e02ff45f8bd1985b3479381bc46 -F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 3494bd0eda06b56e137ff71fcdada9c463d40a0bbb02fc0ce96bf3761e6110b7 -F ext/jni/src/org/sqlite/jni/Tester1.java ecc72fcba231f5dfd787fd5d62fac685e8cfc349f74d11245d19325643517bfd +F ext/jni/src/org/sqlite/jni/SQLite3Jni.java eb1a0b741654a1c813de4e3f11f354aae87b50f8656e440d95c0fd0509fad2f5 +F ext/jni/src/org/sqlite/jni/Tester1.java a57a56717104d6ff50932c9e81edf4a8773ce524d497988c8b044c18bbc963ee F ext/jni/src/org/sqlite/jni/TesterFts5.java cf2d687baafffdeba219b77cf611fd47a0556248820ea794ae3e8259bfbdc5ee F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71cece3b8819fa10bf26a5461dc973ee -F ext/jni/src/org/sqlite/jni/fts5_api.java ae52ff7f963976fabb7e87b0b8cdb3f9d2ba1838e7d3b79b0b4cb526202d4709 +F ext/jni/src/org/sqlite/jni/fts5_api.java 8c6b32455d7f85ee3f7f3e71c148bb3c2106f1d5484017daddfd560dd69d4f66 F ext/jni/src/org/sqlite/jni/fts5_extension_function.java ac825035d7d83fc7fd960347abfa6803e1614334a21533302041823ad5fc894c F ext/jni/src/org/sqlite/jni/fts5_tokenizer.java e530b36e6437fcc500e95d5d75fbffe272bdea20d2fac6be2e1336c578fba98b F ext/jni/src/org/sqlite/jni/sqlite3.java 600c3ddc1ac28ee8f58669fb435fd0d21f2972c652039361fde907d4fe44eb58 @@ -2082,8 +2082,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 07dd082c9e371829a18aeb574f842891e545e1fc125760238ede7e7e2b6a4262 -R 774991bd316a19b5ee8ab2518b7f41ee +P ebcfc2379be12f76a96f3605b734f406b3354d4c985062cdbfca0cf7e3f31379 +R a7badfa2d93b121b26fb8275a69f64a6 U stephan -Z 78a283a26c39161657872bbb379dbda5 +Z afedd572770e60de292afd4c7121fd3f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 972cac53d6..7a14addf8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebcfc2379be12f76a96f3605b734f406b3354d4c985062cdbfca0cf7e3f31379 \ No newline at end of file +672d85795d04131135b1dc6a02d64eceb8b5084217c17766afeca4af23c07ec4 \ No newline at end of file