Ejemplo n.º 1
0
/*
 * Convert to string.
 *
 * This method only uses JavaScript-modifiable properties name, message.  It
 * is left to the host to check for private data and report filename and line
 * number information along with this message.
 */
static JSBool
exn_toString(JSContext *cx, uintN argc, Value *vp)
{
    jsval v;
    JSString *name, *message, *result;
    jschar *chars, *cp;
    size_t name_length, message_length, length;

    JSObject *obj = ToObject(cx, &vp[1]);
    if (!obj)
        return JS_FALSE;
    if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(&v)))
        return JS_FALSE;
    name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
    vp->setString(name);

    if (!JS_GetProperty(cx, obj, js_message_str, &v))
        return JS_FALSE;
    message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
              : cx->runtime->emptyString;

    if (message->length() != 0) {
        name_length = name->length();
        message_length = message->length();
        length = (name_length ? name_length + 2 : 0) + message_length;
        cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
        if (!chars)
            return JS_FALSE;

        if (name_length) {
            const jschar *name_chars = name->getChars(cx);
            if (!name_chars)
                return JS_FALSE;
            js_strncpy(cp, name_chars, name_length);
            cp += name_length;
            *cp++ = ':';
            *cp++ = ' ';
        }
        const jschar *message_chars = message->getChars(cx);
        if (!message_chars)
            return JS_FALSE;
        js_strncpy(cp, message_chars, message_length);
        cp += message_length;
        *cp = 0;

        result = js_NewString(cx, chars, length);
        if (!result) {
            cx->free_(chars);
            return JS_FALSE;
        }
    } else {
        result = name;
    }

    vp->setString(result);
    return JS_TRUE;
}
Ejemplo n.º 2
0
static JSBool
IteratorNextImpl(JSContext *cx, JSObject *obj, jsval *rval)
{
    JSObject *iterable;
    jsval state;
    uintN flags;
    JSBool foreach, ok;
    jsid id;

    JS_ASSERT(obj->getClass() == &js_IteratorClass);

    iterable = obj->getParent();
    JS_ASSERT(iterable);
    state = obj->getSlot(JSSLOT_ITER_STATE);
    if (JSVAL_IS_NULL(state))
        goto stop;

    flags = JSVAL_TO_INT(obj->getSlot(JSSLOT_ITER_FLAGS));
    JS_ASSERT(!(flags & JSITER_ENUMERATE));
    foreach = (flags & JSITER_FOREACH) != 0;
    ok =
#if JS_HAS_XML_SUPPORT
         (foreach && OBJECT_IS_XML(cx, iterable))
         ? js_EnumerateXMLValues(cx, iterable, JSENUMERATE_NEXT, &state,
                                 &id, rval)
         :
#endif
           iterable->enumerate(cx, JSENUMERATE_NEXT, &state, &id);
    if (!ok)
        return JS_FALSE;

    obj->setSlot(JSSLOT_ITER_STATE, state);
    if (JSVAL_IS_NULL(state))
        goto stop;

    if (foreach) {
#if JS_HAS_XML_SUPPORT
        if (!OBJECT_IS_XML(cx, iterable) &&
            !iterable->getProperty(cx, id, rval)) {
            return JS_FALSE;
        }
#endif
        if (!NewKeyValuePair(cx, id, *rval, rval))
            return JS_FALSE;
    } else {
        *rval = ID_TO_VALUE(id);
    }
    return JS_TRUE;

  stop:
    JS_ASSERT(obj->getSlot(JSSLOT_ITER_STATE) == JSVAL_NULL);
    *rval = JSVAL_HOLE;
    return JS_TRUE;
}
Ejemplo n.º 3
0
static JSBool
JA(JSContext *cx, Value *vp, StringifyContext *scx)
{
    JSObject *obj = &vp->toObject();

    CycleDetector detect(scx, obj);
    if (!detect.init(cx))
        return JS_FALSE;

    if (!scx->sb.append('['))
        return JS_FALSE;

    jsuint length;
    if (!js_GetLengthProperty(cx, obj, &length))
        return JS_FALSE;

    if (length != 0 && !WriteIndent(cx, scx, scx->depth))
        return JS_FALSE;

    AutoValueRooter outputValue(cx);

    jsid id;
    jsuint i;
    for (i = 0; i < length; i++) {
        id = INT_TO_JSID(i);

        if (!obj->getProperty(cx, id, outputValue.addr()))
            return JS_FALSE;

        if (!Str(cx, id, obj, scx, outputValue.addr()))
            return JS_FALSE;

        if (outputValue.value().isUndefined()) {
            if (!scx->sb.append("null"))
                return JS_FALSE;
        }

        if (i < length - 1) {
            if (!scx->sb.append(','))
                return JS_FALSE;
            if (!WriteIndent(cx, scx, scx->depth))
                return JS_FALSE;
        }
    }

    if (length != 0 && !WriteIndent(cx, scx, scx->depth - 1))
        return JS_FALSE;

    return scx->sb.append(']');
}
Ejemplo n.º 4
0
/*
 * Convert to string.
 *
 * This method only uses JavaScript-modifiable properties name, message.  It
 * is left to the host to check for private data and report filename and line
 * number information along with this message.
 */
static JSBool
exn_toString(JSContext *cx, uintN argc, jsval *vp)
{
    JSObject *obj;
    jsval v;
    JSString *name, *message, *result;
    jschar *chars, *cp;
    size_t name_length, message_length, length;

    obj = JS_THIS_OBJECT(cx, vp);
    if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), &v))
        return JS_FALSE;
    name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
    *vp = STRING_TO_JSVAL(name);

    if (!JS_GetProperty(cx, obj, js_message_str, &v))
        return JS_FALSE;
    message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
                                 : cx->runtime->emptyString;

    if (message->length() != 0) {
        name_length = name->length();
        message_length = message->length();
        length = (name_length ? name_length + 2 : 0) + message_length;
        cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
        if (!chars)
            return JS_FALSE;

        if (name_length) {
            js_strncpy(cp, name->chars(), name_length);
            cp += name_length;
            *cp++ = ':'; *cp++ = ' ';
        }
        js_strncpy(cp, message->chars(), message_length);
        cp += message_length;
        *cp = 0;

        result = js_NewString(cx, chars, length);
        if (!result) {
            cx->free(chars);
            return JS_FALSE;
        }
    } else {
        result = name;
    }

    *vp = STRING_TO_JSVAL(result);
    return JS_TRUE;
}
Ejemplo n.º 5
0
static JSBool
JA(JSContext *cx, jsval *vp, StringifyContext *scx)
{
    JSObject *obj = JSVAL_TO_OBJECT(*vp);

    if (!scx->cb.append('['))
        return JS_FALSE;

    jsuint length;
    if (!js_GetLengthProperty(cx, obj, &length))
        return JS_FALSE;

    jsval outputValue = JSVAL_NULL;
    JSAutoTempValueRooter tvr(cx, 1, &outputValue);

    jsid id;
    jsuint i;
    for (i = 0; i < length; i++) {
        id = INT_TO_JSID(i);

        if (!obj->getProperty(cx, id, &outputValue))
            return JS_FALSE;

        if (!Str(cx, id, obj, scx, &outputValue))
            return JS_FALSE;

        if (outputValue == JSVAL_VOID) {
            if (!js_AppendLiteral(scx->cb, "null"))
                return JS_FALSE;
        }

        if (i < length - 1) {
            if (!scx->cb.append(','))
                return JS_FALSE;
            if (!WriteIndent(cx, scx, scx->depth))
                return JS_FALSE;
        }
    }

    if (length != 0 && !WriteIndent(cx, scx, scx->depth - 1))
        return JS_FALSE;

    return scx->cb.append(']');
}
Ejemplo n.º 6
0
/*
 * Return a string that may eval to something similar to the original object.
 */
static JSBool
exn_toSource(JSContext *cx, uintN argc, Value *vp)
{
    JSString *name, *message, *filename, *lineno_as_str, *result;
    jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
    size_t lineno_length, name_length, message_length, filename_length, length;
    jschar *chars, *cp;

    JSObject *obj = ToObject(cx, &vp[1]);
    if (!obj)
        return false;
    if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp))
        return false;
    name = js_ValueToString(cx, *vp);
    if (!name)
        return false;
    vp->setString(name);

    {
        AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), Valueify(localroots));

#ifdef __GNUC__
        message = filename = NULL;
#endif
        if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) ||
                !(message = js_ValueToSource(cx, Valueify(localroots[0])))) {
            return false;
        }
        localroots[0] = STRING_TO_JSVAL(message);

        if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) ||
                !(filename = js_ValueToSource(cx, Valueify(localroots[1])))) {
            return false;
        }
        localroots[1] = STRING_TO_JSVAL(filename);

        if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]))
            return false;
        uint32_t lineno;
        if (!ValueToECMAUint32(cx, Valueify(localroots[2]), &lineno))
            return false;

        if (lineno != 0) {
            lineno_as_str = js_ValueToString(cx, Valueify(localroots[2]));
            if (!lineno_as_str)
                return false;
            lineno_length = lineno_as_str->length();
        } else {
            lineno_as_str = NULL;
            lineno_length = 0;
        }

        /* Magic 8, for the characters in ``(new ())''. */
        name_length = name->length();
        message_length = message->length();
        length = 8 + name_length + message_length;

        filename_length = filename->length();
        if (filename_length != 0) {
            /* append filename as ``, {filename}'' */
            length += 2 + filename_length;
            if (lineno_as_str) {
                /* append lineno as ``, {lineno_as_str}'' */
                length += 2 + lineno_length;
            }
        } else {
            if (lineno_as_str) {
                /*
                 * no filename, but have line number,
                 * need to append ``, "", {lineno_as_str}''
                 */
                length += 6 + lineno_length;
            }
        }

        cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
        if (!chars)
            return false;

        *cp++ = '(';
        *cp++ = 'n';
        *cp++ = 'e';
        *cp++ = 'w';
        *cp++ = ' ';
        const jschar *name_chars = name->getChars(cx);
        if (!name_chars)
            return false;
        js_strncpy(cp, name_chars, name_length);
        cp += name_length;
        *cp++ = '(';
        const jschar *message_chars = message->getChars(cx);
        if (!message_chars)
            return false;
        if (message_length != 0) {
            js_strncpy(cp, message_chars, message_length);
            cp += message_length;
        }

        if (filename_length != 0) {
            /* append filename as ``, {filename}'' */
            *cp++ = ',';
            *cp++ = ' ';
            const jschar *filename_chars = filename->getChars(cx);
            if (!filename_chars)
                return false;
            js_strncpy(cp, filename_chars, filename_length);
            cp += filename_length;
        } else {
            if (lineno_as_str) {
                /*
                 * no filename, but have line number,
                 * need to append ``, "", {lineno_as_str}''
                 */
                *cp++ = ',';
                *cp++ = ' ';
                *cp++ = '"';
                *cp++ = '"';
            }
        }
        if (lineno_as_str) {
            /* append lineno as ``, {lineno_as_str}'' */
            *cp++ = ',';
            *cp++ = ' ';
            const jschar *lineno_chars = lineno_as_str->getChars(cx);
            if (!lineno_chars)
                return false;
            js_strncpy(cp, lineno_chars, lineno_length);
            cp += lineno_length;
        }

        *cp++ = ')';
        *cp++ = ')';
        *cp = 0;

        result = js_NewString(cx, chars, length);
        if (!result) {
            cx->free_(chars);
            return false;
        }
        vp->setString(result);
        return true;
    }
}
Ejemplo n.º 7
0
/*
 * Return a string that may eval to something similar to the original object.
 */
static JSBool
exn_toSource(JSContext *cx, uintN argc, jsval *vp)
{
    JSObject *obj;
    JSString *name, *message, *filename, *lineno_as_str, *result;
    jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
    JSTempValueRooter tvr;
    JSBool ok;
    uint32 lineno;
    size_t lineno_length, name_length, message_length, filename_length, length;
    jschar *chars, *cp;

    obj = JS_THIS_OBJECT(cx, vp);
    if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp))
        return JS_FALSE;
    name = js_ValueToString(cx, *vp);
    if (!name)
        return JS_FALSE;
    *vp = STRING_TO_JSVAL(name);

    MUST_FLOW_THROUGH("out");
    JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr);

#ifdef __GNUC__
    message = filename = NULL;
#endif
    ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) &&
         (message = js_ValueToSource(cx, localroots[0]));
    if (!ok)
        goto out;
    localroots[0] = STRING_TO_JSVAL(message);

    ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) &&
         (filename = js_ValueToSource(cx, localroots[1]));
    if (!ok)
        goto out;
    localroots[1] = STRING_TO_JSVAL(filename);

    ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]);
    if (!ok)
        goto out;
    lineno = js_ValueToECMAUint32 (cx, &localroots[2]);
    ok = !JSVAL_IS_NULL(localroots[2]);
    if (!ok)
        goto out;

    if (lineno != 0) {
        lineno_as_str = js_ValueToString(cx, localroots[2]);
        if (!lineno_as_str) {
            ok = JS_FALSE;
            goto out;
        }
        lineno_length = lineno_as_str->length();
    } else {
        lineno_as_str = NULL;
        lineno_length = 0;
    }

    /* Magic 8, for the characters in ``(new ())''. */
    name_length = name->length();
    message_length = message->length();
    length = 8 + name_length + message_length;

    filename_length = filename->length();
    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        length += 2 + filename_length;
        if (lineno_as_str) {
            /* append lineno as ``, {lineno_as_str}'' */
            length += 2 + lineno_length;
        }
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            length += 6 + lineno_length;
        }
    }

    cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
    if (!chars) {
        ok = JS_FALSE;
        goto out;
    }

    *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
    js_strncpy(cp, name->chars(), name_length);
    cp += name_length;
    *cp++ = '(';
    if (message_length != 0) {
        js_strncpy(cp, message->chars(), message_length);
        cp += message_length;
    }

    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, filename->chars(), filename_length);
        cp += filename_length;
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
        }
    }
    if (lineno_as_str) {
        /* append lineno as ``, {lineno_as_str}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, lineno_as_str->chars(), lineno_length);
        cp += lineno_length;
    }

    *cp++ = ')'; *cp++ = ')'; *cp = 0;

    result = js_NewString(cx, chars, length);
    if (!result) {
        cx->free(chars);
        ok = JS_FALSE;
        goto out;
    }
    *vp = STRING_TO_JSVAL(result);
    ok = JS_TRUE;

out:
    JS_POP_TEMP_ROOT(cx, &tvr);
    return ok;
}