mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1025875 part 10 - Make array.join work with Latin1 strings. r=luke
--HG-- extra : rebase_source : e811a9ad5b5c8e46ad65554e55272fab95fef2cc
This commit is contained in:
parent
531dbe80df
commit
372fb7e9d7
14
js/src/jit-test/tests/latin1/join.js
Normal file
14
js/src/jit-test/tests/latin1/join.js
Normal file
@ -0,0 +1,14 @@
|
||||
var arrLatin1 = [toLatin1("abc1"), toLatin1("abc\u00A0")];
|
||||
assertEq(arrLatin1.join(toLatin1("sep\u00ff")), "abc1sep\xFFabc\xA0");
|
||||
|
||||
var arrTwoByte = [toLatin1("abc2"), "def\u1200"];
|
||||
assertEq(arrTwoByte.join(toLatin1("sep\u00fe")), "abc2sep\xFEdef\u1200");
|
||||
|
||||
assertEq(arrLatin1.join(toLatin1("-")), "abc1-abc\xA0");
|
||||
assertEq(arrTwoByte.join(toLatin1("7")), "abc27def\u1200");
|
||||
|
||||
assertEq(arrLatin1.join("\u1200"), "abc1\u1200abc\xA0");
|
||||
assertEq(arrTwoByte.join("\u1200"), "abc2\u1200def\u1200");
|
||||
|
||||
assertEq(arrLatin1.join("---\u1200"), "abc1---\u1200abc\xA0");
|
||||
assertEq(arrTwoByte.join("---\u1200"), "abc2---\u1200def\u1200");
|
@ -943,23 +943,22 @@ struct EmptySeparatorOp
|
||||
bool operator()(JSContext *, StringBuffer &sb) { return true; }
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
struct CharSeparatorOp
|
||||
{
|
||||
jschar sep;
|
||||
explicit CharSeparatorOp(jschar sep) : sep(sep) {};
|
||||
const CharT sep;
|
||||
explicit CharSeparatorOp(CharT sep) : sep(sep) {};
|
||||
bool operator()(JSContext *, StringBuffer &sb) { return sb.append(sep); }
|
||||
};
|
||||
|
||||
struct StringSeparatorOp
|
||||
{
|
||||
const jschar *sepchars;
|
||||
size_t seplen;
|
||||
HandleLinearString sep;
|
||||
|
||||
StringSeparatorOp(const jschar *sepchars, size_t seplen)
|
||||
: sepchars(sepchars), seplen(seplen) {};
|
||||
explicit StringSeparatorOp(HandleLinearString sep) : sep(sep) {}
|
||||
|
||||
bool operator()(JSContext *cx, StringBuffer &sb) {
|
||||
return sb.append(sepchars, seplen);
|
||||
return sb.append(sep);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1064,22 +1063,16 @@ ArrayJoin(JSContext *cx, CallArgs &args)
|
||||
return false;
|
||||
|
||||
// Steps 4 and 5
|
||||
RootedString sepstr(cx, nullptr);
|
||||
const jschar *sepchars;
|
||||
size_t seplen;
|
||||
RootedLinearString sepstr(cx);
|
||||
if (!Locale && args.hasDefined(0)) {
|
||||
sepstr = ToString<CanGC>(cx, args[0]);
|
||||
JSString *s = ToString<CanGC>(cx, args[0]);
|
||||
if (!s)
|
||||
return false;
|
||||
sepstr = s->ensureLinear(cx);
|
||||
if (!sepstr)
|
||||
return false;
|
||||
sepchars = sepstr->getChars(cx);
|
||||
if (!sepchars)
|
||||
return false;
|
||||
seplen = sepstr->length();
|
||||
} else {
|
||||
HandlePropertyName comma = cx->names().comma;
|
||||
sepstr = comma;
|
||||
sepchars = comma->chars();
|
||||
seplen = comma->length();
|
||||
sepstr = cx->names().comma;
|
||||
}
|
||||
|
||||
JS::Anchor<JSString*> anchor(sepstr);
|
||||
@ -1100,9 +1093,12 @@ ArrayJoin(JSContext *cx, CallArgs &args)
|
||||
}
|
||||
|
||||
StringBuffer sb(cx);
|
||||
if (sepstr->hasTwoByteChars() && !sb.ensureTwoByteChars())
|
||||
return false;
|
||||
|
||||
// The separator will be added |length - 1| times, reserve space for that
|
||||
// so that we don't have to unnecessarily grow the buffer.
|
||||
size_t seplen = sepstr->length();
|
||||
if (length > 0 && !sb.reserve(seplen * (length - 1)))
|
||||
return false;
|
||||
|
||||
@ -1112,11 +1108,18 @@ ArrayJoin(JSContext *cx, CallArgs &args)
|
||||
if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
|
||||
return false;
|
||||
} else if (seplen == 1) {
|
||||
CharSeparatorOp op(sepchars[0]);
|
||||
if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
|
||||
return false;
|
||||
jschar c = sepstr->latin1OrTwoByteChar(0);
|
||||
if (c <= JSString::MAX_LATIN1_CHAR) {
|
||||
CharSeparatorOp<Latin1Char> op(c);
|
||||
if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
|
||||
return false;
|
||||
} else {
|
||||
CharSeparatorOp<jschar> op(c);
|
||||
if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
StringSeparatorOp op(sepchars, seplen);
|
||||
StringSeparatorOp op(sepstr);
|
||||
if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
|
||||
return false;
|
||||
}
|
||||
|
@ -258,6 +258,8 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
static const uint32_t MAX_LENGTH = JS_BIT(28) - 1;
|
||||
|
||||
static const JS::Latin1Char MAX_LATIN1_CHAR = 0xff;
|
||||
|
||||
/*
|
||||
* Helper function to validate that a string of a given length is
|
||||
* representable by a JSString. An allocation overflow is reported if false
|
||||
|
@ -67,8 +67,6 @@ class StringBuffer
|
||||
return cb.ref<TwoByteCharBuffer>();
|
||||
}
|
||||
|
||||
static const Latin1Char MaxLatin1Char = 0xff;
|
||||
|
||||
bool inflateChars();
|
||||
|
||||
public:
|
||||
@ -107,7 +105,7 @@ class StringBuffer
|
||||
|
||||
inline bool append(const jschar c) {
|
||||
if (isLatin1()) {
|
||||
if (c <= MaxLatin1Char)
|
||||
if (c <= JSString::MAX_LATIN1_CHAR)
|
||||
return latin1Chars().append(Latin1Char(c));
|
||||
if (!inflateChars())
|
||||
return false;
|
||||
@ -224,7 +222,7 @@ StringBuffer::append(const jschar *begin, const jschar *end)
|
||||
while (true) {
|
||||
if (begin >= end)
|
||||
return true;
|
||||
if (*begin > MaxLatin1Char)
|
||||
if (*begin > JSString::MAX_LATIN1_CHAR)
|
||||
break;
|
||||
if (!latin1Chars().append(*begin))
|
||||
return false;
|
||||
@ -246,7 +244,9 @@ StringBuffer::append(JSLinearString *str)
|
||||
if (!inflateChars())
|
||||
return false;
|
||||
}
|
||||
return twoByteChars().append(str->twoByteChars(nogc), str->length());
|
||||
return str->hasLatin1Chars()
|
||||
? twoByteChars().append(str->latin1Chars(nogc), str->length())
|
||||
: twoByteChars().append(str->twoByteChars(nogc), str->length());
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -261,7 +261,9 @@ StringBuffer::appendSubstring(JSLinearString *base, size_t off, size_t len)
|
||||
if (!inflateChars())
|
||||
return false;
|
||||
}
|
||||
return twoByteChars().append(base->twoByteChars(nogc) + off, len);
|
||||
return base->hasLatin1Chars()
|
||||
? twoByteChars().append(base->latin1Chars(nogc) + off, len)
|
||||
: twoByteChars().append(base->twoByteChars(nogc) + off, len);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
Loading…
Reference in New Issue
Block a user