зеркало из https://github.com/mozilla/gecko-dev.git
Backing out the merge with SpiderMonkey140_BRANCH for LiveConnect.
Some OJI-related changes were made on the trunk that can't be easily reconciled with the branch.
This commit is contained in:
Родитель
05603647c8
Коммит
e1ac50b525
|
@ -466,7 +466,7 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
thread_list_monitor =
|
||||
(struct PRMonitor *) PR_NewMonitor();
|
||||
}
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
/* Put this VM on the list of all created VMs */
|
||||
jsjava_vm->next = jsjava_vm_list;
|
||||
|
@ -580,7 +580,7 @@ JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
|
|||
PR_DestroyMonitor(thread_list_monitor);
|
||||
thread_list_monitor = NULL;
|
||||
}
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
free(jsjava_vm);
|
||||
}
|
||||
|
@ -600,14 +600,14 @@ new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jE
|
|||
if (thread_name)
|
||||
jsj_env->name = strdup(thread_name);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
jsj_env->next = thread_list;
|
||||
thread_list = jsj_env;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -620,10 +620,6 @@ find_jsjava_thread(JNIEnv *jEnv)
|
|||
JSJavaThreadState *e, **p, *jsj_env;
|
||||
jsj_env = NULL;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
/* Search for the thread state among the list of all created
|
||||
LiveConnect threads */
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
|
@ -635,15 +631,19 @@ find_jsjava_thread(JNIEnv *jEnv)
|
|||
|
||||
/* Move a found thread to head of list for faster search next time. */
|
||||
if (jsj_env && p != &thread_list) {
|
||||
*p = jsj_env->next;
|
||||
jsj_env->next = thread_list;
|
||||
thread_list = jsj_env;
|
||||
}
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
/* First, check to make sure list hasn't mutated since we searched */
|
||||
if (*p == jsj_env) {
|
||||
*p = jsj_env->next;
|
||||
thread_list = jsj_env;
|
||||
}
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
|
@ -744,9 +744,6 @@ JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
|
|||
JSContext *old_context;
|
||||
old_context = jsj_env->cx;
|
||||
jsj_env->cx = cx;
|
||||
|
||||
/* The following line prevents clearing of jsj_env->cx by jsj_ExitJava() */
|
||||
jsj_env->recursion_depth++;
|
||||
return old_context;
|
||||
}
|
||||
|
||||
|
@ -760,23 +757,16 @@ JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
|||
/* Disassociate the current native thread from its corresponding Java thread */
|
||||
java_vm = jsj_env->jsjava_vm->java_vm;
|
||||
jEnv = jsj_env->jEnv;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
|
||||
if (!JSJ_callbacks->detach_current_thread(java_vm, jEnv)) {
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
|
||||
if (!JSJ_callbacks->detach_current_thread(java_vm, jEnv))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Destroy the LiveConnect execution environment passed in */
|
||||
jsj_ClearPendingJSErrors(jsj_env);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
if (e == jsj_env) {
|
||||
*p = jsj_env->next;
|
||||
|
@ -784,11 +774,9 @@ JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
|||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(e);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
free(jsj_env);
|
||||
return JS_TRUE;
|
||||
|
@ -800,17 +788,13 @@ JSBool
|
|||
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSBool result;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
result = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
|||
if (!handle)
|
||||
return NULL;
|
||||
handle->js_obj = js_obj;
|
||||
handle->rt = JS_GetRuntime(cx);
|
||||
handle->cx = cx;
|
||||
|
||||
/* Create a new Java object that wraps the JavaScript object by storing its
|
||||
address in a private integer field. */
|
||||
|
@ -366,7 +366,7 @@ capture_js_error_reports_for_java(JSContext *cx, const char *message,
|
|||
}
|
||||
|
||||
/* Get the head of the list of pending JS errors */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_env = jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jsj_env)
|
||||
goto abort;
|
||||
|
||||
|
@ -383,7 +383,6 @@ capture_js_error_reports_for_java(JSContext *cx, const char *message,
|
|||
/* Push this error onto the list of pending JS errors */
|
||||
new_error->next = jsj_env->pending_js_errors;
|
||||
jsj_env->pending_js_errors = new_error;
|
||||
jsj_ExitJava(jsj_env);
|
||||
return;
|
||||
|
||||
abort:
|
||||
|
@ -694,14 +693,7 @@ jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj,
|
|||
Java and back into JS. Invoke a callback to obtain/create a
|
||||
JSContext for us to use. */
|
||||
if (JSJ_callbacks->map_jsj_thread_to_js_context) {
|
||||
#ifdef OJI
|
||||
cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
|
||||
applet_obj,
|
||||
jEnv, &err_msg);
|
||||
#else
|
||||
cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
|
||||
jEnv, &err_msg);
|
||||
#endif
|
||||
cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, applet_obj, jEnv, &err_msg);
|
||||
if (!cx)
|
||||
goto error;
|
||||
} else {
|
||||
|
@ -712,6 +704,7 @@ jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj,
|
|||
jsj_env->cx = cx;
|
||||
}
|
||||
*cxp = cx;
|
||||
jsj_env->recursion_depth++;
|
||||
|
||||
/*
|
||||
* Capture all JS error reports so that they can be thrown into the Java
|
||||
|
@ -720,10 +713,6 @@ jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj,
|
|||
*old_error_reporterp =
|
||||
JS_SetErrorReporter(cx, capture_js_error_reports_for_java);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_BeginRequest(cx);
|
||||
#endif
|
||||
|
||||
return jsj_env;
|
||||
|
||||
error:
|
||||
|
@ -751,10 +740,6 @@ jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JSErrorReporter original_
|
|||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_EndRequest(cx);
|
||||
#endif
|
||||
|
||||
/* Restore the JS error reporter */
|
||||
JS_SetErrorReporter(cx, original_reporter);
|
||||
|
||||
|
@ -780,6 +765,9 @@ jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JSErrorReporter original_
|
|||
if (JSJ_callbacks->exit_js)
|
||||
JSJ_callbacks->exit_js(jEnv);
|
||||
|
||||
jsj_env->recursion_depth--;
|
||||
if (!jsj_env->recursion_depth)
|
||||
jsj_env->cx = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -823,7 +811,7 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv *jEnv,
|
|||
jobject java_wrapper_obj,
|
||||
jstring property_name_jstr)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
int dummy_cost;
|
||||
|
@ -881,7 +869,7 @@ Java_netscape_javascript_JSObject_getSlot(JNIEnv *jEnv,
|
|||
jobject java_wrapper_obj,
|
||||
jint slot)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
int dummy_cost;
|
||||
|
@ -919,7 +907,7 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv *jEnv,
|
|||
jstring property_name_jstr,
|
||||
jobject java_obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
const jchar *property_name_ucs2;
|
||||
|
@ -969,7 +957,7 @@ Java_netscape_javascript_JSObject_setSlot(JNIEnv *jEnv,
|
|||
jint slot,
|
||||
jobject java_obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
JSErrorReporter saved_reporter;
|
||||
|
@ -997,7 +985,7 @@ Java_netscape_javascript_JSObject_removeMember(JNIEnv *jEnv,
|
|||
jobject java_wrapper_obj,
|
||||
jstring property_name_jstr)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
const jchar *property_name_ucs2;
|
||||
|
@ -1043,7 +1031,7 @@ Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj,
|
|||
{
|
||||
int i, argc, arg_num;
|
||||
jsval *argv;
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val, function_val;
|
||||
int dummy_cost;
|
||||
|
@ -1131,7 +1119,7 @@ Java_netscape_javascript_JSObject_eval(JNIEnv *jEnv,
|
|||
{
|
||||
const char *codebase;
|
||||
JSPrincipals *principals;
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSBool eval_succeeded;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
|
@ -1200,7 +1188,7 @@ Java_netscape_javascript_JSObject_toString(JNIEnv *jEnv,
|
|||
jobject java_wrapper_obj)
|
||||
{
|
||||
jstring result;
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
JSString *jsstr;
|
||||
JSErrorReporter saved_reporter;
|
||||
|
@ -1234,7 +1222,7 @@ Java_netscape_javascript_JSObject_getWindow(JNIEnv *jEnv,
|
|||
jobject java_applet_obj)
|
||||
{
|
||||
char *err_msg;
|
||||
JSContext *cx = NULL;
|
||||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
int dummy_cost;
|
||||
|
@ -1276,17 +1264,19 @@ JNIEXPORT void JNICALL
|
|||
Java_netscape_javascript_JSObject_finalize(JNIEnv *jEnv, jobject java_wrapper_obj)
|
||||
{
|
||||
JSBool success;
|
||||
JSContext *cx;
|
||||
JSObjectHandle *handle;
|
||||
|
||||
success = JS_FALSE;
|
||||
|
||||
|
||||
handle = (JSObjectHandle *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal));
|
||||
JS_ASSERT(handle);
|
||||
if (!handle)
|
||||
return;
|
||||
cx = handle->cx;
|
||||
|
||||
success = JS_RemoveRootRT(handle->rt, &handle->js_obj);
|
||||
free(handle);
|
||||
success = JS_RemoveRoot(cx, &handle->js_obj);
|
||||
JS_free(cx, handle);
|
||||
|
||||
JS_ASSERT(success);
|
||||
}
|
||||
|
|
|
@ -94,8 +94,7 @@ access_java_array_element(JSContext *cx,
|
|||
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
|
||||
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
|
||||
if (!strcmp(property_name, "constructor")) {
|
||||
if (vp)
|
||||
*vp = JSVAL_VOID;
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +132,7 @@ access_java_array_element(JSContext *cx,
|
|||
JSJMSG_CANT_WRITE_JARRAY, member_name);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
if (vp)
|
||||
*vp = JSVAL_VOID;
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
} else {
|
||||
|
@ -192,30 +190,20 @@ JS_STATIC_DLL_CALLBACK(JSBool)
|
|||
JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
result = access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaArray_setPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
result = access_java_array_element(cx, jEnv, obj, id, vp, JS_TRUE);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return access_java_array_element(cx, jEnv, obj, id, vp, JS_TRUE);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -229,16 +217,13 @@ JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
JNIEnv *jEnv;
|
||||
JSBool result;
|
||||
JSErrorReporter old_reporter;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
old_reporter = JS_SetErrorReporter(cx, NULL);
|
||||
result = access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -247,13 +232,9 @@ JavaArray_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
|||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
jsval *vp = &value;
|
||||
if (propp)
|
||||
return JS_FALSE;
|
||||
if (attrs & ~(JSPROP_PERMANENT|JSPROP_ENUMERATE))
|
||||
return JS_FALSE;
|
||||
|
||||
return JavaArray_setPropertyById(cx, obj, id, vp);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JARRAY_PROP_DEFINE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -309,7 +290,6 @@ JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JNIEnv *jEnv;
|
||||
jsize array_length, index;
|
||||
|
||||
|
@ -323,15 +303,13 @@ JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
}
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_wrapper->java_obj);
|
||||
if (array_length < 0) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (array_length < 0)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
switch(enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
|
@ -339,7 +317,6 @@ JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(array_length);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
|
@ -355,12 +332,10 @@ JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
|
||||
case JSENUMERATE_DESTROY:
|
||||
*statep = JSVAL_NULL;
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
JS_ASSERT(0);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,23 +148,18 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
JavaClassDescriptor *class_descriptor;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
/* printf("In JavaClass_getProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor)) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!member_descriptor) {
|
||||
*vp = JSVAL_VOID;
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -172,9 +167,7 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
|
||||
if (member_descriptor->field) {
|
||||
if (!member_descriptor->methods) {
|
||||
result = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
|
||||
} else {
|
||||
JS_ASSERT(0);
|
||||
}
|
||||
|
@ -196,15 +189,11 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
}
|
||||
function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,
|
||||
JSFUN_BOUND_METHOD, obj, member_name);
|
||||
if (!function) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!function)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function));
|
||||
}
|
||||
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -217,20 +206,16 @@ JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
JavaMemberDescriptor *member_descriptor;
|
||||
jsval idval;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
/* printf("In JavaClass_setProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor)) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Check for the case where there is a method with the given name, but no field
|
||||
with that name */
|
||||
|
@ -238,15 +223,11 @@ JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
goto no_such_field;
|
||||
|
||||
/* Silently fail if field value is final (immutable), as required by ECMA spec */
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
result = jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);
|
||||
|
||||
no_such_field:
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
|
@ -254,7 +235,6 @@ no_such_field:
|
|||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_MISSING_STATIC,
|
||||
member_name, class_descriptor->name);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -265,20 +245,18 @@ JS_STATIC_DLL_CALLBACK(void)
|
|||
JavaClass_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
JavaClassDescriptor *class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor)
|
||||
return;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
/* printf("Finalizing %s\n", class_descriptor->name); */
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
|
||||
jsj_ExitJava(jsj_env);
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,12 +270,11 @@ JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
JNIEnv *jEnv;
|
||||
JSErrorReporter old_reporter;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* printf("In JavaClass_lookupProperty()\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -311,7 +288,6 @@ JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
}
|
||||
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -388,7 +364,6 @@ JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
JavaMemberDescriptor *member_descriptor;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
|
||||
|
@ -403,14 +378,13 @@ JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
switch(enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
|
@ -479,7 +453,6 @@ JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
|
|||
jclass java_class;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
has_instance = JS_FALSE;
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
|
@ -513,9 +486,8 @@ JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
|
|||
}
|
||||
java_obj = java_wrapper->java_obj;
|
||||
/* Get JNI pointer */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
has_instance = (*jEnv)->IsInstanceOf(jEnv, java_obj, java_class);
|
||||
jsj_ExitJava(jsj_env);
|
||||
|
||||
done:
|
||||
*has_instancep = has_instance;
|
||||
|
@ -617,7 +589,10 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc != 1 ||
|
||||
!JSVAL_IS_OBJECT(argv[0]) ||
|
||||
|
@ -636,20 +611,12 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
|
||||
if (!JavaClass_obj) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!JavaClass_obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -660,7 +627,10 @@ JavaClass_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
|
|||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc != 1 ||
|
||||
!JSVAL_IS_OBJECT(argv[0]) ||
|
||||
|
@ -672,27 +642,18 @@ JavaClass_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
if (!(*jEnv)->IsSameObject(jEnv, class_descriptor->java_class, jlClass)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NEED_JCLASS_ARG);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_wrapper->java_obj);
|
||||
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
|
||||
if (!JavaClass_obj) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!JavaClass_obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,11 +62,16 @@ static void
|
|||
JavaMember_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JavaMethodOrFieldValue *member_val;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
member_val = JS_GetPrivate(cx, obj);
|
||||
if (!member_val)
|
||||
return;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
if (JSVAL_IS_GCTHING(member_val->method_val))
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
|
|
|
@ -54,7 +54,6 @@ static JSJHashTable *java_obj_reflections = NULL;
|
|||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
static PRMonitor *java_obj_reflections_monitor = NULL;
|
||||
static int java_obj_reflections_mutation_count = 0;
|
||||
#endif
|
||||
|
||||
JSBool
|
||||
|
@ -93,10 +92,6 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
JavaClassDescriptor *class_descriptor;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
int mutation_count;
|
||||
#endif
|
||||
|
||||
js_wrapper_obj = NULL;
|
||||
|
||||
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
|
||||
|
@ -108,26 +103,16 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
hep = JSJ_HashTableRawLookup(java_obj_reflections,
|
||||
hash_code, java_obj, (void*)jEnv);
|
||||
he = *hep;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
/* Track mutations to hash table */
|
||||
mutation_count = java_obj_reflections_mutation_count;
|
||||
|
||||
/* We must temporarily release this monitor so as to avoid
|
||||
deadlocks with the JS GC. See Bugsplat #354852 */
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
if (he) {
|
||||
js_wrapper_obj = (JSObject *)he->value;
|
||||
if (js_wrapper_obj)
|
||||
return js_wrapper_obj;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* No existing reflection found. Construct a new one */
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
if (!class_descriptor)
|
||||
return NULL;
|
||||
goto done;
|
||||
if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {
|
||||
js_class = &JavaArray_class;
|
||||
} else {
|
||||
|
@ -138,40 +123,17 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
/* Create new JS object to reflect Java object */
|
||||
js_wrapper_obj = JS_NewObject(cx, js_class, NULL, NULL);
|
||||
if (!js_wrapper_obj)
|
||||
return NULL;
|
||||
goto done;
|
||||
|
||||
/* Create private, native portion of JavaObject */
|
||||
java_wrapper =
|
||||
(JavaObjectWrapper *)JS_malloc(cx, sizeof(JavaObjectWrapper));
|
||||
if (!java_wrapper) {
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
|
||||
return NULL;
|
||||
goto done;
|
||||
}
|
||||
JS_SetPrivate(cx, js_wrapper_obj, java_wrapper);
|
||||
java_wrapper->class_descriptor = class_descriptor;
|
||||
java_wrapper->java_obj = NULL;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(java_obj_reflections_monitor);
|
||||
|
||||
/* We may need to do the hash table lookup again, since some other
|
||||
thread may have updated it while the lock wasn't being held. */
|
||||
if (mutation_count != java_obj_reflections_mutation_count) {
|
||||
hep = JSJ_HashTableRawLookup(java_obj_reflections,
|
||||
hash_code, java_obj, (void*)jEnv);
|
||||
he = *hep;
|
||||
if (he) {
|
||||
js_wrapper_obj = (JSObject *)he->value;
|
||||
if (js_wrapper_obj) {
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
return js_wrapper_obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java_obj_reflections_mutation_count++;
|
||||
|
||||
#endif
|
||||
|
||||
java_obj = (*jEnv)->NewGlobalRef(jEnv, java_obj);
|
||||
java_wrapper->java_obj = java_obj;
|
||||
|
@ -181,21 +143,23 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
/* Add the JavaObject to the hash table */
|
||||
he = JSJ_HashTableRawAdd(java_obj_reflections, hep, hash_code,
|
||||
java_obj, js_wrapper_obj, (void*)jEnv);
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
if (!he) {
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
|
||||
goto out_of_memory;
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
return js_wrapper_obj;
|
||||
|
||||
out_of_memory:
|
||||
/* No need to free js_wrapper_obj, as it will be finalized by GC. */
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
js_wrapper_obj = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -219,8 +183,6 @@ remove_java_obj_reflection_from_hashtable(jobject java_obj, JNIEnv *jEnv)
|
|||
JSJ_HashTableRawRemove(java_obj_reflections, hep, he, (void*)jEnv);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
java_obj_reflections_mutation_count++;
|
||||
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
}
|
||||
|
@ -231,14 +193,13 @@ JavaObject_finalize(JSContext *cx, JSObject *obj)
|
|||
JavaObjectWrapper *java_wrapper;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper)
|
||||
return;
|
||||
java_obj = java_wrapper->java_obj;
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
|
@ -248,7 +209,6 @@ JavaObject_finalize(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, java_wrapper->class_descriptor);
|
||||
JS_free(cx, java_wrapper);
|
||||
jsj_ExitJava(jsj_env);
|
||||
}
|
||||
|
||||
/* Trivial helper for jsj_DiscardJavaObjReflections(), below */
|
||||
|
@ -295,8 +255,11 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
JavaClassDescriptor *class_descriptor;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper) {
|
||||
|
@ -306,10 +269,10 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
}
|
||||
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_OP_JOBJECT);
|
||||
JSJMSG_BAD_OP_JOBJECT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
|
@ -320,43 +283,22 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
|
||||
case JSTYPE_FUNCTION:
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_CONVERT_TO_FUNC);
|
||||
JSJMSG_CONVERT_TO_FUNC);
|
||||
return JS_FALSE;
|
||||
|
||||
case JSTYPE_VOID:
|
||||
case JSTYPE_STRING:
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Either extract a C-string from the java.lang.String object
|
||||
or call the Java toString() method */
|
||||
result = jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
case JSTYPE_NUMBER:
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Call Java doubleValue() method, if applicable */
|
||||
result = jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
/* Call Java doubleValue() method, if applicable */
|
||||
return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
case JSTYPE_BOOLEAN:
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Call booleanValue() method, if applicable */
|
||||
result = jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
default:
|
||||
JS_ASSERT(0);
|
||||
|
@ -518,28 +460,23 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
JSObject *funobj;
|
||||
jsval field_val, method_val;
|
||||
JSBool success;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* printf("In JavaObject_getProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (vp)
|
||||
*vp = JSVAL_VOID;
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, vp)) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Handle access to special, non-Java properties of JavaObjects, e.g. the
|
||||
"constructor" property of the prototype object */
|
||||
if (!member_descriptor) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!member_descriptor)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
field_val = method_val = JSVAL_VOID;
|
||||
|
@ -547,10 +484,8 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
/* If a field member, get the value of the field */
|
||||
if (member_descriptor->field) {
|
||||
success = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, &field_val);
|
||||
if (!success) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!success)
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a method member, build a wrapper around the Java method */
|
||||
|
@ -558,20 +493,16 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
/* Create a function object with this JavaObject as its parent, so that
|
||||
JSFUN_BOUND_METHOD binds it as the default 'this' for the function. */
|
||||
funobj = JS_CloneFunctionObject(cx, member_descriptor->invoke_func_obj, obj);
|
||||
if (!funobj) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!funobj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
method_val = OBJECT_TO_JSVAL(funobj);
|
||||
}
|
||||
|
||||
#if TEST_JAVAMEMBER
|
||||
/* Always create a JavaMember object, even though it's inefficient */
|
||||
obj = jsj_CreateJavaMember(cx, method_val, field_val);
|
||||
if (!obj) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
#else /* !TEST_JAVAMEMBER */
|
||||
|
||||
|
@ -585,10 +516,8 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
In Java, such ambiguity is not possible because the compiler
|
||||
can statically determine which is being accessed. */
|
||||
obj = jsj_CreateJavaMember(cx, method_val, field_val);
|
||||
if (!obj) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
|
||||
|
@ -598,8 +527,7 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
}
|
||||
|
||||
#endif /* !TEST_JAVAMEMBER */
|
||||
|
||||
jsj_ExitJava(jsj_env);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -613,20 +541,16 @@ JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
JavaMemberDescriptor *member_descriptor;
|
||||
jsval idval;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
/* printf("In JavaObject_setProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, NULL)) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, NULL))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Could be assignment to magic JS __proto__ property rather than a Java field */
|
||||
if (!member_descriptor) {
|
||||
|
@ -639,11 +563,9 @@ JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
if (!JSVAL_IS_OBJECT(*vp)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_PROTO_ASSIGNMENT);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_FALSE;
|
||||
}
|
||||
JS_SetPrototype(cx, obj, JSVAL_TO_OBJECT(*vp));
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -653,15 +575,11 @@ JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
goto no_such_field;
|
||||
|
||||
/* Silently fail if field value is final (immutable), as required by ECMA spec */
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL) {
|
||||
jsj_ExitJava(jsj_env);
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
result = jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp);
|
||||
|
||||
no_such_field:
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
|
@ -670,7 +588,6 @@ no_such_field:
|
|||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NO_NAME_IN_CLASS,
|
||||
member_name, class_descriptor->name);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -685,12 +602,11 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
JNIEnv *jEnv;
|
||||
JSErrorReporter old_reporter;
|
||||
jsval dummy_val;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* printf("In JavaObject_lookupProperty()\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -708,7 +624,6 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
}
|
||||
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -778,7 +693,6 @@ JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
JavaMemberDescriptor *member_descriptor;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
/* Check for prototype object */
|
||||
|
@ -795,7 +709,7 @@ JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
case JSENUMERATE_INIT:
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -803,7 +717,6 @@ JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
*statep = PRIVATE_TO_JSVAL(member_descriptor);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
|
|
|
@ -118,7 +118,6 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
char *subPath, *newPath;
|
||||
const char *path;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* Painful hack for pre_define_java_packages() */
|
||||
if (quiet_resolve_failure)
|
||||
|
@ -149,7 +148,7 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -236,7 +235,6 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
|
||||
out:
|
||||
free(newPath);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -396,41 +396,10 @@ jsj_DiscardJavaClassReflections(JNIEnv *jEnv)
|
|||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
char *err_msg;
|
||||
JSContext *cx;
|
||||
|
||||
/* Get the per-thread state corresponding to the current Java thread */
|
||||
jsj_env = jsj_MapJavaThreadToJSJavaThreadState(jEnv, &err_msg);
|
||||
JS_ASSERT(jsj_env);
|
||||
if (!jsj_env)
|
||||
return;
|
||||
|
||||
/* Get the JSContext that we're supposed to use for this Java thread */
|
||||
cx = jsj_env->cx;
|
||||
if (!cx) {
|
||||
/* We called spontaneously into JS from Java, rather than from JS into
|
||||
Java and back into JS. Invoke a callback to obtain/create a
|
||||
JSContext for us to use. */
|
||||
if (JSJ_callbacks->map_jsj_thread_to_js_context) {
|
||||
#ifdef OJI
|
||||
cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
|
||||
NULL /* FIXME: What should this argument be ? */
|
||||
jEnv, &err_msg);
|
||||
#else
|
||||
cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env,
|
||||
jEnv, &err_msg);
|
||||
#endif
|
||||
JS_ASSERT(cx);
|
||||
if (!cx)
|
||||
return;
|
||||
} else {
|
||||
err_msg = JS_smprintf("Unable to find/create JavaScript execution "
|
||||
"context for JNI thread 0x%08x", jEnv);
|
||||
jsj_LogError(err_msg);
|
||||
free(err_msg);
|
||||
return;
|
||||
}
|
||||
jsj_env->cx = cx;
|
||||
}
|
||||
|
||||
if (java_class_reflections) {
|
||||
JSJ_HashTableEnumerateEntries(java_class_reflections,
|
||||
|
@ -501,22 +470,19 @@ reflect_java_methods_and_fields(JSContext *cx,
|
|||
|
||||
success = JS_TRUE; /* optimism */
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(java_reflect_monitor);
|
||||
#endif
|
||||
|
||||
/* See if we raced with another thread to reflect members of this class.
|
||||
If the status is REFLECT_COMPLETE, another thread beat us to it. If
|
||||
the status is REFLECT_IN_PROGRESS, we've recursively called this
|
||||
function within a single thread. Either way, we're done. */
|
||||
/* See if we raced with another thread to reflect members of this class */
|
||||
if (reflect_statics_only) {
|
||||
if (class_descriptor->static_members_reflected != REFLECT_NO)
|
||||
if (class_descriptor->static_members_reflected)
|
||||
goto done;
|
||||
class_descriptor->static_members_reflected = REFLECT_IN_PROGRESS;
|
||||
class_descriptor->static_members_reflected = JS_TRUE;
|
||||
} else {
|
||||
if (class_descriptor->instance_members_reflected != REFLECT_NO)
|
||||
if (class_descriptor->instance_members_reflected)
|
||||
goto done;
|
||||
class_descriptor->instance_members_reflected = REFLECT_IN_PROGRESS;
|
||||
class_descriptor->instance_members_reflected = JS_TRUE;
|
||||
}
|
||||
|
||||
if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only))
|
||||
|
@ -530,18 +496,16 @@ reflect_java_methods_and_fields(JSContext *cx,
|
|||
class_descriptor->num_static_members++;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
class_descriptor->static_members_reflected = REFLECT_COMPLETE;
|
||||
} else {
|
||||
member_descriptor = class_descriptor->instance_members;
|
||||
while (member_descriptor) {
|
||||
class_descriptor->num_instance_members++;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
class_descriptor->instance_members_reflected = REFLECT_COMPLETE;
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(java_reflect_monitor);
|
||||
#endif
|
||||
return success;
|
||||
|
@ -556,7 +520,7 @@ jsj_GetClassStaticMembers(JSContext *cx,
|
|||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (class_descriptor->static_members_reflected != REFLECT_COMPLETE)
|
||||
if (!class_descriptor->static_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
|
||||
return class_descriptor->static_members;
|
||||
}
|
||||
|
@ -566,7 +530,7 @@ jsj_GetClassInstanceMembers(JSContext *cx,
|
|||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (class_descriptor->instance_members_reflected != REFLECT_COMPLETE)
|
||||
if (!class_descriptor->instance_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE);
|
||||
return class_descriptor->instance_members;
|
||||
}
|
||||
|
@ -651,7 +615,7 @@ JavaMemberDescriptor *
|
|||
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (class_descriptor->static_members_reflected != REFLECT_COMPLETE)
|
||||
if (!class_descriptor->static_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
|
||||
return class_descriptor->constructors;
|
||||
}
|
||||
|
|
|
@ -1088,16 +1088,13 @@ preferred_conversion(JSContext *cx, JNIEnv *jEnv, jsval js_val,
|
|||
js_type = compute_jsj_type(cx, js_val);
|
||||
rank1 = rank_table[js_type][(int)descriptor1->type - 2];
|
||||
rank2 = rank_table[js_type][(int)descriptor2->type - 2];
|
||||
|
||||
/* Fast path for conversion from most JS types */
|
||||
if (rank1 < rank2)
|
||||
return JSJPREF_FIRST_ARG;
|
||||
|
||||
/*
|
||||
* Special logic is required for matching the classes of wrapped
|
||||
* Java objects.
|
||||
*/
|
||||
if (rank2 == 0) {
|
||||
if (((js_type == JSJTYPE_JAVAOBJECT) || (js_type == JSJTYPE_JAVAARRAY)) &&
|
||||
IS_REFERENCE_TYPE(descriptor2->type)) {
|
||||
java_class1 = descriptor1->java_class;
|
||||
java_class2 = descriptor2->java_class;
|
||||
|
||||
|
@ -1113,7 +1110,7 @@ preferred_conversion(JSContext *cx, JNIEnv *jEnv, jsval js_val,
|
|||
* For JavaObject arguments, any compatible reference type is preferable
|
||||
* to any primitive Java type or to java.lang.String.
|
||||
*/
|
||||
if (rank1 != 0)
|
||||
if (rank2 < rank1)
|
||||
return JSJPREF_SECOND_ARG;
|
||||
|
||||
/*
|
||||
|
@ -1130,6 +1127,10 @@ preferred_conversion(JSContext *cx, JNIEnv *jEnv, jsval js_val,
|
|||
return JSJPREF_AMBIGUOUS;
|
||||
}
|
||||
|
||||
/* Fast path for conversion from most JS types */
|
||||
if (rank1 < rank2)
|
||||
return JSJPREF_FIRST_ARG;
|
||||
|
||||
if (rank1 > rank2)
|
||||
return JSJPREF_SECOND_ARG;
|
||||
|
||||
|
@ -1393,12 +1394,6 @@ invoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env,
|
|||
}
|
||||
}
|
||||
|
||||
/* Prevent deadlocking if we re-enter JS on another thread as a result of a Java
|
||||
method call and that new thread wants to perform a GC. */
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_EndRequest(cx);
|
||||
#endif
|
||||
|
||||
#define CALL_JAVA_METHOD(type, member) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (is_static_method) { \
|
||||
|
@ -1463,8 +1458,7 @@ invoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env,
|
|||
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
JS_ASSERT(0);
|
||||
error_occurred = JS_TRUE;
|
||||
goto out;
|
||||
return JS_FALSE;
|
||||
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
|
@ -1474,7 +1468,6 @@ invoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env,
|
|||
}
|
||||
|
||||
out:
|
||||
|
||||
JSJ_SetDefaultJSContextForJavaThread(old_cx, jsj_env);
|
||||
|
||||
if (localv) {
|
||||
|
@ -1487,10 +1480,6 @@ out:
|
|||
if (jargv)
|
||||
JS_free(cx, jargv);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_BeginRequest(cx);
|
||||
#endif
|
||||
|
||||
if (!error_occurred) {
|
||||
success = jsj_ConvertJavaValueToJSValue(cx, jEnv, return_val_signature, &java_value, vp);
|
||||
if (IS_REFERENCE_TYPE(return_val_signature->type))
|
||||
|
@ -1567,19 +1556,9 @@ invoke_java_constructor(JSContext *cx,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Prevent deadlocking if we re-enter JS on another thread as a result of a Java
|
||||
method call and that new thread wants to perform a GC. */
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_EndRequest(cx);
|
||||
#endif
|
||||
|
||||
/* Call the constructor */
|
||||
java_object = (*jEnv)->NewObjectA(jEnv, java_class, methodID, jargv);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
JS_BeginRequest(cx);
|
||||
#endif
|
||||
|
||||
JSJ_SetDefaultJSContextForJavaThread(old_cx, jsj_env);
|
||||
|
||||
if (!java_object) {
|
||||
|
@ -1676,23 +1655,19 @@ jsj_JavaConstructorWrapper(JSContext *cx, JSObject *obj,
|
|||
JavaMemberDescriptor *member_descriptor;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JNIEnv *jEnv;
|
||||
JSBool result;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
obj = JSVAL_TO_OBJECT(argv[-2]);
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
JS_ASSERT(class_descriptor);
|
||||
if (!class_descriptor)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
member_descriptor = jsj_LookupJavaClassConstructors(cx, jEnv, class_descriptor);
|
||||
result = java_constructor_wrapper(cx, jsj_env, member_descriptor,
|
||||
class_descriptor, argc, argv, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return java_constructor_wrapper(cx, jsj_env, member_descriptor,
|
||||
class_descriptor, argc, argv, vp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1734,25 +1709,22 @@ jsj_JavaStaticMethodWrapper(JSContext *cx, JSObject *obj,
|
|||
jsval idval;
|
||||
JNIEnv *jEnv;
|
||||
JSJavaThreadState *jsj_env;
|
||||
JSBool result;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
JS_ASSERT(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION);
|
||||
function = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[-2]));
|
||||
idval = STRING_TO_JSVAL(JS_InternString(cx, JS_GetFunctionName(function)));
|
||||
JS_ValueToId(cx, idval, &id);
|
||||
|
||||
result = static_method_wrapper(cx, jsj_env, class_descriptor, id, argc, argv, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return static_method_wrapper(cx, jsj_env, class_descriptor, id, argc, argv, vp);
|
||||
}
|
||||
|
||||
JS_DLL_CALLBACK JSBool
|
||||
|
@ -1768,7 +1740,11 @@ jsj_JavaInstanceMethodWrapper(JSContext *cx, JSObject *obj,
|
|||
JSJavaThreadState *jsj_env;
|
||||
JNIEnv *jEnv;
|
||||
jobject java_obj;
|
||||
JSBool result;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper)
|
||||
|
@ -1781,22 +1757,14 @@ jsj_JavaInstanceMethodWrapper(JSContext *cx, JSObject *obj,
|
|||
JS_ValueToId(cx, idval, &id);
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_env = jsj_EnterJava(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Try to find an instance method with the given name first */
|
||||
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (member_descriptor)
|
||||
result = invoke_overloaded_java_method(cx, jsj_env, member_descriptor,
|
||||
JS_FALSE, java_obj,
|
||||
class_descriptor, argc, argv, vp);
|
||||
return invoke_overloaded_java_method(cx, jsj_env, member_descriptor,
|
||||
JS_FALSE, java_obj,
|
||||
class_descriptor, argc, argv, vp);
|
||||
|
||||
/* If no instance method was found, try for a static method or constructor */
|
||||
else
|
||||
result = static_method_wrapper(cx, jsj_env, class_descriptor, id, argc, argv, vp);
|
||||
jsj_ExitJava(jsj_env);
|
||||
return result;
|
||||
return static_method_wrapper(cx, jsj_env, class_descriptor, id, argc, argv, vp);
|
||||
}
|
||||
|
||||
|
|
|
@ -151,13 +151,6 @@ struct JavaMemberDescriptor {
|
|||
JSObject * invoke_func_obj; /* If non-null, JSFunction obj to invoke method */
|
||||
};
|
||||
|
||||
/* Status of Class member reflection. See JavaClassDescriptor. */
|
||||
typedef enum {
|
||||
REFLECT_NO,
|
||||
REFLECT_IN_PROGRESS,
|
||||
REFLECT_COMPLETE
|
||||
} ReflectStatus;
|
||||
|
||||
/* This is the native portion of a reflected Java class */
|
||||
struct JavaClassDescriptor {
|
||||
const char * name; /* Name of class, e.g. "java.lang.Byte" */
|
||||
|
@ -165,9 +158,9 @@ struct JavaClassDescriptor {
|
|||
jclass java_class; /* Opaque JVM handle to corresponding java.lang.Class */
|
||||
int num_instance_members;
|
||||
int num_static_members;
|
||||
volatile ReflectStatus instance_members_reflected;
|
||||
JSBool instance_members_reflected;
|
||||
JavaMemberDescriptor * instance_members;
|
||||
volatile ReflectStatus static_members_reflected;
|
||||
JSBool static_members_reflected;
|
||||
JavaMemberDescriptor * static_members;
|
||||
JavaMemberDescriptor * constructors;
|
||||
int modifiers; /* Class declaration qualifiers,
|
||||
|
@ -211,7 +204,7 @@ struct JSJavaThreadState {
|
|||
JNIEnv * jEnv; /* Per-thread opaque handle to Java VM */
|
||||
CapturedJSError * pending_js_errors; /* JS errors to be thrown as Java exceptions */
|
||||
JSContext * cx; /* current JS context for thread */
|
||||
int recursion_depth;/* # transitions into Java from JS */
|
||||
int recursion_depth;/* # transitions into JS from Java */
|
||||
JSJavaThreadState * next; /* next thread state among all created threads */
|
||||
};
|
||||
|
||||
|
@ -226,7 +219,7 @@ typedef struct JavaToJSSavedState JavaToJSSavedState;
|
|||
objects hold a reference to native JSObjects. */
|
||||
struct JSObjectHandle {
|
||||
JSObject *js_obj;
|
||||
JSRuntime *rt;
|
||||
JSContext *cx; /* Creating context, needed for finalization */
|
||||
};
|
||||
typedef struct JSObjectHandle JSObjectHandle;
|
||||
|
||||
|
@ -585,11 +578,8 @@ JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp);
|
|||
extern const char *
|
||||
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr);
|
||||
|
||||
extern JSJavaThreadState *
|
||||
jsj_EnterJava(JSContext *cx, JNIEnv **envp);
|
||||
|
||||
extern void
|
||||
jsj_ExitJava(JSJavaThreadState *jsj_env);
|
||||
JSJavaThreadState *
|
||||
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_LOG(args) printf args
|
||||
|
|
|
@ -221,97 +221,88 @@ vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
|
|||
|
||||
/* Get the exception out of the java environment. */
|
||||
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (!java_exception) {
|
||||
JSString *err_jsstr;
|
||||
char *err = JS_vsmprintf(format, ap);
|
||||
if (!err)
|
||||
return;
|
||||
err_jsstr = JS_NewString(cx, err, strlen(err));
|
||||
if (!err_jsstr)
|
||||
return;
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(err_jsstr));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
|
||||
/* Check for JSException */
|
||||
if (njJSException &&
|
||||
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
|
||||
if (java_exception) {
|
||||
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
|
||||
wrapped_exception_type =
|
||||
(*jEnv)->GetIntField(jEnv, java_exception,
|
||||
njJSException_wrappedExceptionType);
|
||||
|
||||
if (wrapped_exception_type != JSTYPE_EMPTY) {
|
||||
java_obj =
|
||||
(*jEnv)->GetObjectField(jEnv, java_exception,
|
||||
njJSException_wrappedException);
|
||||
|
||||
if ((java_obj == NULL) &&
|
||||
(wrapped_exception_type == JSTYPE_OBJECT)) {
|
||||
js_exception = JSVAL_NULL;
|
||||
} else {
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
/* OK to delete ref, since above call adds global ref */
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class);
|
||||
/* Check for JSException */
|
||||
if (njJSException &&
|
||||
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
|
||||
|
||||
wrapped_exception_type =
|
||||
(*jEnv)->GetIntField(jEnv, java_exception,
|
||||
njJSException_wrappedExceptionType);
|
||||
|
||||
/* Convert native JS values back to native types. */
|
||||
switch(wrapped_exception_type) {
|
||||
case JSTYPE_NUMBER:
|
||||
if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto error;
|
||||
break;
|
||||
case JSTYPE_BOOLEAN:
|
||||
if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto error;
|
||||
break;
|
||||
case JSTYPE_STRING:
|
||||
if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto error;
|
||||
break;
|
||||
case JSTYPE_VOID:
|
||||
js_exception = JSVAL_VOID;
|
||||
break;
|
||||
case JSTYPE_OBJECT:
|
||||
case JSTYPE_FUNCTION:
|
||||
default:
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
|
||||
js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
|
||||
if (!js_exception)
|
||||
goto error;
|
||||
} else {
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj,
|
||||
&js_exception))
|
||||
goto error;
|
||||
if (wrapped_exception_type != JSTYPE_EMPTY) {
|
||||
java_obj =
|
||||
(*jEnv)->GetObjectField(jEnv, java_exception,
|
||||
njJSException_wrappedException);
|
||||
|
||||
if ((java_obj == NULL) &&
|
||||
(wrapped_exception_type == JSTYPE_OBJECT)) {
|
||||
js_exception = JSVAL_NULL;
|
||||
} else {
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
/* OK to delete ref, since above call adds global ref */
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class);
|
||||
|
||||
/* Convert native JS values back to native types. */
|
||||
switch(wrapped_exception_type) {
|
||||
case JSTYPE_NUMBER:
|
||||
if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_BOOLEAN:
|
||||
if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_STRING:
|
||||
if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_VOID:
|
||||
js_exception = JSVAL_VOID;
|
||||
break;
|
||||
case JSTYPE_OBJECT:
|
||||
case JSTYPE_FUNCTION:
|
||||
default:
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
|
||||
js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
|
||||
if (!js_exception)
|
||||
goto do_report;
|
||||
} else {
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check for internal exception */
|
||||
} else {
|
||||
if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
|
||||
&js_exception)) {
|
||||
goto error;
|
||||
} else {
|
||||
if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
|
||||
&js_exception)) {
|
||||
goto do_report;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set pending JS exception and clear the java exception. */
|
||||
JS_SetPendingException(cx, js_exception);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set pending JS exception and clear the java exception. */
|
||||
JS_SetPendingException(cx, js_exception);
|
||||
goto done;
|
||||
|
||||
error:
|
||||
do_report:
|
||||
|
||||
JS_ASSERT(0);
|
||||
jsj_LogError("Out of memory while attempting to throw JSException\n");
|
||||
|
@ -420,7 +411,7 @@ jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array)
|
|||
static JSJavaThreadState *the_java_jsj_env = NULL;
|
||||
|
||||
JSJavaThreadState *
|
||||
jsj_EnterJava(JSContext *cx, JNIEnv **envp)
|
||||
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
|
||||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
char *err_msg;
|
||||
|
@ -438,24 +429,13 @@ jsj_EnterJava(JSContext *cx, JNIEnv **envp)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_ASSERT((jsj_env->recursion_depth == 0) || (jsj_env->cx == cx));
|
||||
jsj_env->recursion_depth++;
|
||||
/* need to assign the context field. */
|
||||
jsj_env->cx = cx;
|
||||
|
||||
if (envp)
|
||||
*envp = jsj_env->jEnv;
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
extern void
|
||||
jsj_ExitJava(JSJavaThreadState *jsj_env)
|
||||
{
|
||||
JS_ASSERT(jsj_env->recursion_depth > 0);
|
||||
if (--jsj_env->recursion_depth == 0)
|
||||
jsj_env->cx = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since only one Java thread is allowed to enter JavaScript, this function is
|
||||
* used to enforce the use of that thread's state. The static global the_java_jsj_env
|
||||
|
|
|
@ -78,9 +78,7 @@ typedef struct JSJCallbacks {
|
|||
callback can call JSJ_SetJSContextForJavaThread() to avoid any further
|
||||
callbacks of this type for this Java thread. */
|
||||
JSContext * (*map_jsj_thread_to_js_context)(JSJavaThreadState *jsj_env,
|
||||
#ifdef OJI
|
||||
void *java_applet_obj,
|
||||
#endif
|
||||
JNIEnv *jEnv,
|
||||
char **errp);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче