JavaMemberDescriptor * jsj_GetJavaMemberDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jstring member_name_jstr) { JavaMemberDescriptor *member_descriptor; jsid id; if (!JavaStringToId(cx, jEnv, member_name_jstr, &id)) return NULL; member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id); if (member_descriptor) return member_descriptor; member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); if (!member_descriptor) return NULL; memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr); if (!member_descriptor->name) { JS_free(cx, member_descriptor); return NULL; } member_descriptor->id = id; member_descriptor->next = class_descriptor->instance_members; class_descriptor->instance_members = member_descriptor; return member_descriptor; }
/* * Given a JVM handle to a java.lang.Class object, malloc a C-string * containing the UTF8 encoding of the fully qualified name of the class. * It's the caller's responsibility to free the returned string. * * If an error occurs, NULL is returned and the error reporter called. */ const char * jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class) { jstring java_class_name_jstr; const char *java_class_name; /* Get java.lang.String object containing class name */ java_class_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName); if (!java_class_name_jstr) goto error; /* Fix bugzilla #183092 * It is necessary to check Exception from JPI * even though java_class_name_jstr != null */ #ifdef XP_UNIX if ((*jEnv)->ExceptionOccurred(jEnv)) goto error; #endif /* Convert to UTF8 encoding and copy */ java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr); (*jEnv)->DeleteLocalRef(jEnv, java_class_name_jstr); return java_class_name; error: jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using" "java.lang.Class.getName()"); return NULL; }
/* * Return, as a C string, the JVM stack trace associated with a Java * exception, as would be printed by java.lang.Throwable.printStackTrace(). * The caller is responsible for free'ing the returned string. * * Returns NULL if an error occurs. */ static const char * get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception) { const char *backtrace; jstring backtrace_jstr; backtrace = NULL; if (java_exception && njJSUtil_getStackTrace) { backtrace_jstr = (*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil, njJSUtil_getStackTrace, java_exception); if (!backtrace_jstr) { jsj_UnexpectedJavaError(cx, jEnv, "Unable to get exception stack trace"); return NULL; } backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr); (*jEnv)->DeleteLocalRef(jEnv, backtrace_jstr); } return backtrace; }
/* * Add a single field, described by java_field, to the JavaMemberDescriptor * named by field_name within the given JavaClassDescriptor. * * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error. */ static JSBool add_java_field_to_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, jstring field_name_jstr, jobject java_field, /* a java.lang.reflect.Field */ jint modifiers) { jclass fieldType; jfieldID fieldID; jclass java_class; JSBool is_static_field; JavaMemberDescriptor *member_descriptor = NULL; const char *sig_cstr = NULL; const char *field_name = NULL; JavaSignature *signature = NULL; JavaFieldSpec *field_spec = NULL; is_static_field = modifiers & ACC_STATIC; if (is_static_field) { member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr); } else { member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr); } if (!member_descriptor) goto error; field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec)); if (!field_spec) goto error; field_spec->modifiers = modifiers; /* Get the Java class corresponding to the type of the field */ fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType); if (!fieldType) { jsj_UnexpectedJavaError(cx, jEnv, "Unable to determine type of field using" " java.lang.reflect.Field.getType()"); goto error; } signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType); (*jEnv)->DeleteLocalRef(jEnv, fieldType); if (!signature) goto error; field_spec->signature = signature; field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr); if (!field_name) goto error; field_spec->name = field_name; /* Compute the JNI-style (string-based) signature of the field type */ sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature); if (!sig_cstr) goto error; /* Compute the JNI fieldID and cache it for quick field access */ java_class = class_descriptor->java_class; if (is_static_field) fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr); else fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr); if (!fieldID) { jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java field ID for class %s, field %s (sig=%s)", class_descriptor->name, field_name, sig_cstr); goto error; } field_spec->fieldID = fieldID; JS_free(cx, (char*)sig_cstr); member_descriptor->field = field_spec; /* Success */ return JS_TRUE; error: if (field_spec) { JS_FREE_IF(cx, (char*)field_spec->name); JS_free(cx, field_spec); } JS_FREE_IF(cx, (char*)sig_cstr); if (signature) jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature); return JS_FALSE; }