if ((size_t)i == length) {  sep->chars = NULL; }
find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip,           JSSubString *sep){    jsint i, j, k;    jschar *chars;    size_t length;    /*     * Stop if past end of string.  If at end of string, we will compare the     * null char stored there (by js_NewString*) to sep->chars[j] in the while     * loop at the end of this function, so that     *     *  "ab,".split(',') => ["ab", ""]     *     * and the resulting array converts back to the string "ab," for symmetry.     * However, we ape Perl and do this only if there is a sufficiently large     * limit argument (see str_split).     */    i = *ip;    if ((size_t)i > JSSTRING_LENGTH(str))        return -1;    /*     * Perl4 special case for str.split(' '), only if the user has selected     * JavaScript1.2 explicitly.  Split on whitespace, and skip leading w/s.     * Strange but true, apparently modeled after awk.     *     * NB: we set sep->length to the length of the w/s run, so we must test     * sep->chars[1] == 0 to make sure sep is just one space.     */    chars = JSSTRING_CHARS(str);    length = JSSTRING_LENGTH(str);    if (JS_VERSION_IS_1_2(cx) &&        !re && *sep->chars == ' ' && sep->chars[1] == 0) {        /* Skip leading whitespace if at front of str. */        if (i == 0) {            while (JS_ISSPACE(chars[i]))                i++;            *ip = i;        }        /* Don't delimit whitespace at end of string. */        if ((size_t)i == length)            return -1;        /* Skip over the non-whitespace chars. */        while ((size_t)i < length && !JS_ISSPACE(chars[i]))            i++;        /* Now skip the next run of whitespace. */        j = i;        while ((size_t)j < length && JS_ISSPACE(chars[j]))            j++;        /* Update sep->length to count delimiter chars. */        sep->length = (size_t)(j - i);        return i;    }#if JS_HAS_REGEXPS    /*     * Match a regular expression against the separator at or above index i.     * Call js_ExecuteRegExp with true for the test argument.  On successful     * match, get the separator from cx->regExpStatics.lastMatch.     */    if (re) {        size_t index;        jsval rval;      again:        /* JS1.2 deviated from Perl by never matching at end of string. */        index = (size_t)i;        if (!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &rval))            return -2;        if (rval != JSVAL_TRUE) {            /* Mismatch: ensure our caller advances i past end of string. */            sep->length = 1;            return length;        }        i = (jsint)index;        *sep = cx->regExpStatics.lastMatch;        if (sep->length == 0) {            /*             * Empty string match: never split on an empty match at the start             * of a find_split cycle.  Same rule as for an empty global match             * in match_or_replace.             */            if (i == *ip) {                /*                 * "Bump-along" to avoid sticking at an empty match, but don't                 * bump past end of string -- our caller must do that by adding                 * sep->length to our return value.                 */                if ((size_t)i == length) {                    if (JS_VERSION_IS_1_2(cx)) {                        sep->length = 1;                        return i;                    }                    return -1;                }                i++;                goto again;            }        }        JS_ASSERT((size_t)i >= sep->length);        return i - sep->length;    }#endif /* JS_HAS_REGEXPS */    /*     * Deviate from ECMA by never splitting an empty string by any separator     * string into a non-empty array (an array of length 1 that contains the     * empty string).     */    if (!JS_VERSION_IS_ECMA(cx) && length == 0)        return -1;    /*     * Special case: if sep is the empty string, split str into one character     * substrings.  Let our caller worry about whether to split once at end of     * string into an empty substring.     *     * For 1.2 compatibility, at the end of the string, we return the length as     * the result, and set the separator length to 1 -- this allows the caller     * to include an additional null string at the end of the substring list.     */    if (sep->length == 0) {        if (JS_VERSION_IS_1_2(cx)) {            if ((size_t)i == length) {                sep->length = 1;                return i;            }            return i + 1;        }        return ((size_t)i == length) ? -1 : i + 1;    }    /*     * Now that we know sep is non-empty, search starting at i in str for an     * occurrence of all of sep's chars.  If we find them, return the index of     * the first separator char.  Otherwise, return length.     */    j = 0;    while ((size_t)(k = i + j) < length) {        if (chars[k] == sep->chars[j]) {            if ((size_t)++j == sep->length)                return i;        } else {            i++;            j = 0;        }    }    return k;}