JS_ReportError(cx, "%s is permanent", JS_GetStringBytes(str));
JS_ReportErrorNumber(cx, NULL, JSMSG_PERMANENT, JS_GetStringBytes(str));
js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval){#if JS_HAS_PROP_DELETE    JSRuntime *rt;    JSObject *proto;    JSProperty *prop;    JSScopeProperty *sprop;    JSString *str;    JSScope *scope;    JSSymbol *sym;    rt = cx->runtime;    *rval = JSVERSION_IS_ECMA(cx->version) ? JSVAL_TRUE : JSVAL_VOID;    /* Handle old bug that treated empty string as zero index.     * Also convert string indices to numbers if applicable. */    CHECK_FOR_FUNNY_INDEX(id);    if (!js_LookupProperty(cx, obj, id, &proto, &prop))	return JS_FALSE;    if (!prop || proto != obj) {	if (prop)	    OBJ_DROP_PROPERTY(cx, proto, prop);	/*	 * If no property, or the property comes from a prototype, call the	 * class's delProperty hook with rval as the result parameter.	 */	return OBJ_GET_CLASS(cx, obj)->delProperty(cx, obj, js_IdToValue(id),						   rval);    }    sprop = (JSScopeProperty *)prop;    if (sprop->attrs & JSPROP_PERMANENT) {	OBJ_DROP_PROPERTY(cx, obj, prop);	if (JSVERSION_IS_ECMA(cx->version)) {	    *rval = JSVAL_FALSE;	    return JS_TRUE;	}	str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL);	if (str)	    JS_ReportError(cx, "%s is permanent", JS_GetStringBytes(str));	return JS_FALSE;    }    /* XXXbe called with obj locked */    if (!LOCKED_OBJ_GET_CLASS(obj)->delProperty(cx, obj, sprop->id, rval)) {	OBJ_DROP_PROPERTY(cx, obj, prop);	return JS_FALSE;    }    GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot));    scope = (JSScope *)obj->map;    /*     * Purge cache only if prop is not about to be destroyed (since     * js_DestroyScopeProperty purges for us).     */    if (sprop->nrefs != 1) {	PROPERTY_CACHE_FILL(cx, &rt->propertyCache, obj, id,			    PROP_NOT_FOUND(obj, id));    }#if JS_HAS_OBJ_WATCHPOINT    if (sprop->setter == js_watch_set) {	/*	 * Keep the symbol around with null value in case of re-set.	 * The watchpoint will hold the "deleted" property until it	 * is removed by obj_unwatch or a native JS_ClearWatchPoint.	 * See js_SetProperty for the re-set logic.	 */	for (sym = sprop->symbols; sym; sym = sym->next) {	    if (sym_id(sym) == id) {		sym->entry.value = NULL;		sprop = js_DropScopeProperty(cx, scope, sprop);		PR_ASSERT(sprop);		goto out;	    }	}    }#endif /* JS_HAS_OBJ_WATCHPOINT */    scope->ops->remove(cx, scope, id);out:    OBJ_DROP_PROPERTY(cx, obj, prop);    return JS_TRUE;#else  /* !JS_HAS_PROP_DELETE */    jsval null = JSVAL_NULL;    *rval = JSVAL_VOID;    return js_SetProperty(cx, obj, id, &null);#endif /* !JS_HAS_PROP_DELETE */}