#define S3JniExceptionIgnore S3JniIfThrew S3JniExceptionClear
#define S3JniExceptionWarnIgnore \
S3JniIfThrew {S3JniExceptionReport; S3JniExceptionClear;}(void)0
-#define EXCEPTION_WARN_CALLBACK_THREW(STR) \
+#define S3JniExceptionWarnCallbackThrew(STR) \
MARKER(("WARNING: " STR " MUST NOT THROW.\n")); \
(*env)->ExceptionDescribe(env)
/** To be used for cases where we're _really_ not expecting an
exception, e.g. looking up well-defined Java class members. */
-#define EXCEPTION_IS_FATAL(MSG) S3JniIfThrew {\
+#define S3JniExceptionIsFatal(MSG) S3JniIfThrew {\
S3JniExceptionReport; S3JniExceptionClear; \
(*env)->FatalError(env, MSG); \
}
#define PtrGet_sqlite3_value(OBJ) PtrGet_T(sqlite3_value, OBJ)
#define PtrGet_sqlite3_context(OBJ) PtrGet_T(sqlite3_context, OBJ)
/* Helpers for Java value reference management. */
-static inline jobject new_global_ref(JNIEnv * const env, jobject const v){
+static inline jobject s3jni_ref_global(JNIEnv * const env, jobject const v){
return v ? (*env)->NewGlobalRef(env, v) : NULL;
}
-static inline void delete_global_ref(JNIEnv * const env, jobject const v){
+static inline void s3jni_unref_global(JNIEnv * const env, jobject const v){
if( v ) (*env)->DeleteGlobalRef(env, v);
}
-static inline void delete_local_ref(JNIEnv * const env, jobject const v){
+static inline void s3jni_unref_local(JNIEnv * const env, jobject const v){
if( v ) (*env)->DeleteLocalRef(env, v);
}
-#define REF_G(VAR) new_global_ref(env, (VAR))
-#define REF_L(VAR) (*env)->NewLocalRef(env, VAR)
-#define UNREF_G(VAR) delete_global_ref(env,(VAR))
-#define UNREF_L(VAR) delete_local_ref(env,(VAR))
+#define S3JniRefGlobal(VAR) s3jni_ref_global(env, (VAR))
+#define S3JniRefLocal(VAR) (*env)->NewLocalRef(env, (VAR))
+#define S3JniUnrefGlobal(VAR) s3jni_unref_global(env, (VAR))
+#define S3JniUnrefLocal(VAR) s3jni_unref_local(env, (VAR))
/**
Keys for use with S3JniGlobal_nph_cache().
}
/*
-** Fetches the S3JniGlobal.envCache row for the given env, allocing
-** a row if needed. When a row is allocated, its state is initialized
-** insofar as possible. Calls (*env)->FatalError() if allocation of
-** an entry fails. That's hypothetically possible but "shouldn't happen."
+** Returns the current JNIEnv object. Fails fatally if it cannot find
+** the object.
*/
-static S3JniEnv * S3JniGlobal_env_cache(JNIEnv * const env){
+static JNIEnv * s3jni_env(void){
+ JNIEnv * env = 0;
+ if( (*SJG.jvm)->GetEnv(SJG.jvm, (void **)&env,
+ JNI_VERSION_1_8) ){
+ fprintf(stderr, "Fatal error: cannot get current JNIEnv.\n");
+ abort();
+ }
+ return env;
+}
+/* Declares local var env = s3jni_env(). */
+#define LocalJniGetEnv JNIEnv * const env = s3jni_env()
+
+/*
+** Fetches the S3JniGlobal.envCache row for the given env, allocing a
+** row if needed. When a row is allocated, its state is initialized
+** insofar as possible. Calls (*env)->FatalError() if allocation of an
+** entry fails. That's hypothetically possible but "shouldn't happen."
+*/
+static S3JniEnv * S3JniEnv_get(JNIEnv * const env){
struct S3JniEnv * row;
S3JniMutex_Env_enter;
row = SJG.envCache.aHead;
return jba;
}
-/*
-** Returns the current JNIEnv object. Fails fatally if it cannot find
-** it.
-*/
-static JNIEnv * s3jni_get_env(void){
- JNIEnv * env = 0;
- if( (*SJG.jvm)->GetEnv(SJG.jvm, (void **)&env,
- JNI_VERSION_1_8) ){
- fprintf(stderr, "Fatal error: cannot get current JNIEnv.\n");
- abort();
- }
- return env;
-}
-/* Declares local var env = s3jni_get_env(). */
-#define LocalJniGetEnv JNIEnv * const env = s3jni_get_env()
-
/*
** Uses the java.lang.String(byte[],Charset) constructor to create a
** new String from UTF-8 string z. n is the number of bytes to
if( jba ){
rv = (*env)->NewObject(env, SJG.g.cString, SJG.g.ctorStringBA,
jba, SJG.g.oCharsetUtf8);
- UNREF_L(jba);
+ S3JniUnrefLocal(jba);
}
}
return rv;
(*env)->GetByteArrayRegion(env, jba, 0, nBa, (jbyte*)rv);
rv[nBa] = 0;
}
- UNREF_L(jba);
+ S3JniUnrefLocal(jba);
return rv;
}
char * zMsg;
jclass const klazz = (*env)->GetObjectClass(env, jx);
mid = (*env)->GetMethodID(env, klazz, "toString", "()Ljava/lang/String;");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew{
S3JniExceptionReport;
S3JniExceptionClear;
return 0;
}
zMsg = s3jni_jstring_to_utf8(env, msg, 0);
- UNREF_L(msg);
+ S3JniUnrefLocal(msg);
return zMsg;
}
zMsg = s3jni_exception_error_msg(env, ex);
s3jni_db_error(ps->pDb, errCode, zMsg ? zMsg : zDfltMsg);
sqlite3_free(zMsg);
- UNREF_L(ex);
+ S3JniUnrefLocal(ex);
}
return errCode;
}
jclass const klazz = (*env)->GetObjectClass(env, jObj);
jmethodID method = (*env)->GetMethodID(env, klazz, "xDestroy", "()V");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
if( method ){
s3jni_incr( &SJG.metrics.nDestroy );
(*env)->CallVoidMethod(env, jObj, method);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("xDestroy() callback");
+ S3JniExceptionWarnCallbackThrew("xDestroy() callback");
S3JniExceptionClear;
}
}else{
if( doXDestroy && s->jObj ){
s3jni_call_xDestroy(env, s->jObj);
}
- UNREF_G(s->jObj);
+ S3JniUnrefGlobal(s->jObj);
memset(s, 0, sizeof(*s));
}
UNHOOK(collationNeeded, 0);
UNHOOK(busyHandler, 1);
#undef UNHOOK
- UNREF_G(s->jDb);
+ S3JniUnrefGlobal(s->jDb);
memset(s, 0, sizeof(S3JniDb));
s->pNext = SJG.perDb.aFree;
if(s->pNext) s->pNext->pPrev = s;
** references the cache owns. Returns true if env was cached and false
** if it was not found in the cache.
*/
-static int S3JniGlobal_env_uncache(JNIEnv * const env){
+static int S3JniEnv_uncache(JNIEnv * const env){
struct S3JniEnv * row;
S3JniMutex_Env_assertLocked;
row = SJG.envCache.aHead;
if( !pNC->pRef ){
pNC->pRef = pRef;
pNC->klazz = (*env)->FindClass(env, pRef->zName);
- EXCEPTION_IS_FATAL("FindClass() unexpectedly threw");
- pNC->klazz = REF_G(pNC->klazz);
+ S3JniExceptionIsFatal("FindClass() unexpectedly threw");
+ pNC->klazz = S3JniRefGlobal(pNC->klazz);
}
S3JniMutex_Nph_leave;
}
S3JniMutex_Nph_enter;
if( !pNC->fidValue ){
pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz, "nativePointer", "J");
- EXCEPTION_IS_FATAL("Code maintenance required: missing nativePointer field.");
+ S3JniExceptionIsFatal("Code maintenance required: missing nativePointer field.");
}
S3JniMutex_Nph_leave;
}
S3NphRef const* pRef){
(*env)->SetLongField(env, ppOut, NativePointerHolder_getField(env, pRef),
(jlong)p);
- EXCEPTION_IS_FATAL("Could not set NativePointerHolder.nativePointer.");
+ S3JniExceptionIsFatal("Could not set NativePointerHolder.nativePointer.");
}
/*
void * const rv = (void*)(*env)->GetLongField(
env, pObj, NativePointerHolder_getField(env, pRef)
);
- EXCEPTION_IS_FATAL("Cannot fetch NativePointerHolder.nativePointer.");
+ S3JniExceptionIsFatal("Cannot fetch NativePointerHolder.nativePointer.");
return rv;
}else{
return 0;
assert(!rv->pNext->pPrev);
rv->pNext->pPrev = rv;
}
- rv->jDb = REF_G(jDb);
+ rv->jDb = S3JniRefGlobal(jDb);
rv->pDb = pDb;
}
S3JniMutex_S3JniDb_leave;
static void S3JniAutoExtension_clear(JNIEnv * const env,
S3JniAutoExtension * const ax){
if( ax->jObj ){
- UNREF_G(ax->jObj);
+ S3JniUnrefGlobal(ax->jObj);
memset(ax, 0, sizeof(*ax));
}
}
ax->midFunc = (*env)->GetMethodID(env, klazz, "call",
"(Lorg/sqlite/jni/sqlite3;)I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniExceptionWarnIgnore;
if( !ax->midFunc ){
MARKER(("Error getting call(sqlite3) from AutoExtension object.\n"));
S3JniAutoExtension_clear(env, ax);
return SQLITE_ERROR;
}
- ax->jObj = REF_G(jAutoExt);
+ ax->jObj = S3JniRefGlobal(jAutoExt);
return 0;
}
S3JniMutex_Nph_enter;
if( !pNC->fidValue ){
pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz, "value", zTypeSig);
- EXCEPTION_IS_FATAL("setupOutputPointer() could not find OutputPointer.*.value");
+ S3JniExceptionIsFatal("setupOutputPointer() could not find OutputPointer.*.value");
}
S3JniMutex_Nph_leave;
}
env, &S3NphRefs.OutputPointer_Int32, "I", jOut
);
(*env)->SetIntField(env, jOut, setter, (jint)v);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.Int32.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.Int32.value");
}
/*
env, &S3NphRefs.OutputPointer_Int64, "J", jOut
);
(*env)->SetLongField(env, jOut, setter, v);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.Int64.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.Int64.value");
}
/*
env, &S3NphRefs.OutputPointer_sqlite3, "Lorg/sqlite/jni/sqlite3;", jOut
);
(*env)->SetObjectField(env, jOut, setter, jDb);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.sqlite3.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.sqlite3.value");
}
/*
"Lorg/sqlite/jni/sqlite3_stmt;", jOut
);
(*env)->SetObjectField(env, jOut, setter, jStmt);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.sqlite3_stmt.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.sqlite3_stmt.value");
}
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
"Lorg/sqlite/jni/sqlite3_value;", jOut
);
(*env)->SetObjectField(env, jOut, setter, jValue);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.sqlite3_value.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.sqlite3_value.value");
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
env, &S3NphRefs.OutputPointer_ByteArray, "[B", jOut
);
(*env)->SetObjectField(env, jOut, setter, v);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.ByteArray.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.ByteArray.value");
}
#endif
env, &S3NphRefs.OutputPointer_String, "Ljava/lang/String;", jOut
);
(*env)->SetObjectField(env, jOut, setter, v);
- EXCEPTION_IS_FATAL("Cannot set OutputPointer.String.value");
+ S3JniExceptionIsFatal("Cannot set OutputPointer.String.value");
}
#endif /* SQLITE_ENABLE_FTS5 */
jbyteArray jbaLhs = (*env)->NewByteArray(env, (jint)nLhs);
jbyteArray jbaRhs = jbaLhs ? (*env)->NewByteArray(env, (jint)nRhs) : NULL;
if( !jbaRhs ){
- UNREF_L(jbaLhs);
+ S3JniUnrefLocal(jbaLhs);
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
return 0;
}
ps->hooks.collation.midCallback,
jbaLhs, jbaRhs);
S3JniExceptionIgnore;
- UNREF_L(jbaLhs);
- UNREF_L(jbaRhs);
+ S3JniUnrefLocal(jbaLhs);
+ S3JniUnrefLocal(jbaRhs);
return (int)rc;
}
/* Collation finalizer for use by the sqlite3 internals. */
static void CollationState_xDestroy(void *pArg){
S3JniDb * const ps = pArg;
- S3JniHook_unref( s3jni_get_env(), &ps->hooks.collation, 1 );
+ S3JniHook_unref( s3jni_env(), &ps->hooks.collation, 1 );
}
/*
static ResultJavaVal * ResultJavaVal_alloc(JNIEnv * const env, jobject jObj){
ResultJavaVal * rv = sqlite3_malloc(sizeof(ResultJavaVal));
if( rv ){
- rv->jObj = jObj ? REF_G(jObj) : 0;
+ rv->jObj = jObj ? S3JniRefGlobal(jObj) : 0;
}
return rv;
}
if( v ){
ResultJavaVal * const rv = (ResultJavaVal*)v;
LocalJniGetEnv;
- UNREF_G(rv->jObj);
+ S3JniUnrefGlobal(rv->jObj);
sqlite3_free(rv);
}
}
S3JniMutex_Nph_enter;
if( !pNC->midCtor ){
pNC->midCtor = (*env)->GetMethodID(env, pNC->klazz, "<init>", "()V");
- EXCEPTION_IS_FATAL("Cannot find constructor for class.");
+ S3JniExceptionIsFatal("Cannot find constructor for class.");
}
S3JniMutex_Nph_leave;
}
rv = (*env)->NewObject(env, pNC->klazz, pNC->midCtor);
- EXCEPTION_IS_FATAL("No-arg constructor threw.");
+ S3JniExceptionIsFatal("No-arg constructor threw.");
s3jni_oom_check(rv);
if( rv ) NativePointerHolder_set(env, rv, pNative, pRef);
return rv;
jclass const klazz = (*env)->GetObjectClass(env, jObj);
memset(s, 0, sizeof(S3JniUdf));
- s->jObj = REF_G(jObj);
+ s->jObj = S3JniRefGlobal(jObj);
#define FGET(FuncName,FuncType,Field) \
s->Field = (*env)->GetMethodID(env, klazz, FuncName, FuncType); \
if( !s->Field ) (*env)->ExceptionClear(env)
FGET("xValue", zFV, jmidxValue);
FGET("xInverse", zFSI, jmidxInverse);
#undef FGET
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
if( s->jmidxFunc ) s->type = UDF_SCALAR;
else if( s->jmidxStep && s->jmidxFinal ){
s->type = s->jmidxValue ? UDF_WINDOW : UDF_AGGREGATE;
if( env ){
//MARKER(("UDF cleanup: %s\n", s->zFuncName));
s3jni_call_xDestroy(env, s->jObj);
- UNREF_G(s->jObj);
+ S3JniUnrefGlobal(s->jObj);
}
sqlite3_free(s->zFuncName);
sqlite3_free(s);
jobject jsv = new_sqlite3_value_wrapper(env, argv[i]);
if( !jsv ) goto error_oom;
(*env)->SetObjectArrayElement(env, ja, i, jsv);
- UNREF_L(jsv)/*array has a ref*/;
+ S3JniUnrefLocal(jsv)/*array has a ref*/;
}
*jCx = jcx;
*jArgv = ja;
return 0;
error_oom:
sqlite3_result_error_nomem(cx);
- UNREF_L(jcx);
- UNREF_L(ja);
+ S3JniUnrefLocal(jcx);
+ S3JniUnrefLocal(ja);
return SQLITE_NOMEM;
}
(*env)->ExceptionDescribe( env );
S3JniExceptionClear;
}
- UNREF_L(ex);
+ S3JniUnrefLocal(ex);
return rc;
}
s->zFuncName, zFuncType);
}
}
- UNREF_L(args.jcx);
- UNREF_L(args.jargv);
+ S3JniUnrefLocal(args.jcx);
+ S3JniUnrefLocal(args.jargv);
return rc;
}
rc = udf_report_exception(env, isFinal, cx, s->zFuncName,
zFuncType);
}
- UNREF_L(jcx);
+ S3JniUnrefLocal(jcx);
return rc;
}
JNIEnv * env = 0;
S3JniDb * ps;
S3JniEnv * jc;
+
if( 0==SJG.autoExt.nExt ) return 0;
- env = s3jni_get_env();
- jc = S3JniGlobal_env_cache(env);
+ env = s3jni_env();
+ jc = S3JniEnv_get(env);
ps = jc->pdbOpening;
if( !ps ){
MARKER(("Unexpected arrival of null S3JniDb in auto-extension runner.\n"));
if( i >= SJG.autoExt.nExt ){
go = 0;
}else{
- ax.jObj = REF_L(SJG.autoExt.pExt[i].jObj);
+ ax.jObj = S3JniRefLocal(SJG.autoExt.pExt[i].jObj);
ax.midFunc = SJG.autoExt.pExt[i].midFunc;
}
S3JniMutex_Ext_leave;
if( ax.jObj ){
rc = (*env)->CallIntMethod(env, ax.jObj, ax.midFunc, ps->jDb);
- UNREF_L(ax.jObj);
+ S3JniUnrefLocal(ax.jObj);
S3JniIfThrew {
jthrowable const ex = (*env)->ExceptionOccurred(env);
char * zMsg;
S3JniExceptionClear;
zMsg = s3jni_exception_error_msg(env, ex);
- UNREF_L(ex);
+ S3JniUnrefLocal(ex);
*pzErr = sqlite3_mprintf("auto-extension threw: %s", zMsg);
sqlite3_free(zMsg);
if( !rc ) rc = SQLITE_ERROR;
rc = (*env)->CallIntMethod(env, ps->hooks.busyHandler.jObj,
ps->hooks.busyHandler.midCallback, (jint)n);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("sqlite3_busy_handler() callback");
+ S3JniExceptionWarnCallbackThrew("sqlite3_busy_handler() callback");
rc = s3jni_db_exception(env, ps, SQLITE_ERROR,
"sqlite3_busy_handler() callback threw.");
}
}
jclass klazz;
S3JniHook_unref(env, pHook, 1);
- pHook->jObj = REF_G(jBusy);
+ pHook->jObj = S3JniRefGlobal(jBusy);
klazz = (*env)->GetObjectClass(env, jBusy);
pHook->midCallback = (*env)->GetMethodID(env, klazz, "call", "(I)I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniHook_unref(env, pHook, 0);
rc = SQLITE_ERROR;
S3JniIfThrew{
s3jni_db_exception(env, ps, 0, "sqlite3_collation_needed() callback threw");
}
- UNREF_L(jName);
+ S3JniUnrefLocal(jName);
}
}
return 0;
}
if( !jHook ){
- UNREF_G(pOld);
+ S3JniUnrefGlobal(pOld);
memset(pHook, 0, sizeof(S3JniHook));
sqlite3_collation_needed(ps->pDb, 0, 0);
return 0;
klazz = (*env)->GetObjectClass(env, jHook);
xCallback = (*env)->GetMethodID(env, klazz, "call",
"(Lorg/sqlite/jni/sqlite3;ILjava/lang/String;)I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
rc = s3jni_db_exception(env, ps, SQLITE_MISUSE,
"Cannot not find matching callback on "
"collation-needed hook object.");
}else{
pHook->midCallback = xCallback;
- pHook->jObj = REF_G(jHook);
- UNREF_G(pOld);
+ pHook->jObj = S3JniRefGlobal(jHook);
+ S3JniUnrefGlobal(pOld);
rc = sqlite3_collation_needed16(ps->pDb, ps, s3jni_collation_needed_impl16);
}
return rc;
}
if( !jHook ){
if( pOld ){
- jobject tmp = REF_L(pOld);
- UNREF_G(pOld);
+ jobject tmp = S3JniRefLocal(pOld);
+ S3JniUnrefGlobal(pOld);
pOld = tmp;
}
memset(pHook, 0, sizeof(S3JniHook));
klazz = (*env)->GetObjectClass(env, jHook);
xCallback = (*env)->GetMethodID(env, klazz, "call",
isCommit ? "()I" : "()V");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionReport;
S3JniExceptionClear;
"hook object.");
}else{
pHook->midCallback = xCallback;
- pHook->jObj = REF_G(jHook);
+ pHook->jObj = S3JniRefGlobal(jHook);
if( isCommit ) sqlite3_commit_hook(ps->pDb, s3jni_commit_hook_impl, ps);
else sqlite3_rollback_hook(ps->pDb, s3jni_rollback_hook_impl, ps);
if( pOld ){
- jobject tmp = REF_L(pOld);
- UNREF_G(pOld);
+ jobject tmp = S3JniRefLocal(pOld);
+ S3JniUnrefGlobal(pOld);
pOld = tmp;
}
}
S3JniHook * const hook = &SJG.hooks.sqllog;
if( !ps || !hook->jObj ) return;
- jArg0 = REF_L(ps->jDb);
+ jArg0 = S3JniRefLocal(ps->jDb);
switch( op ){
case 0: /* db opened */
case 1: /* SQL executed */
}
(*env)->CallVoidMethod(env, hook->jObj, hook->midCallback, jArg0, jArg1, op);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("SQLITE_CONFIG_SQLLOG callback");
+ S3JniExceptionWarnCallbackThrew("SQLITE_CONFIG_SQLLOG callback");
S3JniExceptionClear;
}
- UNREF_L(jArg0);
- UNREF_L(jArg1);
+ S3JniUnrefLocal(jArg0);
+ S3JniUnrefLocal(jArg1);
}
//! Requirement of SQLITE_CONFIG_SQLLOG.
void sqlite3_init_sqllog(void){
"(Lorg/sqlite/jni/sqlite3;"
"Ljava/lang/String;"
"I)V");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
if( !hook->midCallback ){
S3JniExceptionWarnIgnore;
S3JniHook_unref(env, hook, 0);
return SQLITE_ERROR;
}
- hook->jObj = REF_G(jLog);
+ hook->jObj = S3JniRefGlobal(jLog);
rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 );
if( rc ){
S3JniHook_unref(env, hook, 0);
klazz = (*env)->GetObjectClass(env, oCollation);
pHook->midCallback = (*env)->GetMethodID(env, klazz, "call",
"([B[B)I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew{
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
return s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Could not get xCompare() method for object.");
}
CollationState_xDestroy);
s3jni_mutf8_release(name, zName);
if( 0==rc ){
- pHook->jObj = REF_G(oCollation);
+ pHook->jObj = S3JniRefGlobal(oCollation);
}else{
S3JniHook_unref(env, pHook, 1);
}
JniDecl(jboolean,1java_1uncache_1thread)(JniArgsEnvClass){
int rc;
S3JniMutex_Env_enter;
- rc = S3JniGlobal_env_uncache(env);
+ rc = S3JniEnv_uncache(env);
S3JniMutex_Env_leave;
return rc ? JNI_TRUE : JNI_FALSE;
}
S3JniDb ** ps){
int rc = 0;
jobject jDb = 0;
- *jc = S3JniGlobal_env_cache(env);
+ *jc = S3JniEnv_get(env);
if( !*jc ){
rc = SQLITE_NOMEM;
goto end;
if( *ps ){
(*jc)->pdbOpening = *ps;
}else{
- UNREF_L(jDb);
+ S3JniUnrefLocal(jDb);
rc = SQLITE_NOMEM;
}
end:
NativePointerHolder_set(env, jStmt, pStmt, &S3NphRefs.sqlite3_stmt);
}else{
/* Happens for comments and whitespace. */
- UNREF_L(jStmt);
+ S3JniUnrefLocal(jStmt);
jStmt = 0;
}
}else{
- UNREF_L(jStmt);
+ S3JniUnrefLocal(jStmt);
jStmt = 0;
}
#if 0
(*env)->CallVoidMethod(env, pHook->jObj, pHook->midCallback,
(jint)opId, jDbName, jTable, (jlong)iKey1);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("sqlite3_(pre)update_hook() callback");
+ S3JniExceptionWarnCallbackThrew("sqlite3_(pre)update_hook() callback");
s3jni_db_exception(env, ps, 0,
"sqlite3_(pre)update_hook() callback threw");
}
}
- UNREF_L(jDbName);
- UNREF_L(jTable);
+ S3JniUnrefLocal(jDbName);
+ S3JniUnrefLocal(jTable);
}
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
}
if( !jHook ){
if( pOld ){
- jobject tmp = REF_L(pOld);
- UNREF_G(pOld);
+ jobject tmp = S3JniRefLocal(pOld);
+ S3JniUnrefGlobal(pOld);
pOld = tmp;
}
memset(pHook, 0, sizeof(S3JniHook));
"JJ)V")
: (*env)->GetMethodID(env, klazz, "call",
"(ILjava/lang/String;Ljava/lang/String;J)V");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_ERROR,
"(pre)update hook object.");
}else{
pHook->midCallback = xCallback;
- pHook->jObj = REF_G(jHook);
+ pHook->jObj = S3JniRefGlobal(jHook);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
if( isPre ) sqlite3_preupdate_hook(ps->pDb, s3jni_preupdate_hook_impl, ps);
else
#endif
sqlite3_update_hook(ps->pDb, s3jni_update_hook_impl, ps);
if( pOld ){
- jobject tmp = REF_L(pOld);
- UNREF_G(pOld);
+ jobject tmp = S3JniRefLocal(pOld);
+ S3JniUnrefGlobal(pOld);
pOld = tmp;
}
}
jobject pWrap = new_sqlite3_value_wrapper(env, pOut);
if( pWrap ){
OutputPointer_set_sqlite3_value(env, jOut, pWrap);
- UNREF_L(pWrap);
+ S3JniUnrefLocal(pWrap);
}else{
rc = SQLITE_NOMEM;
}
jmethodID xCallback;
if( n<1 || !jProgress ){
if( ps ){
- UNREF_G(ps->hooks.progress.jObj);
+ S3JniUnrefGlobal(ps->hooks.progress.jObj);
memset(&ps->hooks.progress, 0, sizeof(ps->hooks.progress));
}
sqlite3_progress_handler(ps->pDb, 0, 0, 0);
}
klazz = (*env)->GetObjectClass(env, jProgress);
xCallback = (*env)->GetMethodID(env, klazz, "call", "()I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching xCallback() on "
"ProgressHandler object.");
}else{
- UNREF_G(ps->hooks.progress.jObj);
+ S3JniUnrefGlobal(ps->hooks.progress.jObj);
ps->hooks.progress.midCallback = xCallback;
- ps->hooks.progress.jObj = REF_G(jProgress);
+ ps->hooks.progress.jObj = S3JniRefGlobal(jProgress);
sqlite3_progress_handler(ps->pDb, (int)n, s3jni_progress_handler_impl, ps);
}
}
S3JniIfThrew{
rc = s3jni_db_exception(env, ps, rc, "sqlite3_set_authorizer() callback");
}
- UNREF_L(s0);
- UNREF_L(s1);
- UNREF_L(s2);
- UNREF_L(s3);
+ S3JniUnrefLocal(s0);
+ S3JniUnrefLocal(s1);
+ S3JniUnrefLocal(s2);
+ S3JniUnrefLocal(s3);
return rc;
}
}
S3JniHook_unref(env, pHook, 0);
}
- pHook->jObj = REF_G(jHook);
+ pHook->jObj = S3JniRefGlobal(jHook);
klazz = (*env)->GetObjectClass(env, jHook);
pHook->midCallback = (*env)->GetMethodID(env, klazz,
"call",
"Ljava/lang/String;"
"Ljava/lang/String;"
")I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniHook_unref(env, pHook, 0);
return s3jni_db_error(ps->pDb, SQLITE_ERROR,
s3jni_reset_auto_extension(env);
S3JniMutex_Env_enter;
while( SJG.envCache.aHead ){
- S3JniGlobal_env_uncache( SJG.envCache.aHead->env );
+ S3JniEnv_uncache( SJG.envCache.aHead->env );
}
S3JniMutex_Env_leave;
#if 0
jobject jP = NULL /* the tracer's P arg */;
jobject jPUnref = NULL /* potentially a local ref to jP */;
int rc;
- int createStmt = 0;
switch( traceflag ){
case SQLITE_TRACE_STMT:
jX = s3jni_utf8_to_jstring(env, (const char *)pX, -1);
if( !jX ) return SQLITE_NOMEM;
/*MARKER(("TRACE_STMT@%p SQL=%p / %s\n", pP, jX, (const char *)pX));*/
- createStmt = 1;
break;
case SQLITE_TRACE_PROFILE:
jX = (*env)->NewObject(env, SJG.g.cLong, SJG.g.ctorLong1,
// hmm. ^^^ (*pX) really is zero.
// MARKER(("profile time = %llu\n", *((sqlite3_int64*)pX)));
if( !jX ) return SQLITE_NOMEM;
- createStmt = 1;
break;
case SQLITE_TRACE_ROW:
- createStmt = 1;
break;
case SQLITE_TRACE_CLOSE:
jP = ps->jDb;
assert(!"cannot happen - unkown trace flag");
return SQLITE_ERROR;
}
- if( createStmt ){
+ if( !jP ){
+ /* Create a new temporary sqlite3_stmt wrapper */
jP = jPUnref = new_sqlite3_stmt_wrapper(env, pP);
if( !jP ){
- UNREF_L(jX);
+ S3JniUnrefLocal(jX);
return SQLITE_NOMEM;
}
}
ps->hooks.trace.midCallback,
(jint)traceflag, jP, jX);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("sqlite3_trace_v2() callback");
rc = s3jni_db_exception(env, ps, SQLITE_ERROR,
"sqlite3_trace_v2() callback threw.");
}
- UNREF_L(jPUnref);
- UNREF_L(jX);
+ S3JniUnrefLocal(jPUnref);
+ S3JniUnrefLocal(jX);
return rc;
}
pHook->midCallback = (*env)->GetMethodID(
env, klazz, "call", "(ILjava/lang/Object;Ljava/lang/Object;)I"
);
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
S3JniHook_unref(env, pHook, 0);
return s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching xCallback() on Tracer object.");
}
- pHook->jObj = REF_G(jTracer);
+ pHook->jObj = S3JniRefGlobal(jTracer);
return sqlite3_trace_v2(ps->pDb, (unsigned)traceMask, s3jni_trace_impl, ps);
}
if( env ){
/*MARKER(("FTS5 aux function cleanup: %s\n", s->zFuncName));*/
s3jni_call_xDestroy(env, s->jObj);
- UNREF_G(s->jObj);
- UNREF_G(s->jUserData);
+ S3JniUnrefGlobal(s->jObj);
+ S3JniUnrefGlobal(s->jUserData);
}
sqlite3_free(s->zFuncName);
sqlite3_free(s);
if( s ){
jclass klazz;
memset(s, 0, sizeof(Fts5JniAux));
- s->jObj = REF_G(jObj);
+ s->jObj = S3JniRefGlobal(jObj);
klazz = (*env)->GetObjectClass(env, jObj);
s->jmid = (*env)->GetMethodID(env, klazz, "xFunction",
"(Lorg/sqlite/jni/Fts5ExtensionApi;"
"Lorg/sqlite/jni/Fts5Context;"
"Lorg/sqlite/jni/sqlite3_context;"
"[Lorg/sqlite/jni/sqlite3_value;)V");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew{
S3JniExceptionReport;
S3JniExceptionClear;
S3JniMutex_Env_enter;
if( pNPH ){
if( !SJG.fts5.jFtsExt ){
- SJG.fts5.jFtsExt = REF_G(pNPH);
+ SJG.fts5.jFtsExt = S3JniRefGlobal(pNPH);
}
- UNREF_L(pNPH);
+ S3JniUnrefLocal(pNPH);
}
S3JniMutex_Env_leave;
}
fts5_api * const pApi = s3jni_fts5_api_from_db(ps->pDb);
if( pApi ){
rv = new_fts5_api_wrapper(env, pApi);
- ps->jFtsApi = rv ? REF_G(rv) : 0;
+ ps->jFtsApi = rv ? S3JniRefGlobal(rv) : 0;
}
}
return rv;
if( pz ){
if( jstr ){
OutputPointer_set_String(env, jOut, jstr);
- UNREF_L(jstr)/*jOut has a reference*/;
+ S3JniUnrefLocal(jstr)/*jOut has a reference*/;
}else{
rc = SQLITE_NOMEM;
}
S3JniIfThrew{
udf_report_exception(env, 1, pCx, pAux->zFuncName, "xFunction");
}
- UNREF_L(jpFts);
- UNREF_L(jpCx);
- UNREF_L(jArgv);
+ S3JniUnrefLocal(jpFts);
+ S3JniUnrefLocal(jpCx);
+ S3JniUnrefLocal(jArgv);
return;
error_oom:
assert( !jArgv );
assert( !jpCx );
- UNREF_L(jpFts);
+ S3JniUnrefLocal(jpFts);
sqlite3_result_error_nomem(pCx);
return;
}
rc = SQLITE_NOMEM;
}
if( 0==rc ){
- pAux->jUserData = jUserData ? REF_G(jUserData) : 0;
+ pAux->jUserData = jUserData ? S3JniRefGlobal(jUserData) : 0;
pAux->zFuncName = sqlite3_mprintf("%s", zName)
/* OOM here is non-fatal. Ignore it. */;
}
if( p->jObj ){
LocalJniGetEnv;
s3jni_call_xDestroy(env, p->jObj);
- UNREF_G(p->jObj);
+ S3JniUnrefGlobal(p->jObj);
}
sqlite3_free(x);
}
if( pAux ){
if( bClear ){
if( pAux->jObj ){
- rv = REF_L(pAux->jObj);
- UNREF_G(pAux->jObj);
+ rv = S3JniRefLocal(pAux->jObj);
+ S3JniUnrefGlobal(pAux->jObj);
}
/* Note that we do not call xDestroy() in this case. */
sqlite3_free(pAux);
S3JniGlobalType * const g = &S3JniGlobal;
assert(g->fts5.jPhraseIter.fidA);
(*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidA, (jlong)pSrc->a);
- EXCEPTION_IS_FATAL("Cannot set Fts5PhraseIter.a field.");
+ S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.a field.");
(*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidB, (jlong)pSrc->b);
- EXCEPTION_IS_FATAL("Cannot set Fts5PhraseIter.b field.");
+ S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.b field.");
}
/* Copy the 'a' and 'b' fields from Fts5PhraseIter object jIter to pDest. */
assert(g->fts5.jPhraseIter.fidA);
pDest->a =
(const unsigned char *)(*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidA);
- EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.a field.");
+ S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field.");
pDest->b =
(const unsigned char *)(*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidB);
- EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.b field.");
+ S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.b field.");
}
JniDeclFtsXA(jint,xPhraseFirst)(JniArgsEnvObj,jobject jCtx, jint iPhrase,
int rc = (int)(*env)->CallIntMethod(env, s->jCallback, s->midCallback,
SJG.fts5.jFtsExt, s->jFcx);
S3JniIfThrew{
- EXCEPTION_WARN_CALLBACK_THREW("xQueryPhrase() callback");
+ S3JniExceptionWarnCallbackThrew("xQueryPhrase() callback");
S3JniExceptionClear;
rc = SQLITE_ERROR;
}
JniDeclFtsXA(jint,xQueryPhrase)(JniArgsEnvObj,jobject jFcx, jint iPhrase,
jobject jCallback){
Fts5ExtDecl;
- S3JniEnv * const jc = S3JniGlobal_env_cache(env);
+ S3JniEnv * const jc = S3JniEnv_get(env);
struct s3jni_xQueryPhraseState s;
jclass klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL;
s.midCallback = (*env)->GetMethodID(env, klazz, "xCallback",
"(Lorg.sqlite.jni.Fts5ExtensionApi;"
"Lorg.sqlite.jni.Fts5Context;)I");
- UNREF_L(klazz);
- EXCEPTION_IS_FATAL("Could not extract xQueryPhraseCallback.xCallback method.");
+ S3JniUnrefLocal(klazz);
+ S3JniExceptionIsFatal("Could not extract xQueryPhraseCallback.xCallback method.");
return (jint)fext->xQueryPhrase(PtrGet_Fts5Context(jFcx), iPhrase, &s,
s3jni_xQueryPhrase);
}
}
return SQLITE_NOMEM;
}
- pAux->jObj = REF_G(jAux);
+ pAux->jObj = S3JniRefGlobal(jAux);
rc = fext->xSetAuxdata(PtrGet_Fts5Context(jCtx), pAux,
S3JniFts5AuxData_xDestroy);
return rc;
jba = s->tok.jba;
}else{
if(s->tok.jba){
- UNREF_L(s->tok.jba);
+ S3JniUnrefLocal(s->tok.jba);
}
s->tok.zPrev = z;
s->tok.nPrev = nZ;
jint tokFlags, jobject jFcx,
jbyteArray jbaText, jobject jCallback){
Fts5ExtDecl;
- S3JniEnv * const jc = S3JniGlobal_env_cache(env);
+ S3JniEnv * const jc = S3JniEnv_get(env);
struct s3jni_xQueryPhraseState s;
int rc = 0;
jbyte * const pText = jCallback ? s3jni_jbytearray_bytes(jbaText) : 0;
s.jFcx = jFcx;
s.fext = fext;
s.midCallback = (*env)->GetMethodID(env, klazz, "xToken", "(I[BII)I");
- UNREF_L(klazz);
+ S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionReport;
S3JniExceptionClear;
s3jni_jbytearray_release(jbaText, pText);
return SQLITE_ERROR;
}
- s.tok.jba = REF_L(jbaText);
+ s.tok.jba = S3JniRefLocal(jbaText);
s.tok.zPrev = (const char *)pText;
s.tok.nPrev = (int)nText;
if( pRef == &S3NphRefs.Fts5ExtensionApi ){
}
if( s.tok.jba ){
assert( s.tok.zPrev );
- UNREF_L(s.tok.jba);
+ S3JniUnrefLocal(s.tok.jba);
}
s3jni_jbytearray_release(jbaText, pText);
return (jint)rc;
}
/* Grab references to various global classes and objects... */
- SJG.g.cObj = REF_G((*env)->FindClass(env,"java/lang/Object"));
- EXCEPTION_IS_FATAL("Error getting reference to Object class.");
+ SJG.g.cObj = S3JniRefGlobal((*env)->FindClass(env,"java/lang/Object"));
+ S3JniExceptionIsFatal("Error getting reference to Object class.");
- SJG.g.cLong = REF_G((*env)->FindClass(env,"java/lang/Long"));
- EXCEPTION_IS_FATAL("Error getting reference to Long class.");
+ SJG.g.cLong = S3JniRefGlobal((*env)->FindClass(env,"java/lang/Long"));
+ S3JniExceptionIsFatal("Error getting reference to Long class.");
SJG.g.ctorLong1 = (*env)->GetMethodID(env, SJG.g.cLong,
"<init>", "(J)V");
- EXCEPTION_IS_FATAL("Error getting reference to Long constructor.");
+ S3JniExceptionIsFatal("Error getting reference to Long constructor.");
- SJG.g.cString = REF_G((*env)->FindClass(env,"java/lang/String"));
- EXCEPTION_IS_FATAL("Error getting reference to String class.");
+ SJG.g.cString = S3JniRefGlobal((*env)->FindClass(env,"java/lang/String"));
+ S3JniExceptionIsFatal("Error getting reference to String class.");
SJG.g.ctorStringBA =
(*env)->GetMethodID(env, SJG.g.cString,
"<init>", "([BLjava/nio/charset/Charset;)V");
- EXCEPTION_IS_FATAL("Error getting reference to String(byte[],Charset) ctor.");
+ S3JniExceptionIsFatal("Error getting reference to String(byte[],Charset) ctor.");
SJG.g.stringGetBytes =
(*env)->GetMethodID(env, SJG.g.cString,
"getBytes", "(Ljava/nio/charset/Charset;)[B");
- EXCEPTION_IS_FATAL("Error getting reference to String.getBytes(Charset).");
+ S3JniExceptionIsFatal("Error getting reference to String.getBytes(Charset).");
{ /* StandardCharsets.UTF_8 */
jfieldID fUtf8;
klazz = (*env)->FindClass(env,"java/nio/charset/StandardCharsets");
- EXCEPTION_IS_FATAL("Error getting reference to StandardCharsets class.");
+ S3JniExceptionIsFatal("Error getting reference to StandardCharsets class.");
fUtf8 = (*env)->GetStaticFieldID(env, klazz, "UTF_8",
"Ljava/nio/charset/Charset;");
- EXCEPTION_IS_FATAL("Error getting StandardCharsets.UTF_8 field.");
+ S3JniExceptionIsFatal("Error getting StandardCharsets.UTF_8 field.");
SJG.g.oCharsetUtf8 =
- REF_G((*env)->GetStaticObjectField(env, klazz, fUtf8));
- EXCEPTION_IS_FATAL("Error getting reference to StandardCharsets.UTF_8.");
- UNREF_L(klazz);
+ S3JniRefGlobal((*env)->GetStaticObjectField(env, klazz, fUtf8));
+ S3JniExceptionIsFatal("Error getting reference to StandardCharsets.UTF_8.");
+ S3JniUnrefLocal(klazz);
}
#ifdef SQLITE_ENABLE_FTS5
klazz = (*env)->FindClass(env, "org/sqlite/jni/Fts5PhraseIter");
- EXCEPTION_IS_FATAL("Error getting reference to org.sqlite.jni.Fts5PhraseIter.");
+ S3JniExceptionIsFatal("Error getting reference to org.sqlite.jni.Fts5PhraseIter.");
SJG.fts5.jPhraseIter.fidA = (*env)->GetFieldID(env, klazz, "a", "J");
- EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.a field.");
+ S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field.");
SJG.fts5.jPhraseIter.fidB = (*env)->GetFieldID(env, klazz, "b", "J");
- EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.b field.");
- UNREF_L(klazz);
+ S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.b field.");
+ S3JniUnrefLocal(klazz);
#endif
SJG.envCache.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
for( pConfFlag = &aLimits[0]; pConfFlag->zName; ++pConfFlag ){
char const * zSig = (JTYPE_BOOL == pConfFlag->jtype) ? "Z" : "I";
fieldId = (*env)->GetStaticFieldID(env, jKlazz, pConfFlag->zName, zSig);
- EXCEPTION_IS_FATAL("Missing an expected static member of the SQLite3Jni class.");
+ S3JniExceptionIsFatal("Missing an expected static member of the SQLite3Jni class.");
assert(fieldId);
switch( pConfFlag->jtype ){
case JTYPE_INT:
pConfFlag->value ? JNI_TRUE : JNI_FALSE);
break;
}
- EXCEPTION_IS_FATAL("Seting a static member of the SQLite3Jni class failed.");
+ S3JniExceptionIsFatal("Seting a static member of the SQLite3Jni class failed.");
}
}