mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1023778 part 3 - Make AtomizeChars and js_NewStringCopyN accept Latin1 chars. r=luke
This commit is contained in:
parent
f138aa5022
commit
e261152579
@ -352,9 +352,10 @@ AtomizeAndtake(ExclusiveContext *cx, jschar *tbchars, size_t length, InternBehav
|
||||
}
|
||||
|
||||
/* |tbchars| must not point into an inline or short string. */
|
||||
template <typename CharT>
|
||||
MOZ_ALWAYS_INLINE
|
||||
static JSAtom *
|
||||
AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, InternBehavior ib)
|
||||
AtomizeAndCopyChars(ExclusiveContext *cx, const CharT *tbchars, size_t length, InternBehavior ib)
|
||||
{
|
||||
if (JSAtom *s = cx->staticStrings().lookup(tbchars, length))
|
||||
return s;
|
||||
@ -396,6 +397,12 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length,
|
||||
return atom;
|
||||
}
|
||||
|
||||
template JSAtom *
|
||||
AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, InternBehavior ib);
|
||||
|
||||
template JSAtom *
|
||||
AtomizeAndCopyChars(ExclusiveContext *cx, const Latin1Char *tbchars, size_t length, InternBehavior ib);
|
||||
|
||||
JSAtom *
|
||||
js::AtomizeString(ExclusiveContext *cx, JSString *str,
|
||||
js::InternBehavior ib /* = js::DoNotInternAtom */)
|
||||
@ -458,8 +465,9 @@ js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavi
|
||||
return AtomizeAndtake(cx, tbcharsZ, length, ib);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
JSAtom *
|
||||
js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, InternBehavior ib)
|
||||
js::AtomizeChars(ExclusiveContext *cx, const CharT *chars, size_t length, InternBehavior ib)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
@ -469,6 +477,12 @@ js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, Inter
|
||||
return AtomizeAndCopyChars(cx, chars, length, ib);
|
||||
}
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeChars(ExclusiveContext *cx, const Latin1Char *chars, size_t length, InternBehavior ib);
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, InternBehavior ib);
|
||||
|
||||
bool
|
||||
js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, MutableHandleId idp)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/Rooting.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "vm/CommonPropertyNames.h"
|
||||
|
||||
class JSAtom;
|
||||
@ -85,14 +86,24 @@ struct AtomHasher
|
||||
{
|
||||
struct Lookup
|
||||
{
|
||||
const jschar *chars;
|
||||
size_t length;
|
||||
const JSAtom *atom; /* Optional. */
|
||||
union {
|
||||
const JS::Latin1Char *latin1Chars;
|
||||
const jschar *twoByteChars;
|
||||
};
|
||||
bool isLatin1;
|
||||
size_t length;
|
||||
const JSAtom *atom; /* Optional. */
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
||||
HashNumber hash;
|
||||
|
||||
Lookup(const jschar *chars, size_t length)
|
||||
: chars(chars), length(length), atom(nullptr)
|
||||
: twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
Lookup(const JS::Latin1Char *chars, size_t length)
|
||||
: latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
}
|
||||
@ -187,8 +198,9 @@ extern JSAtom *
|
||||
Atomize(ExclusiveContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
template <typename CharT>
|
||||
extern JSAtom *
|
||||
AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length,
|
||||
AtomizeChars(ExclusiveContext *cx, const CharT *chars, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
extern JSAtom *
|
||||
|
@ -137,9 +137,15 @@ IdToString(JSContext *cx, jsid id)
|
||||
|
||||
inline
|
||||
AtomHasher::Lookup::Lookup(const JSAtom *atom)
|
||||
: chars(atom->chars()), length(atom->length()), atom(atom)
|
||||
: isLatin1(atom->hasLatin1Chars()), length(atom->length()), atom(atom)
|
||||
{
|
||||
hash = mozilla::HashString(chars, length);
|
||||
if (isLatin1) {
|
||||
latin1Chars = atom->latin1Chars(nogc);
|
||||
hash = mozilla::HashString(latin1Chars, length);
|
||||
} else {
|
||||
twoByteChars = atom->twoByteChars(nogc);
|
||||
hash = mozilla::HashString(twoByteChars, length);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -150,7 +156,18 @@ AtomHasher::match(const AtomStateEntry &entry, const Lookup &lookup)
|
||||
return lookup.atom == key;
|
||||
if (key->length() != lookup.length)
|
||||
return false;
|
||||
return mozilla::PodEqual(key->chars(), lookup.chars, lookup.length);
|
||||
|
||||
if (key->hasLatin1Chars()) {
|
||||
const Latin1Char *keyChars = key->latin1Chars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return mozilla::PodEqual(keyChars, lookup.latin1Chars, lookup.length);
|
||||
return EqualCharsLatin1TwoByte(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
const jschar *keyChars = key->twoByteChars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return EqualCharsLatin1TwoByte(lookup.latin1Chars, keyChars, lookup.length);
|
||||
return mozilla::PodEqual(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
inline Handle<PropertyName*>
|
||||
|
119
js/src/jsstr.cpp
119
js/src/jsstr.cpp
@ -22,6 +22,7 @@
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/Range.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@ -71,6 +72,7 @@ using mozilla::IsNegativeZero;
|
||||
using mozilla::IsSame;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::Range;
|
||||
using mozilla::SafeCast;
|
||||
|
||||
using JS::AutoCheckCannotGC;
|
||||
@ -1702,16 +1704,6 @@ str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EqualCharsLatin1TwoByte(const Latin1Char *s1, const jschar *s2, size_t len)
|
||||
{
|
||||
for (const Latin1Char *s1end = s1 + len; s1 < s1end; s1++, s2++) {
|
||||
if (jschar(*s1) != *s2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HasSubstringAt(JSLinearString *text, JSLinearString *pat, size_t start)
|
||||
{
|
||||
@ -4279,51 +4271,90 @@ js_NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t len
|
||||
return JSDependentString::new_(cx, base, start, length);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN(ExclusiveContext *cx, const jschar *s, size_t n)
|
||||
{
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, TwoByteChars(s, n));
|
||||
template <typename CharT>
|
||||
static void
|
||||
CopyCharsMaybeInflate(jschar *dest, const CharT *src, size_t len);
|
||||
|
||||
jschar *news = cx->pod_malloc<jschar>(n + 1);
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const jschar *src, size_t len)
|
||||
{
|
||||
PodCopy(dest, src, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const Latin1Char *src, size_t len)
|
||||
{
|
||||
CopyAndInflateChars(dest, src, len);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN(ThreadSafeContext *cx, const CharT *s, size_t n)
|
||||
{
|
||||
if (EnableLatin1Strings) {
|
||||
if (JSFatInlineString::lengthFits<CharT>(n))
|
||||
return NewFatInlineString<allowGC>(cx, Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<CharT> news(cx->pod_malloc<CharT>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
PodCopy(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
|
||||
JSFlatString *str = js_NewString<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<jschar> news(cx->pod_malloc<jschar>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
js_strncpy(news, s, n);
|
||||
|
||||
CopyCharsMaybeInflate(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
JSFlatString *str = js_NewString<allowGC>(cx, news, n);
|
||||
|
||||
JSFlatString *str = js_NewString<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
js_free(news);
|
||||
return str;
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, JS::Latin1Chars(s, n));
|
||||
|
||||
jschar *chars = InflateString(cx, s, &n);
|
||||
if (!chars)
|
||||
return nullptr;
|
||||
JSFlatString *str = js_NewString<allowGC>(cx, chars, n);
|
||||
if (!str)
|
||||
js_free(chars);
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *cx, const char *s, size_t n);
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *cx, const char *s, size_t n);
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template <>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
return js_NewStringCopyN<CanGC>(cx, reinterpret_cast<const Latin1Char *>(s), n);
|
||||
}
|
||||
|
||||
template <>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
return js_NewStringCopyN<NoGC>(cx, reinterpret_cast<const Latin1Char *>(s), n);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
@ -4331,7 +4362,7 @@ js_NewStringCopyZ(ExclusiveContext *cx, const jschar *s)
|
||||
{
|
||||
size_t n = js_strlen(s);
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, TwoByteChars(s, n));
|
||||
return NewFatInlineString<allowGC>(cx, Range<const jschar>(s, n));
|
||||
|
||||
size_t m = (n + 1) * sizeof(jschar);
|
||||
jschar *news = (jschar *) cx->malloc_(m);
|
||||
|
@ -101,13 +101,9 @@ extern JSLinearString *
|
||||
js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
|
||||
|
||||
/* Copy a counted string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyN(js::ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyN(js::ThreadSafeContext *cx, const char *s, size_t n);
|
||||
js_NewStringCopyN(js::ThreadSafeContext *cx, const CharT *s, size_t n);
|
||||
|
||||
/* Copy a C string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
@ -237,6 +233,16 @@ js_strdup(js::ThreadSafeContext *cx, const jschar *s);
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
EqualCharsLatin1TwoByte(const Latin1Char *s1, const jschar *s2, size_t len)
|
||||
{
|
||||
for (const Latin1Char *s1end = s1 + len; s1 < s1end; s1++, s2++) {
|
||||
if (jschar(*s1) != *s2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inflate bytes in ASCII encoding to jschars. Return null on error, otherwise
|
||||
* return the jschar that was malloc'ed. length is updated to the length of the
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "vm/String.h"
|
||||
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/Range.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
@ -42,7 +43,7 @@ AllocateFatInlineString(ThreadSafeContext *cx, size_t len, CharT **chars)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString *
|
||||
NewFatInlineString(ThreadSafeContext *cx, JS::Latin1Chars chars)
|
||||
NewFatInlineString(ThreadSafeContext *cx, mozilla::Range<const Latin1Char> chars)
|
||||
{
|
||||
size_t len = chars.length();
|
||||
|
||||
@ -70,7 +71,7 @@ NewFatInlineString(ThreadSafeContext *cx, JS::Latin1Chars chars)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString *
|
||||
NewFatInlineString(ExclusiveContext *cx, JS::TwoByteChars chars)
|
||||
NewFatInlineString(ThreadSafeContext *cx, mozilla::Range<const jschar> chars)
|
||||
{
|
||||
/*
|
||||
* Don't bother trying to find a static atom; measurement shows that not
|
||||
|
@ -6,12 +6,16 @@
|
||||
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
#include "mozilla/Range.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
using mozilla::Range;
|
||||
|
||||
template <typename CharT, class Buffer>
|
||||
static CharT *
|
||||
ExtractWellSized(ExclusiveContext *cx, Buffer &cb)
|
||||
@ -96,10 +100,10 @@ StringBuffer::finishString()
|
||||
|
||||
if (isLatin1()) {
|
||||
if (JSFatInlineString::latin1LengthFits(len))
|
||||
return NewFatInlineString<CanGC>(cx, Latin1Chars(latin1Chars().begin(), len));
|
||||
return NewFatInlineString<CanGC>(cx, Range<const Latin1Char>(latin1Chars().begin(), len));
|
||||
} else {
|
||||
if (JSFatInlineString::twoByteLengthFits(len))
|
||||
return NewFatInlineString<CanGC>(cx, TwoByteChars(twoByteChars().begin(), len));
|
||||
return NewFatInlineString<CanGC>(cx, Range<const jschar>(twoByteChars().begin(), len));
|
||||
}
|
||||
|
||||
return isLatin1()
|
||||
|
@ -313,6 +313,13 @@ HashString(const char* str, size_t length)
|
||||
return detail::HashKnownLength(str, length);
|
||||
}
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
inline uint32_t
|
||||
HashString(const unsigned char* str, size_t length)
|
||||
{
|
||||
return detail::HashKnownLength(str, length);
|
||||
}
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
inline uint32_t
|
||||
HashString(const uint16_t* str)
|
||||
|
Loading…
Reference in New Issue
Block a user