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:
fur%netscape.com 1999-06-24 05:56:16 +00:00
Родитель 05603647c8
Коммит e1ac50b525
12 изменённых файлов: 241 добавлений и 515 удалений

Просмотреть файл

@ -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);