Bug 1032726 part 3 - Make FindEnumStringIndex work with Latin1 strings. r=bz,terrence

--HG--
extra : rebase_source : dd266d1453f926438eec533502d75e2a7de37795
This commit is contained in:
Jan de Mooij 2014-07-02 15:45:04 +02:00
parent 2d66c3ecb7
commit 8b009a1066
3 changed files with 76 additions and 29 deletions

View File

@ -1056,16 +1056,16 @@ HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
template<bool Fatal>
inline bool
EnumValueNotFound(JSContext* cx, const jschar* chars, size_t length,
const char* type, const char* sourceDescription)
EnumValueNotFound(JSContext* cx, JSString* str, const char* type,
const char* sourceDescription)
{
return false;
}
template<>
inline bool
EnumValueNotFound<false>(JSContext* cx, const jschar* chars, size_t length,
const char* type, const char* sourceDescription)
EnumValueNotFound<false>(JSContext* cx, JSString* str, const char* type,
const char* sourceDescription)
{
// TODO: Log a warning to the console.
return true;
@ -1073,34 +1073,21 @@ EnumValueNotFound<false>(JSContext* cx, const jschar* chars, size_t length,
template<>
inline bool
EnumValueNotFound<true>(JSContext* cx, const jschar* chars, size_t length,
const char* type, const char* sourceDescription)
EnumValueNotFound<true>(JSContext* cx, JSString* str, const char* type,
const char* sourceDescription)
{
NS_LossyConvertUTF16toASCII deflated(static_cast<const char16_t*>(chars),
length);
JSAutoByteString deflated(cx, str);
if (!deflated) {
return false;
}
return ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, sourceDescription,
deflated.get(), type);
deflated.ptr(), type);
}
template<bool InvalidValueFatal>
template<typename CharT>
inline int
FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* values,
const char* type, const char* sourceDescription, bool* ok)
FindEnumStringIndexImpl(const CharT* chars, size_t length, const EnumEntry* values)
{
// JS_StringEqualsAscii is slow as molasses, so don't use it here.
JSString* str = JS::ToString(cx, v);
if (!str) {
*ok = false;
return 0;
}
JS::Anchor<JSString*> anchor(str);
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars) {
*ok = false;
return 0;
}
int i = 0;
for (const EnumEntry* value = values; value->value; ++value, ++i) {
if (length != value->length) {
@ -1117,13 +1104,54 @@ FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* val
}
if (equal) {
*ok = true;
return i;
}
}
*ok = EnumValueNotFound<InvalidValueFatal>(cx, chars, length, type,
sourceDescription);
return -1;
}
template<bool InvalidValueFatal>
inline int
FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* values,
const char* type, const char* sourceDescription, bool* ok)
{
// JS_StringEqualsAscii is slow as molasses, so don't use it here.
JSString* str = JS::ToString(cx, v);
if (!str) {
*ok = false;
return 0;
}
JS::Anchor<JSString*> anchor(str);
{
int index;
size_t length;
JS::AutoCheckCannotGC nogc;
if (JS_StringHasLatin1Chars(str)) {
const JS::Latin1Char* chars = JS_GetLatin1StringCharsAndLength(cx, nogc, str,
&length);
if (!chars) {
*ok = false;
return 0;
}
index = FindEnumStringIndexImpl(chars, length, values);
} else {
const jschar* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
&length);
if (!chars) {
*ok = false;
return 0;
}
index = FindEnumStringIndexImpl(chars, length, values);
}
if (index >= 0) {
*ok = true;
return index;
}
}
*ok = EnumValueNotFound<InvalidValueFatal>(cx, str, type, sourceDescription);
return -1;
}

View File

@ -5365,6 +5365,21 @@ JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
return linear->chars();
}
JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1StringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *plength)
{
JS_ASSERT(plength);
AssertHeapIsIdleOrStringIsFlat(cx, str);
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
JSLinearString *linear = str->ensureLinear(cx);
if (!linear)
return nullptr;
*plength = linear->length();
return linear->latin1Chars(nogc);
}
JS_PUBLIC_API(const jschar *)
JS_GetTwoByteStringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *plength)

View File

@ -4173,6 +4173,10 @@ JS_StringHasLatin1Chars(JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
extern JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1StringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *length);
extern JS_PUBLIC_API(const jschar *)
JS_GetTwoByteStringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *length);