JSBool JS_DLL_CALLBACK js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSRuntime *rt; JSWatchPoint *wp; JSScopeProperty *sprop; jsval userid; JSScope *scope; JSBool ok; rt = cx->runtime; for (wp = (JSWatchPoint *)rt->watchPointList.next; wp != (JSWatchPoint *)&rt->watchPointList; wp = (JSWatchPoint *)wp->links.next) { sprop = wp->sprop; if (wp->object == obj && SPROP_USERID(sprop) == id) { JS_LOCK_OBJ(cx, obj); userid = SPROP_USERID(sprop); scope = OBJ_SCOPE(obj); JS_UNLOCK_OBJ(cx, obj); HoldWatchPoint(wp); ok = wp->handler(cx, obj, userid, SPROP_HAS_VALID_SLOT(sprop, scope) ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot) : JSVAL_VOID, vp, wp->closure); if (ok) { /* * Create pseudo-frame for call to setter so that any * stack-walking security code in the setter will correctly * identify the guilty party. */ JSObject *funobj = (JSObject *) wp->closure; JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj); JSStackFrame frame; memset(&frame, 0, sizeof(frame)); frame.script = fun->script; frame.fun = fun; frame.down = cx->fp; cx->fp = &frame; ok = !wp->setter || ((sprop->attrs & JSPROP_SETTER) ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter), 1, vp, vp) : wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp)); cx->fp = frame.down; } return DropWatchPoint(cx, wp); } } JS_ASSERT(0); /* XXX can't happen */ return JS_FALSE; }
static int sort_compare(const void *a, const void *b, void *arg) { jsval av = *(const jsval *)a, bv = *(const jsval *)b; CompareArgs *ca = (CompareArgs *) arg; JSContext *cx = ca->context; jsdouble cmp = -1; jsval fval, argv[2], rval; JSBool ok; fval = ca->fval; if (fval == JSVAL_NULL) { JSString *astr, *bstr; if (av == bv) { cmp = 0; } else if (av == JSVAL_VOID || bv == JSVAL_VOID) { /* Put undefined properties at the end. */ cmp = (av == JSVAL_VOID) ? 1 : -1; } else if ((astr = js_ValueToString(cx, av)) != NULL && (bstr = js_ValueToString(cx, bv)) != NULL) { cmp = js_CompareStrings(astr, bstr); } else { ca->status = JS_FALSE; } } else { argv[0] = av; argv[1] = bv; ok = js_InternalCall(cx, OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)), fval, 2, argv, &rval); if (ok) { ok = js_ValueToNumber(cx, rval, &cmp); /* Clamp cmp to -1, 0, 1. */ if (JSDOUBLE_IS_NaN(cmp)) { /* XXX report some kind of error here? ECMA talks about * 'consistent compare functions' that don't return NaN, but is * silent about what the result should be. So we currently * ignore it. */ cmp = 0; } else if (cmp != 0) { cmp = cmp > 0 ? 1 : -1; } } else { ca->status = ok; } } return (int)cmp; }
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval) { uintN flags; /* Fast path for native iterators */ if (OBJ_GET_CLASS(cx, iterobj) == &js_IteratorClass) { flags = JSVAL_TO_INT(STOBJ_GET_SLOT(iterobj, JSSLOT_ITER_FLAGS)); if (flags & JSITER_ENUMERATE) return CallEnumeratorNext(cx, iterobj, flags, rval); /* * Call next directly as all the methods of the native iterator are * read-only and permanent. */ if (!IteratorNextImpl(cx, iterobj, rval)) return JS_FALSE; } else { jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom); if (!JS_GetMethodById(cx, iterobj, id, &iterobj, rval)) return JS_FALSE; if (!js_InternalCall(cx, iterobj, *rval, 0, NULL, rval)) { /* Check for StopIteration. */ if (!cx->throwing || JSVAL_IS_PRIMITIVE(cx->exception) || OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(cx->exception)) != &js_StopIterationClass) { return JS_FALSE; } /* Inline JS_ClearPendingException(cx). */ cx->throwing = JS_FALSE; cx->exception = JSVAL_VOID; *rval = JSVAL_HOLE; return JS_TRUE; } } return JS_TRUE; }