if (ln == 0) return right;
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right){    size_t rn, ln, lrdist, n;    jschar *rs, *ls, *s;    JSDependentString *ldep;    /* non-null if left should become dependent */    JSString *str;    if (JSSTRING_IS_DEPENDENT(right)) {        rn = JSSTRDEP_LENGTH(right);        rs = JSSTRDEP_CHARS(right);    } else {        rn = right->length;        rs = right->chars;    }    if (rn == 0)        return left;    if (JSSTRING_IS_DEPENDENT(left) ||        !(*js_GetGCThingFlags(left) & GCF_MUTABLE)) {        /* We must copy if left does not own a buffer to realloc. */        ln = JSSTRING_LENGTH(left);        ls = JSSTRING_CHARS(left);        s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar));        if (!s)            return NULL;        js_strncpy(s, ls, ln);        ldep = NULL;    } else {        /* We can realloc left's space and make it depend on our result. */        ln = left->length;        if (ln == 0)            return right;        ls = left->chars;        s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));        if (!s)            return NULL;         /* Take care: right could depend on left! */        lrdist = (size_t)(rs - ls);        if (lrdist < ln)            rs = s + lrdist;        left->chars = ls = s;        ldep = JSSTRDEP(left);    }    js_strncpy(s + ln, rs, rn);    n = ln + rn;    s[n] = 0;    str = js_NewString(cx, s, n, GCF_MUTABLE);    if (!str) {        /* Out of memory: clean up any space we (re-)allocated. */        if (!ldep) {            JS_free(cx, s);        } else {            s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar));            if (s)                left->chars = s;        }    } else {        /* Morph left into a dependent prefix if we realloc'd its buffer. */        if (ldep) {            JSPREFIX_SET_LENGTH(ldep, ln);            JSPREFIX_SET_BASE(ldep, str);#ifdef DEBUG          {            JSRuntime *rt = cx->runtime;            JS_RUNTIME_METER(rt, liveDependentStrings);            JS_RUNTIME_METER(rt, totalDependentStrings);            JS_LOCK_RUNTIME_VOID(rt,                (rt->strdepLengthSum += (double)ln,                 rt->strdepLengthSquaredSum += (double)ln * (double)ln));          }#endif        }    }    return str;}