Ejemplo n.º 1
0
bool
ScopedThreadSafeStringInspector::ensureChars(ThreadSafeContext *cx, const AutoCheckCannotGC &nogc)
{
    if (state_ != Uninitialized)
        return true;

    if (cx->isExclusiveContext()) {
        JSLinearString *linear = str_->ensureLinear(cx->asExclusiveContext());
        if (!linear)
            return false;
        if (linear->hasTwoByteChars()) {
            state_ = TwoByte;
            twoByteChars_ = linear->twoByteChars(nogc);
        } else {
            state_ = Latin1;
            latin1Chars_ = linear->latin1Chars(nogc);
        }
    } else {
        if (str_->isLinear()) {
            if (str_->hasLatin1Chars()) {
                state_ = Latin1;
                latin1Chars_ = str_->asLinear().latin1Chars(nogc);
            } else {
                state_ = TwoByte;
                twoByteChars_ = str_->asLinear().twoByteChars(nogc);
            }
        } else {
            if (str_->hasLatin1Chars()) {
                ScopedJSFreePtr<Latin1Char> chars;
                if (!str_->asRope().copyLatin1Chars(cx, chars))
                    return false;
                state_ = Latin1;
                latin1Chars_ = chars;
                scopedChars_ = chars.forget();
            } else {
                ScopedJSFreePtr<jschar> chars;
                if (!str_->asRope().copyTwoByteChars(cx, chars))
                    return false;
                state_ = TwoByte;
                twoByteChars_ = chars;
                scopedChars_ = chars.forget();
            }
        }
    }

    MOZ_ASSERT(state_ != Uninitialized);
    return true;
}
Ejemplo n.º 2
0
static JSString*
CopyStringPure(JSContext* cx, JSString* str)
{
    /*
     * Directly allocate the copy in the destination compartment, rather than
     * first flattening it (and possibly allocating in source compartment),
     * because we don't know whether the flattening will pay off later.
     */

    size_t len = str->length();
    JSString* copy;
    if (str->isLinear()) {
        /* Only use AutoStableStringChars if the NoGC allocation fails. */
        if (str->hasLatin1Chars()) {
            JS::AutoCheckCannotGC nogc;
            copy = NewStringCopyN<NoGC>(cx, str->asLinear().latin1Chars(nogc), len);
        } else {
            JS::AutoCheckCannotGC nogc;
            copy = NewStringCopyNDontDeflate<NoGC>(cx, str->asLinear().twoByteChars(nogc), len);
        }
        if (copy)
            return copy;

        AutoStableStringChars chars(cx);
        if (!chars.init(cx, str))
            return nullptr;

        return chars.isLatin1()
               ? NewStringCopyN<CanGC>(cx, chars.latin1Range().begin().get(), len)
               : NewStringCopyNDontDeflate<CanGC>(cx, chars.twoByteRange().begin().get(), len);
    }

    if (str->hasLatin1Chars()) {
        ScopedJSFreePtr<Latin1Char> copiedChars;
        if (!str->asRope().copyLatin1CharsZ(cx, copiedChars))
            return nullptr;

        return NewString<CanGC>(cx, copiedChars.forget(), len);
    }

    ScopedJSFreePtr<char16_t> copiedChars;
    if (!str->asRope().copyTwoByteCharsZ(cx, copiedChars))
        return nullptr;

    return NewStringDontDeflate<CanGC>(cx, copiedChars.forget(), len);
}
Ejemplo n.º 3
0
bool
JSCompartment::wrap(JSContext *cx, JSString **strp)
{
    JS_ASSERT(!cx->runtime()->isAtomsCompartment(this));
    JS_ASSERT(cx->compartment() == this);

    /* If the string is already in this compartment, we are done. */
    JSString *str = *strp;
    if (str->zone() == zone())
        return true;

    /* If the string is an atom, we don't have to copy. */
    if (str->isAtom()) {
        JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
        return true;
    }

    /* Check the cache. */
    RootedValue key(cx, StringValue(str));
    if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
        *strp = p->value().get().toString();
        return true;
    }

    /*
     * No dice. Make a copy, and cache it. Directly allocate the copy in the
     * destination compartment, rather than first flattening it (and possibly
     * allocating in source compartment), because we don't know whether the
     * flattening will pay off later.
     */
    JSString *copy;
    if (str->hasPureChars()) {
        copy = js_NewStringCopyN<CanGC>(cx, str->pureChars(), str->length());
    } else {
        ScopedJSFreePtr<jschar> copiedChars;
        if (!str->copyNonPureCharsZ(cx, copiedChars))
            return false;
        copy = js_NewString<CanGC>(cx, copiedChars.forget(), str->length());
    }

    if (!copy)
        return false;
    if (!putWrapper(cx, key, StringValue(copy)))
        return false;

    *strp = copy;
    return true;
}