/* * Free up a JavaFieldSpec and all its resources. */ void jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field) { JS_FREE_IF(cx, (char*)field->name); jsj_ReleaseJavaClassDescriptor(cx, jEnv, field->signature); JS_free(cx, field); }
static void destroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor) { JS_FREE_IF(cx, (char *)class_descriptor->name); if (class_descriptor->java_class) (*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class); if (class_descriptor->array_component_signature) jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature); destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members); destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members); destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors); JS_free(cx, class_descriptor); }
static void destroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor) { JavaMethodSpec *method, *next_method; if (member_descriptor->field) jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field); method = member_descriptor->methods; while (method) { next_method = method->next; jsj_DestroyMethodSpec(cx, jEnv, method); method = next_method; } JS_RemoveRoot(cx, &member_descriptor->invoke_func_obj); JS_FREE_IF(cx, (char *)member_descriptor->name); JS_free(cx, member_descriptor); }
/* * Pre-define a hierarchy of JavaPackage objects. * Pre-defining a Java package at initialization time is not necessary, but * it will make package lookup faster and, more importantly, will avoid * unnecessary network accesses if classes are being loaded over the network. */ static JSBool pre_define_java_packages(JSContext *cx, JSObject *global_obj, JavaPackageDef *predefined_packages) { JSBool package_exists; JSObject *parent_obj; JavaPackageDef *package_def; char *simple_name, *cp, *package_name, *path; int flags; if (!predefined_packages) return JS_TRUE; /* Iterate over all pre-defined Java packages */ for (package_def = predefined_packages; package_def->name; package_def++) { #if HAVE_STRTOK_R char *nextstr; #endif package_name = path = NULL; parent_obj = global_obj; package_name = strdup(package_def->name); if (!package_name) goto out_of_memory; /* Walk the chain of JavaPackage objects to get to the parent of the rightmost sub-package in the fully-qualified package name. */ for (simple_name = STRTOK_1ST(package_name, ".", nextstr); simple_name /*1*/; simple_name = STRTOK_OTHER(".", nextstr)) { jsval v; if (!simple_name) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_DOUBLE_SHIPPING, package_name); goto error; } /* Check to see if the sub-package already exists */ quiet_resolve_failure = JS_TRUE; package_exists = JS_LookupProperty(cx, parent_obj, simple_name, &v) && JSVAL_IS_OBJECT(v); quiet_resolve_failure = JS_FALSE; if (package_exists) { parent_obj = JSVAL_TO_OBJECT(v); continue; } /* New package objects should only be created at the terminal sub-package in a fully-qualified package-name */ if (STRTOK_OTHER(".", nextstr)) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_PACKAGE_PREDEF, package_def->name); goto error; } if (package_def->path) { path = strdup(package_def->path); if (!path) goto out_of_memory; } else { /* * The default path is specified, so create it from the * fully-qualified package name. */ path = strdup(package_def->name); if (!path) goto out_of_memory; /* Transform package name, e.g. "java.lang" ==> "java/lang" */ for (cp = path; *cp != '\0'; cp++) { if (*cp == '.') *cp = '/'; } } flags = package_def->flags; parent_obj = define_JavaPackage(cx, parent_obj, simple_name, path, flags, package_def->access); if (!parent_obj) goto error; free(path); break; } free(package_name); } return JS_TRUE; out_of_memory: JS_ReportOutOfMemory(cx); error: JS_FREE_IF(cx, package_name); JS_FREE_IF(cx, path); return JS_FALSE; }
/* * 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; }