JS_ReportError(cx, "can't watch non-native objects of class %s", OBJ_GET_CLASS(cx, obj)->name);
JS_ReportErrorNumber(cx, NULL, JSMSG_CANT_WATCH, OBJ_GET_CLASS(cx, obj)->name);
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,		 JSWatchPointHandler handler, void *closure){    JSAtom *atom;    jsid symid;    JSObject *pobj;    JSScopeProperty *sprop;    JSRuntime *rt;    JSWatchPoint *wp;    if (!OBJ_IS_NATIVE(obj)) {	JS_ReportError(cx, "can't watch non-native objects of class %s",		       OBJ_GET_CLASS(cx, obj)->name);	return JS_FALSE;    }    if (JSVAL_IS_INT(id)) {	symid = (jsid)id;	atom = NULL;    } else {	atom = js_ValueToStringAtom(cx, id);	if (!atom)	    return JS_FALSE;	symid = (jsid)atom;    }    if (!js_LookupProperty(cx, obj, symid, &pobj, (JSProperty **)&sprop))	return JS_FALSE;    rt = cx->runtime;    if (!sprop) {	/* Check for a deleted symbol watchpoint, which holds its property. */	sprop = js_FindWatchPoint(rt, obj, id);	if (sprop) {#ifdef JS_THREADSAFE	    /* Emulate js_LookupProperty if thread-safe. */	    JS_LOCK_OBJ(cx, obj);	    sprop->nrefs++;#endif	} else {	    /* Make a new property in obj so we can watch for the first set. */	    if (!js_DefineProperty(cx, obj, symid, JSVAL_VOID, NULL, NULL, 0,				   (JSProperty **)&sprop)) {		sprop = NULL;	    }	}    } else if (pobj != obj) {	/* Clone the prototype property so we can watch the right object. */	jsval value;	JSPropertyOp getter, setter;	uintN attrs;	if (OBJ_IS_NATIVE(pobj)) {	    value = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);	} else {	    if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) {		OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);		return JS_FALSE;	    }	}	getter = sprop->getter;	setter = sprop->setter;	attrs = sprop->attrs;	OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);	if (!js_DefineProperty(cx, obj, symid, value, getter, setter, attrs,			       (JSProperty **)&sprop)) {	    sprop = NULL;	}    }    if (!sprop)	return JS_FALSE;    wp = FindWatchPoint(rt, obj, id);    if (!wp) {	wp = JS_malloc(cx, sizeof *wp);	if (!wp)	    return JS_FALSE;	if (!js_AddRoot(cx, &wp->closure, "wp->closure")) {	    JS_free(cx, wp);	    return JS_FALSE;	}	PR_APPEND_LINK(&wp->links, &rt->watchPointList);	wp->object = obj;	wp->userid = id;	wp->sprop = js_HoldScopeProperty(cx, (JSScope *)obj->map, sprop);	wp->setter = sprop->setter;	sprop->setter = js_watch_set;	wp->nrefs = 1;    }    wp->handler = handler;    wp->closure = closure;    OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);    return JS_TRUE;}