if (vp) {
if (proto_chainp && prop_infop) {
lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,                    JavaObjectWrapper **java_wrapperp,                    jsid id,                    JavaMemberDescriptor **member_descriptorp,                    jsval *vp){    jsval idval;    JavaObjectWrapper *java_wrapper;    JavaMemberDescriptor *member_descriptor;    const char *member_name;    JavaClassDescriptor *class_descriptor;    JSObject *proto_chain;        member_descriptor = NULL;    java_wrapper = JS_GetPrivate(cx, obj);    /* Handle accesses to prototype object */    if (!java_wrapper) {        if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&            (member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {            if (!strcmp(member_name, "constructor"))                goto done;        }        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_OP_JOBJECT);        return JS_FALSE;    }        class_descriptor = java_wrapper->class_descriptor;    JS_ASSERT(IS_REFERENCE_TYPE(class_descriptor->type));        member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);    if (member_descriptor)        goto done;        /* Instances can reference static methods and fields */    member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);    if (member_descriptor)        goto done;    /* Ensure that the property we're searching for is string-valued. */    JS_IdToValue(cx, id, &idval);    if (!JSVAL_IS_STRING(idval)) {        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_JOBJECT_EXPR);        return JS_FALSE;    }    member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));    /*     * A little LC3 feature magic:     *   + Instances of java.lang.String "inherit" the standard ECMA string methods     *     of String.prototype.  All of the ECMA string methods convert the Java     *     string to a JS string before performing the string operation.  For example,     *         s = new java.lang.String("foobar");     *         return s.slice(2);     *   + Similarly, instances of Java arrays "inherit" the standard ECMA array     *     methods of Array.prototype.  (Not all of these methods work properly     *     on JavaArray objects, however, since the 'length' property is read-only.)     */    if (vp) {        if ((class_descriptor->type == JAVA_SIGNATURE_JAVA_LANG_STRING) &&            inherit_props_from_JS_natives(cx, "String", member_name, vp))            goto done;        if ((class_descriptor->type == JAVA_SIGNATURE_ARRAY) &&            inherit_props_from_JS_natives(cx, "Array", member_name, vp))            goto done;    }    /* Check for access to magic prototype chain property */    if (!strcmp(member_name, "__proto__")) {        proto_chain = JS_GetPrototype(cx, obj);        if (vp)            *vp = OBJECT_TO_JSVAL(proto_chain);        goto done;    }        /*     * See if the property looks like the explicit resolution of an     * overloaded method, e.g. "max(double,double)", first as an instance method,     * then as a static method.  If we find such a method, it will be cached     * so future accesses won't run this code.     */    member_descriptor = jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_FALSE);    if (member_descriptor)        goto done;    member_descriptor = jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_TRUE);    if (member_descriptor)        goto done;        /* Is this lookup on behalf of a GetProperty or a LookupProperty ? */    if (vp) {        /* If so, follow __proto__ link to search prototype chain */        proto_chain = JS_GetPrototype(cx, obj);        /* TODO: No way to tell if the property doesn't exist in proto_chain           or if it exists, but has an undefined value.  We assume the former. */        if (proto_chain && JS_LookupProperty(cx, proto_chain, member_name, vp) &&            (*vp != JSVAL_VOID))            goto done;    }    /* Report lack of Java member with the given property name */    JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NO_INSTANCE_NAME,                         class_descriptor->name, member_name);    return JS_FALSE;done:    /* Success.  Handle the multiple return values */    if (java_wrapperp)        *java_wrapperp = java_wrapper;    if (member_descriptorp)        *member_descriptorp = member_descriptor;    return JS_TRUE;}