mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 04:05:49 +00:00
Bug 1027528 part 19 - Make XDR work with Latin1 strings. r=luke
This commit is contained in:
parent
fe65a821ae
commit
f88cb28860
@ -23,3 +23,15 @@ var ff = function() { return 10; };
|
||||
ff.toSource = function() { return "((11))"; }
|
||||
Object.defineProperty(o, "prop", {get: ff, set: ff, enumerable: true});
|
||||
assertEq(o.toSource(), "({prop:((11)), prop:((11))})");
|
||||
|
||||
// XDR
|
||||
load(libdir + 'bytecode-cache.js');
|
||||
|
||||
// Latin1 string constant
|
||||
toLatin1("string123");
|
||||
test = "'string123';";
|
||||
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
|
||||
|
||||
// TwoByte string constant
|
||||
test = "'string\u1234';";
|
||||
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
|
||||
|
@ -1,7 +1,6 @@
|
||||
var s = "Foo123";
|
||||
assertEq(isLatin1(s), false);
|
||||
assertEq(isLatin1("Foo123\u1200"), false);
|
||||
|
||||
s = toLatin1(s);
|
||||
s = toLatin1("Foo123");
|
||||
assertEq(isLatin1(s), true);
|
||||
|
||||
function testEq(s) {
|
||||
|
@ -42,8 +42,10 @@ function testSearchRope() {
|
||||
|
||||
// Latin1 + Latin1
|
||||
s1 = "foobarbaz0123456789".repeat(10);
|
||||
s1.indexOf("333"); // flatten
|
||||
s1 = toLatin1(s1);
|
||||
var ropeLatin1 = s1 + toLatin1("abcdef\u00AA");
|
||||
assertEq(isLatin1(ropeLatin1), false);
|
||||
assertEq(isLatin1(ropeLatin1), true);
|
||||
assertEq(ropeLatin1.search(abc), 190);
|
||||
|
||||
// Latin1 + TwoByte
|
||||
|
@ -589,53 +589,62 @@ bool
|
||||
js::XDRAtom(XDRState<mode> *xdr, MutableHandleAtom atomp)
|
||||
{
|
||||
if (mode == XDR_ENCODE) {
|
||||
uint32_t nchars = atomp->length();
|
||||
if (!xdr->codeUint32(&nchars))
|
||||
static_assert(JSString::MAX_LENGTH <= INT32_MAX, "String length must fit in 31 bits");
|
||||
uint32_t length = atomp->length();
|
||||
uint32_t lengthAndEncoding = (length << 1) | uint32_t(atomp->hasLatin1Chars());
|
||||
if (!xdr->codeUint32(&lengthAndEncoding))
|
||||
return false;
|
||||
|
||||
jschar *chars = const_cast<jschar *>(atomp->getChars(xdr->cx()));
|
||||
if (!chars)
|
||||
return false;
|
||||
|
||||
return xdr->codeChars(chars, nchars);
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
return atomp->hasLatin1Chars()
|
||||
? xdr->codeChars(atomp->latin1Chars(nogc), length)
|
||||
: xdr->codeChars(const_cast<jschar*>(atomp->twoByteChars(nogc)), length);
|
||||
}
|
||||
|
||||
/* Avoid JSString allocation for already existing atoms. See bug 321985. */
|
||||
uint32_t nchars;
|
||||
if (!xdr->codeUint32(&nchars))
|
||||
uint32_t lengthAndEncoding;
|
||||
if (!xdr->codeUint32(&lengthAndEncoding))
|
||||
return false;
|
||||
|
||||
uint32_t length = lengthAndEncoding >> 1;
|
||||
bool latin1 = lengthAndEncoding & 0x1;
|
||||
|
||||
JSContext *cx = xdr->cx();
|
||||
JSAtom *atom;
|
||||
#if IS_LITTLE_ENDIAN
|
||||
/* Directly access the little endian chars in the XDR buffer. */
|
||||
const jschar *chars = reinterpret_cast<const jschar *>(xdr->buf.read(nchars * sizeof(jschar)));
|
||||
atom = AtomizeChars(cx, chars, nchars);
|
||||
#else
|
||||
/*
|
||||
* We must copy chars to a temporary buffer to convert between little and
|
||||
* big endian data.
|
||||
*/
|
||||
jschar *chars;
|
||||
jschar stackChars[256];
|
||||
if (nchars <= ArrayLength(stackChars)) {
|
||||
chars = stackChars;
|
||||
if (latin1) {
|
||||
const Latin1Char *chars = reinterpret_cast<const Latin1Char *>(xdr->buf.read(length));
|
||||
atom = AtomizeChars(cx, chars, length);
|
||||
} else {
|
||||
#if IS_LITTLE_ENDIAN
|
||||
/* Directly access the little endian chars in the XDR buffer. */
|
||||
const jschar *chars = reinterpret_cast<const jschar *>(xdr->buf.read(length * sizeof(jschar)));
|
||||
atom = AtomizeChars(cx, chars, length);
|
||||
#else
|
||||
/*
|
||||
* This is very uncommon. Don't use the tempLifoAlloc arena for this as
|
||||
* most allocations here will be bigger than tempLifoAlloc's default
|
||||
* chunk size.
|
||||
* We must copy chars to a temporary buffer to convert between little and
|
||||
* big endian data.
|
||||
*/
|
||||
chars = cx->runtime()->pod_malloc<jschar>(nchars);
|
||||
if (!chars)
|
||||
return false;
|
||||
}
|
||||
jschar *chars;
|
||||
jschar stackChars[256];
|
||||
if (length <= ArrayLength(stackChars)) {
|
||||
chars = stackChars;
|
||||
} else {
|
||||
/*
|
||||
* This is very uncommon. Don't use the tempLifoAlloc arena for this as
|
||||
* most allocations here will be bigger than tempLifoAlloc's default
|
||||
* chunk size.
|
||||
*/
|
||||
chars = cx->runtime()->pod_malloc<jschar>(length);
|
||||
if (!chars)
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_ALWAYS_TRUE(xdr->codeChars(chars, nchars));
|
||||
atom = AtomizeChars(cx, chars, nchars);
|
||||
if (chars != stackChars)
|
||||
js_free(chars);
|
||||
JS_ALWAYS_TRUE(xdr->codeChars(chars, length));
|
||||
atom = AtomizeChars(cx, chars, length);
|
||||
if (chars != stackChars)
|
||||
js_free(chars);
|
||||
#endif /* !IS_LITTLE_ENDIAN */
|
||||
}
|
||||
|
||||
if (!atom)
|
||||
return false;
|
||||
|
@ -33,6 +33,7 @@ XDRBuffer::grow(size_t n)
|
||||
size_t offset = cursor - base;
|
||||
size_t newCapacity = JS_ROUNDUP(offset + n, MEM_BLOCK);
|
||||
if (isUint32Overflow(newCapacity)) {
|
||||
js::gc::AutoSuppressGC suppressGC(cx());
|
||||
JS_ReportErrorNumber(cx(), js_GetErrorMessage, nullptr, JSMSG_TOO_BIG_TO_ENCODE);
|
||||
return false;
|
||||
}
|
||||
@ -48,6 +49,22 @@ XDRBuffer::grow(size_t n)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRState<mode>::codeChars(const Latin1Char *chars, size_t nchars)
|
||||
{
|
||||
static_assert(sizeof(Latin1Char) == sizeof(uint8_t), "Latin1Char must fit in 1 byte");
|
||||
|
||||
MOZ_ASSERT(mode == XDR_ENCODE);
|
||||
|
||||
uint8_t *ptr = buf.write(nchars);
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
mozilla::PodCopy(ptr, chars, nchars);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRState<mode>::codeChars(jschar *chars, size_t nchars)
|
||||
|
@ -28,7 +28,7 @@ namespace js {
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 173);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 174);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
@ -229,6 +229,7 @@ class XDRState {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool codeChars(const JS::Latin1Char *chars, size_t nchars);
|
||||
bool codeChars(jschar *chars, size_t nchars);
|
||||
|
||||
bool codeFunction(JS::MutableHandleObject objp);
|
||||
|
Loading…
Reference in New Issue
Block a user