Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}