? clasp == &js_FunctionClass
? clasp == &js_FunctionClass || clasp->call
JS_TypeOfValue(JSContext *cx, jsval v){    JSType type;    JSObject *obj;    JSObjectOps *ops;    JSClass *clasp;    CHECK_REQUEST(cx);    if (JSVAL_IS_OBJECT(v)) {        type = JSTYPE_OBJECT;           /* XXXbe JSTYPE_NULL for JS2 */        obj = JSVAL_TO_OBJECT(v);        if (obj) {            ops = obj->map->ops;#if JS_HAS_XML_SUPPORT            if (ops == &js_XMLObjectOps.base) {                type = JSTYPE_XML;            } else#endif            {                clasp = OBJ_GET_CLASS(cx, obj);                if ((ops == &js_ObjectOps)                    ? clasp == &js_FunctionClass                    : ops->call != NULL) {                    type = JSTYPE_FUNCTION;                } else {#ifdef NARCISSUS                    if (!OBJ_GET_PROPERTY(cx, obj,                                          ATOM_TO_JSID(cx->runtime->atomState                                                       .callAtom),                                          &v)) {                        JS_ClearPendingException(cx);                    } else if (JSVAL_IS_FUNCTION(cx, v)) {                        type = JSTYPE_FUNCTION;                    }#endif                }            }        }    } else if (JSVAL_IS_NUMBER(v)) {        type = JSTYPE_NUMBER;    } else if (JSVAL_IS_STRING(v)) {        type = JSTYPE_STRING;    } else if (JSVAL_IS_BOOLEAN(v)) {        type = JSTYPE_BOOLEAN;    } else {        type = JSTYPE_VOID;    }    return type;}