* new value is not a getter or setter -- or if it is, insist that the * property being replaced is not permanent.
* new value is not a getter if the old value was, ditto for setters -- * unless prop is impermanent (in which case anyone could delete it and * redefine it, willy-nilly).
js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,                      JSBool *foundp){    JSObject *obj2;    JSProperty *prop;    JSBool ok;    uintN oldAttrs, report;    JSBool isFunction;    jsval value;    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))        return JS_FALSE;    *foundp = (prop != NULL);    if (!prop)        return JS_TRUE;    ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs);    OBJ_DROP_PROPERTY(cx, obj2, prop);    if (!ok)        return JS_FALSE;    /* If either property is readonly, we have an error. */    report = ((oldAttrs | attrs) & JSPROP_READONLY)             ? JSREPORT_ERROR             : JSREPORT_WARNING | JSREPORT_STRICT;    if (report != JSREPORT_ERROR) {        /*         * Allow redeclaration of variables and functions, but insist that the         * new value is not a getter or setter -- or if it is, insist that the         * property being replaced is not permanent.         */        if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER)))            return JS_TRUE;        if (!(oldAttrs & JSPROP_PERMANENT))            return JS_TRUE;        report = JSREPORT_ERROR;    }    isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0;    if (!isFunction) {        if (!OBJ_GET_PROPERTY(cx, obj, id, &value))            return JS_FALSE;        isFunction = JSVAL_IS_FUNCTION(cx, value);    }    return JS_ReportErrorFlagsAndNumber(cx, report,                                        js_GetErrorMessage, NULL,                                        JSMSG_REDECLARED_VAR,                                        isFunction                                        ? js_function_str                                        : (oldAttrs & JSPROP_READONLY)                                        ? js_const_str                                        : js_var_str,                                        ATOM_BYTES((JSAtom *)id));}